aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Documentation/.gitignore7
-rw-r--r--Documentation/DocBook/drm.tmpl12
-rw-r--r--Documentation/DocBook/v4l/v4l2.xml2
-rw-r--r--Documentation/DocBook/v4l/vidioc-query-dv-preset.xml6
-rw-r--r--Documentation/edac.txt152
-rw-r--r--Documentation/feature-removal-schedule.txt9
-rw-r--r--Documentation/filesystems/xfs-delayed-logging-design.txt5
-rw-r--r--Documentation/i2c/busses/i2c-ali15354
-rw-r--r--Documentation/i2c/busses/i2c-ali15632
-rw-r--r--Documentation/i2c/busses/i2c-ali15x316
-rw-r--r--Documentation/i2c/busses/i2c-pca-isa14
-rw-r--r--Documentation/i2c/busses/i2c-sis559558
-rw-r--r--Documentation/i2c/busses/i2c-sis6308
-rw-r--r--Documentation/i2c/ten-bit-addresses6
-rw-r--r--Documentation/kbuild/kbuild.txt6
-rw-r--r--Documentation/mutex-design.txt4
-rw-r--r--Documentation/timers/Makefile2
-rw-r--r--Documentation/video4linux/CARDLIST.saa71345
-rw-r--r--Documentation/video4linux/gspca.txt1
-rw-r--r--MAINTAINERS12
-rw-r--r--Makefile67
-rw-r--r--arch/cris/arch-v10/drivers/ds1302.c20
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c19
-rw-r--r--arch/cris/arch-v10/kernel/irq.c8
-rw-r--r--arch/cris/arch-v10/lib/dmacopy.c15
-rw-r--r--arch/cris/arch-v10/lib/hw_settings.S14
-rw-r--r--arch/cris/arch-v32/drivers/Kconfig16
-rw-r--r--arch/cris/arch-v32/drivers/i2c.c22
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c21
-rw-r--r--arch/cris/arch-v32/kernel/crisksyms.c4
-rw-r--r--arch/cris/arch-v32/kernel/irq.c14
-rw-r--r--arch/cris/arch-v32/kernel/smp.c4
-rw-r--r--arch/cris/include/arch-v10/arch/irq.h9
-rw-r--r--arch/cris/include/arch-v32/arch/irq.h4
-rw-r--r--arch/cris/include/asm/param.h17
-rw-r--r--arch/frv/kernel/break.S4
-rw-r--r--arch/frv/kernel/entry.S2
-rw-r--r--arch/frv/kernel/head.S2
-rw-r--r--arch/frv/kernel/vmlinux.lds.S10
-rw-r--r--arch/frv/mm/fault.c8
-rw-r--r--arch/frv/mm/tlb-miss.S2
-rw-r--r--arch/h8300/boot/compressed/head.S2
-rw-r--r--arch/h8300/boot/compressed/vmlinux.lds2
-rw-r--r--arch/ia64/include/asm/asmmacro.h12
-rw-r--r--arch/ia64/include/asm/cache.h2
-rw-r--r--arch/ia64/include/asm/percpu.h2
-rw-r--r--arch/ia64/kernel/Makefile.gate2
-rw-r--r--arch/ia64/kernel/gate-data.S2
-rw-r--r--arch/ia64/kernel/gate.S8
-rw-r--r--arch/ia64/kernel/gate.lds.S10
-rw-r--r--arch/ia64/kernel/init_task.c2
-rw-r--r--arch/ia64/kernel/ivt.S2
-rw-r--r--arch/ia64/kernel/minstate.h4
-rw-r--r--arch/ia64/kernel/paravirtentry.S2
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S28
-rw-r--r--arch/ia64/kvm/vmm_ivt.S2
-rw-r--r--arch/ia64/scripts/unwcheck.py2
-rw-r--r--arch/ia64/xen/gate-data.S2
-rw-r--r--arch/ia64/xen/xensetup.S2
-rw-r--r--arch/m32r/mm/fault.c14
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S4
-rw-r--r--arch/m68knommu/platform/68360/head-ram.S2
-rw-r--r--arch/m68knommu/platform/68360/head-rom.S2
-rw-r--r--arch/mips/lasat/image/head.S2
-rw-r--r--arch/mips/lasat/image/romscript.normal2
-rw-r--r--arch/mn10300/mm/fault.c9
-rw-r--r--arch/parisc/include/asm/cache.h2
-rw-r--r--arch/parisc/include/asm/system.h2
-rw-r--r--arch/parisc/kernel/head.S2
-rw-r--r--arch/parisc/kernel/init_task.c6
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S12
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/Makefile5
-rw-r--r--arch/powerpc/boot/4xx.c12
-rw-r--r--arch/powerpc/boot/dts/icon.dts447
-rw-r--r--arch/powerpc/boot/dts/katmai.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds.dts4
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts15
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts7
-rw-r--r--arch/powerpc/boot/dts/p1021mds.dts698
-rw-r--r--arch/powerpc/boot/dts/redwood.dts122
-rw-r--r--arch/powerpc/configs/44x/icon_defconfig1451
-rw-r--r--arch/powerpc/include/asm/cache.h2
-rw-r--r--arch/powerpc/include/asm/cputable.h1
-rw-r--r--arch/powerpc/include/asm/kexec.h13
-rw-r--r--arch/powerpc/include/asm/macio.h4
-rw-r--r--arch/powerpc/include/asm/page_64.h8
-rw-r--r--arch/powerpc/include/asm/reg_booke.h33
-rw-r--r--arch/powerpc/kernel/Makefile8
-rw-r--r--arch/powerpc/kernel/cputable.c2
-rw-r--r--arch/powerpc/kernel/crash.c4
-rw-r--r--arch/powerpc/kernel/fsl_booke_entry_mapping.S237
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S200
-rw-r--r--arch/powerpc/kernel/kprobes.c14
-rw-r--r--arch/powerpc/kernel/misc_32.S17
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c2
-rw-r--r--arch/powerpc/kernel/swsusp_booke.S193
-rw-r--r--arch/powerpc/kernel/traps.c88
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S10
-rw-r--r--arch/powerpc/platforms/44x/Kconfig11
-rw-r--r--arch/powerpc/platforms/44x/ppc44x_simple.c3
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c102
-rw-r--r--arch/powerpc/platforms/cell/iommu.c2
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c117
-rw-r--r--arch/powerpc/sysdev/fsl_msi.h3
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c2
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c119
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.h58
-rw-r--r--arch/s390/include/asm/cache.h2
-rw-r--r--arch/s390/kernel/swsusp_asm64.S2
-rw-r--r--arch/sh/Kconfig16
-rw-r--r--arch/sh/boards/Kconfig3
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c2
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c101
-rw-r--r--arch/sh/boards/mach-migor/setup.c2
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c8
-rw-r--r--arch/sh/boot/compressed/vmlinux.scr2
-rw-r--r--arch/sh/boot/romimage/Makefile13
-rw-r--r--arch/sh/boot/romimage/head.S42
-rw-r--r--arch/sh/boot/romimage/mmcif-sh7724.c72
-rw-r--r--arch/sh/boot/romimage/vmlinux.scr2
-rw-r--r--arch/sh/include/asm/cache.h2
-rw-r--r--arch/sh/include/asm/io.h8
-rw-r--r--arch/sh/include/asm/machvec.h9
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7724.h1
-rw-r--r--arch/sh/include/mach-common/mach/romimage.h10
-rw-r--r--arch/sh/include/mach-ecovec24/mach/romimage.h27
-rw-r--r--arch/sh/include/mach-kfr2r09/mach/romimage.h10
-rw-r--r--arch/sh/kernel/Makefile3
-rw-r--r--arch/sh/kernel/dwarf.c19
-rw-r--r--arch/sh/kernel/io.c22
-rw-r--r--arch/sh/kernel/io_generic.c20
-rw-r--r--arch/sh/kernel/io_trapped.c4
-rw-r--r--arch/sh/kernel/machvec.c17
-rw-r--r--arch/sh/kernel/return_address.c2
-rw-r--r--arch/sparc/boot/btfixupprep.c2
-rw-r--r--arch/sparc/include/asm/cache.h2
-rw-r--r--arch/um/kernel/dyn.lds.S2
-rw-r--r--arch/um/kernel/init_task.c2
-rw-r--r--arch/um/kernel/skas/uaccess.c2
-rw-r--r--arch/um/kernel/uml.lds.S2
-rw-r--r--arch/x86/.gitignore3
-rw-r--r--arch/x86/boot/compressed/mkpiggy.c2
-rw-r--r--arch/x86/boot/compressed/vmlinux.lds.S4
-rw-r--r--arch/x86/include/asm/cache.h2
-rw-r--r--arch/x86/include/asm/pci_x86.h2
-rw-r--r--arch/x86/kernel/acpi/wakeup_32.S2
-rw-r--r--arch/x86/kernel/amd_iommu.c16
-rw-r--r--arch/x86/kernel/amd_iommu_init.c20
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c10
-rw-r--r--arch/x86/kernel/cpu/perf_event.c22
-rw-r--r--arch/x86/kernel/init_task.c2
-rw-r--r--arch/x86/kernel/setup_percpu.c8
-rw-r--r--arch/x86/kernel/smpboot.c2
-rw-r--r--arch/x86/kernel/vmlinux.lds.S4
-rw-r--r--arch/x86/mm/numa.c6
-rw-r--r--arch/x86/pci/legacy.c42
-rw-r--r--arch/x86/xen/suspend.c4
-rw-r--r--arch/xtensa/mm/fault.c14
-rw-r--r--block/blk-core.c20
-rw-r--r--block/cfq-iosched.c101
-rw-r--r--block/elevator.c8
-rw-r--r--drivers/acpi/ec.c22
-rw-r--r--drivers/acpi/internal.h5
-rw-r--r--drivers/acpi/processor_idle.c17
-rw-r--r--drivers/acpi/sleep.c57
-rw-r--r--drivers/ata/Kconfig6
-rw-r--r--drivers/ata/libata-core.c6
-rw-r--r--drivers/ata/libata-scsi.c29
-rw-r--r--drivers/ata/pata_macio.c10
-rw-r--r--drivers/ata/sata_nv.c2
-rw-r--r--drivers/ata/sata_via.c13
-rw-r--r--drivers/block/brd.c53
-rw-r--r--drivers/block/cciss_scsi.c2
-rw-r--r--drivers/block/drbd/drbd_int.h14
-rw-r--r--drivers/block/drbd/drbd_main.c68
-rw-r--r--drivers/block/drbd/drbd_receiver.c45
-rw-r--r--drivers/block/drbd/drbd_req.c54
-rw-r--r--drivers/block/drbd/drbd_req.h1
-rw-r--r--drivers/block/drbd/drbd_worker.c24
-rw-r--r--drivers/block/swim3.c6
-rw-r--r--drivers/block/virtio_blk.c4
-rw-r--r--drivers/char/Kconfig1
-rw-r--r--drivers/char/agp/intel-gtt.c46
-rw-r--r--drivers/char/agp/uninorth-agp.c2
-rw-r--r--drivers/char/n_gsm.c9
-rw-r--r--drivers/char/virtio_console.c14
-rw-r--r--drivers/char/vt.c2
-rw-r--r--drivers/char/vt_ioctl.c4
-rw-r--r--drivers/clocksource/sh_cmt.c22
-rw-r--r--drivers/clocksource/sh_tmu.c20
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.c6
-rw-r--r--drivers/crypto/n2_core.c123
-rw-r--r--drivers/dma/mpc512x_dma.c10
-rw-r--r--drivers/dma/ppc4xx/adma.c4
-rw-r--r--drivers/edac/Kconfig13
-rw-r--r--drivers/edac/Makefile2
-rw-r--r--drivers/edac/edac_core.h23
-rw-r--r--drivers/edac/edac_mc_sysfs.c175
-rw-r--r--drivers/edac/edac_mce.c61
-rw-r--r--drivers/edac/i7core_edac.c2078
-rw-r--r--drivers/edac/mpc85xx_edac.c12
-rw-r--r--drivers/edac/ppc4xx_edac.c6
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c28
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c82
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c715
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c70
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h209
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c897
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c182
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h82
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h24
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c10
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c23
-rw-r--r--drivers/gpu/drm/i915/intel_display.c290
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c11
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c6
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c5
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c52
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c849
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h124
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c71
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c71
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c34
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_crtc.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c29
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c6
-rw-r--r--drivers/gpu/drm/nouveau/nv04_cursor.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_cursor.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_sor.c7
-rw-r--r--drivers/gpu/drm/radeon/Makefile7
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c5
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c1356
-rw-r--r--drivers/gpu/drm/radeon/evergreen_reg.h3
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h464
-rw-r--r--drivers/gpu/drm/radeon/r600.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c70
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c75
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/evergreen611
-rw-r--r--drivers/gpu/drm/radeon/rs600.c3
-rw-r--r--drivers/gpu/drm/radeon/rv770.c5
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c64
-rw-r--r--drivers/gpu/drm/vmwgfx/Makefile2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c24
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h49
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c9
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c87
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c173
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c23
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_irq.c17
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c203
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c189
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c2
-rw-r--r--drivers/gpu/vga/vgaarb.c61
-rw-r--r--drivers/hwmon/adt7411.c2
-rw-r--r--drivers/hwmon/asc7621.c2
-rw-r--r--drivers/hwmon/f75375s.c2
-rw-r--r--drivers/hwmon/g760a.c2
-rw-r--r--drivers/hwmon/lm73.c1
-rw-r--r--drivers/hwmon/lm75.c2
-rw-r--r--drivers/hwmon/lm95241.c1
-rw-r--r--drivers/hwmon/tmp102.c2
-rw-r--r--drivers/hwmon/tmp421.c2
-rw-r--r--drivers/hwmon/w83781d.c2
-rw-r--r--drivers/i2c/busses/Kconfig40
-rw-r--r--drivers/i2c/busses/Makefile6
-rw-r--r--drivers/i2c/i2c-core.c179
-rw-r--r--drivers/i2c/i2c-smbus.c1
-rw-r--r--drivers/ide/pmac.c7
-rw-r--r--drivers/infiniband/hw/qib/qib_fs.c4
-rw-r--r--drivers/input/keyboard/adp5588-keys.c1
-rw-r--r--drivers/input/keyboard/lm8323.c2
-rw-r--r--drivers/input/keyboard/max7359_keypad.c1
-rw-r--r--drivers/input/keyboard/qt2160.c1
-rw-r--r--drivers/input/keyboard/tca6416-keypad.c2
-rw-r--r--drivers/input/misc/ad714x-i2c.c1
-rw-r--r--drivers/input/misc/pcf8574_keypad.c2
-rw-r--r--drivers/input/mouse/synaptics_i2c.c1
-rw-r--r--drivers/input/serio/Kconfig3
-rw-r--r--drivers/input/tablet/wacom_sys.c1
-rw-r--r--drivers/input/tablet/wacom_wac.c73
-rw-r--r--drivers/input/tablet/wacom_wac.h1
-rw-r--r--drivers/input/touchscreen/Kconfig2
-rw-r--r--drivers/input/touchscreen/ad7879.c5
-rw-r--r--drivers/input/touchscreen/ads7846.c2
-rw-r--r--drivers/input/touchscreen/eeti_ts.c2
-rw-r--r--drivers/input/touchscreen/mcs5000_ts.c1
-rw-r--r--drivers/input/touchscreen/s3c2410_ts.c2
-rw-r--r--drivers/input/touchscreen/tps6507x-ts.c12
-rw-r--r--drivers/input/touchscreen/tsc2007.c2
-rw-r--r--drivers/isdn/capi/kcapi.c6
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c4
-rw-r--r--drivers/isdn/hardware/mISDN/netjet.c4
-rw-r--r--drivers/leds/leds-bd2802.c2
-rw-r--r--drivers/leds/leds-lp3944.c1
-rw-r--r--drivers/leds/leds-pca9532.c5
-rw-r--r--drivers/leds/leds-pca955x.c2
-rw-r--r--drivers/macintosh/macio_asic.c8
-rw-r--r--drivers/macintosh/mediabay.c6
-rw-r--r--drivers/macintosh/rack-meter.c8
-rw-r--r--drivers/macintosh/therm_adt746x.c2
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c5
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c1
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c1
-rw-r--r--drivers/media/IR/Kconfig2
-rw-r--r--drivers/media/IR/imon.c75
-rw-r--r--drivers/media/IR/ir-keytable.c17
-rw-r--r--drivers/media/IR/ir-sysfs.c7
-rw-r--r--drivers/media/IR/keymaps/Makefile3
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c90
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-m135a.c147
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c95
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c12
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig4
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/dvb-usb/ttusb2.c95
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c2
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c26
-rw-r--r--drivers/media/dvb/frontends/ds3000.c5
-rw-r--r--drivers/media/dvb/frontends/stv6110x.c5
-rw-r--r--drivers/media/dvb/ngene/ngene-cards.c15
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c80
-rw-r--r--drivers/media/dvb/ngene/ngene-dvb.c15
-rw-r--r--drivers/media/dvb/ngene/ngene-i2c.c1
-rw-r--r--drivers/media/dvb/ngene/ngene.h3
-rw-r--r--drivers/media/dvb/ttpci/Kconfig5
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c1
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c1
-rw-r--r--drivers/media/video/Kconfig4
-rw-r--r--drivers/media/video/ak881x.c3
-rw-r--r--drivers/media/video/bw-qcam.c759
-rw-r--r--drivers/media/video/bw-qcam.h69
-rw-r--r--drivers/media/video/c-qcam.c634
-rw-r--r--drivers/media/video/cx18/cx18-alsa-main.c2
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.c2
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.h2
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.c2
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.h2
-rw-r--r--drivers/media/video/cx18/cx18-alsa.h2
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c2
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c127
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h2
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c2
-rw-r--r--drivers/media/video/cx18/cx18-cards.c2
-rw-r--r--drivers/media/video/cx18/cx18-cards.h2
-rw-r--r--drivers/media/video/cx18/cx18-controls.c11
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.h2
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c2
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c2
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c2
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c2
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h2
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/video/cx18/cx18-io.c2
-rw-r--r--drivers/media/video/cx18/cx18-io.h4
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c10
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.h2
-rw-r--r--drivers/media/video/cx18/cx18-irq.c2
-rw-r--r--drivers/media/video/cx18/cx18-irq.h2
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c2
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h2
-rw-r--r--drivers/media/video/cx18/cx18-queue.c2
-rw-r--r--drivers/media/video/cx18/cx18-queue.h2
-rw-r--r--drivers/media/video/cx18/cx18-scb.c2
-rw-r--r--drivers/media/video/cx18/cx18-scb.h2
-rw-r--r--drivers/media/video/cx18/cx18-streams.c2
-rw-r--r--drivers/media/video/cx18/cx18-streams.h2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c5
-rw-r--r--drivers/media/video/cx2341x.c6
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c12
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-input.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-ioctl.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-ioctl.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c5
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c2
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.h2
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c99
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c16
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c7
-rw-r--r--drivers/media/video/gspca/sonixb.c2
-rw-r--r--drivers/media/video/gspca/sonixj.c5
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c23
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c14
-rw-r--r--drivers/media/video/mt9m001.c6
-rw-r--r--drivers/media/video/mt9m111.c6
-rw-r--r--drivers/media/video/mt9t031.c4
-rw-r--r--drivers/media/video/mt9t112.c6
-rw-r--r--drivers/media/video/mt9v011.c37
-rw-r--r--drivers/media/video/mt9v022.c6
-rw-r--r--drivers/media/video/mx3_camera.c4
-rw-r--r--drivers/media/video/omap/omap_vout.c3
-rw-r--r--drivers/media/video/ov772x.c6
-rw-r--r--drivers/media/video/ov9640.c6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h5
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c37
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c13
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c15
-rw-r--r--drivers/media/video/pxa_camera.c4
-rw-r--r--drivers/media/video/rj54n1cb0c.c6
-rw-r--r--drivers/media/video/saa7115.c19
-rw-r--r--drivers/media/video/saa7127.c8
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c46
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c55
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c9
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c18
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/saa717x.c38
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c4
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h2
-rw-r--r--drivers/media/video/soc_camera.c3
-rw-r--r--drivers/media/video/soc_camera_platform.c2
-rw-r--r--drivers/media/video/tcm825x.c8
-rw-r--r--drivers/media/video/tvp514x.c223
-rw-r--r--drivers/media/video/tvp5150.c20
-rw-r--r--drivers/media/video/tw9910.c4
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c3
-rw-r--r--drivers/mfd/88pm860x-i2c.c2
-rw-r--r--drivers/mfd/ab3100-core.c2
-rw-r--r--drivers/mfd/ab3550-core.c1
-rw-r--r--drivers/mfd/adp5520.c2
-rw-r--r--drivers/mfd/da903x.c2
-rw-r--r--drivers/mfd/max8925-i2c.c1
-rw-r--r--drivers/mfd/menelaus.c2
-rw-r--r--drivers/mfd/pcf50633-core.c2
-rw-r--r--drivers/mfd/tc35892.c2
-rw-r--r--drivers/mfd/tps65010.c1
-rw-r--r--drivers/mfd/wm8350-i2c.c2
-rw-r--r--drivers/mfd/wm8400-core.c2
-rw-r--r--drivers/misc/eeprom/at24.c1
-rw-r--r--drivers/misc/vmware_balloon.c18
-rw-r--r--drivers/mmc/host/omap.c1
-rw-r--r--drivers/mmc/host/sh_mmcif.c125
-rw-r--r--drivers/mtd/maps/pismo.c2
-rw-r--r--drivers/mtd/nand/fsl_upm.c17
-rw-r--r--drivers/mtd/nand/mpc5121_nfc.c8
-rw-r--r--drivers/mtd/nand/socrates_nand.c4
-rw-r--r--drivers/net/benet/be_cmds.c13
-rw-r--r--drivers/net/bmac.c7
-rw-r--r--drivers/net/bnx2.c14
-rw-r--r--drivers/net/can/mscan/mpc5xxx_can.c10
-rw-r--r--drivers/net/e1000e/netdev.c2
-rw-r--r--drivers/net/enic/enic.h7
-rw-r--r--drivers/net/enic/enic_main.c200
-rw-r--r--drivers/net/epic100.c7
-rw-r--r--drivers/net/fec.c16
-rw-r--r--drivers/net/fs_enet/mac-fcc.c49
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c4
-rw-r--r--drivers/net/greth.c11
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h1
-rw-r--r--drivers/net/korina.c32
-rw-r--r--drivers/net/ksz884x.c3
-rw-r--r--drivers/net/mace.c7
-rw-r--r--drivers/net/ppp_generic.c2
-rw-r--r--drivers/net/sfc/net_driver.h2
-rw-r--r--drivers/net/sfc/siena.c4
-rw-r--r--drivers/net/tehuti.c4
-rw-r--r--drivers/net/virtio_net.c8
-rw-r--r--drivers/net/wan/x25_asy.c2
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c14
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c6
-rw-r--r--drivers/net/wireless/libertas/rx.c5
-rw-r--r--drivers/net/wireless/orinoco/airport.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c2
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c4
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c2
-rw-r--r--drivers/power/max17040_battery.c2
-rw-r--r--drivers/regulator/lp3971.c2
-rw-r--r--drivers/regulator/max1586.c1
-rw-r--r--drivers/regulator/max8649.c2
-rw-r--r--drivers/regulator/max8660.c1
-rw-r--r--drivers/regulator/tps65023-regulator.c3
-rw-r--r--drivers/rtc/rtc-ds1374.c2
-rw-r--r--drivers/rtc/rtc-mpc5121.c14
-rw-r--r--drivers/rtc/rtc-rx8025.c2
-rw-r--r--drivers/rtc/rtc-s35390a.c2
-rw-r--r--drivers/rtc/rtc-s3c.c9
-rw-r--r--drivers/scsi/mac53c94.c7
-rw-r--r--drivers/scsi/mesh.c7
-rw-r--r--drivers/scsi/sd.c22
-rw-r--r--drivers/serial/8250_pci.c71
-rw-r--r--drivers/serial/altera_uart.c44
-rw-r--r--drivers/serial/bfin_5xx.c9
-rw-r--r--drivers/serial/msm_serial.c21
-rw-r--r--drivers/serial/msm_serial.h56
-rw-r--r--drivers/serial/pmac_zilog.c7
-rw-r--r--drivers/serial/serial_cs.c18
-rw-r--r--drivers/sfi/sfi_core.c4
-rw-r--r--drivers/sh/intc.c12
-rw-r--r--drivers/spi/mpc512x_psc_spi.c12
-rw-r--r--drivers/spi/spi_ppc4xx.c2
-rw-r--r--drivers/ssb/pci.c9
-rw-r--r--drivers/ssb/sprom.c1
-rw-r--r--drivers/staging/Kconfig6
-rw-r--r--drivers/staging/Makefile3
-rw-r--r--drivers/staging/adis16255/Kconfig2
-rw-r--r--drivers/staging/adis16255/adis16255.c4
-rw-r--r--drivers/staging/batman-adv/device.c2
-rw-r--r--drivers/staging/batman-adv/main.c5
-rw-r--r--drivers/staging/batman-adv/send.c24
-rw-r--r--drivers/staging/comedi/Kconfig81
-rw-r--r--drivers/staging/comedi/comedi_fops.c44
-rw-r--r--drivers/staging/comedi/drivers/Makefile4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c14
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_035.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1516.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_16xx.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1710.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2016.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2032.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2200.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3001.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3200.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3300.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c2
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c180
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c35
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c2
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c3
-rw-r--r--drivers/staging/dream/synaptics_i2c_rmi.c2
-rw-r--r--drivers/staging/dt3155/allocator.c4
-rw-r--r--drivers/staging/go7007/wis-saa7113.c2
-rw-r--r--drivers/staging/go7007/wis-saa7115.c2
-rw-r--r--drivers/staging/go7007/wis-sony-tuner.c1
-rw-r--r--drivers/staging/go7007/wis-tw2804.c1
-rw-r--r--drivers/staging/go7007/wis-tw9903.c2
-rw-r--r--drivers/staging/iio/Documentation/iio_utils.h3
-rw-r--r--drivers/staging/iio/adc/max1363_core.c2
-rw-r--r--drivers/staging/iio/light/tsl2563.c2
-rw-r--r--drivers/staging/iio/ring_sw.c2
-rw-r--r--drivers/staging/mrst-touchscreen/Kconfig7
-rw-r--r--drivers/staging/mrst-touchscreen/Makefile3
-rw-r--r--drivers/staging/mrst-touchscreen/TODO2
-rw-r--r--drivers/staging/mrst-touchscreen/intel-mid-touch.c864
-rw-r--r--drivers/staging/msm/Kconfig134
-rw-r--r--drivers/staging/msm/Makefile93
-rw-r--r--drivers/staging/msm/TODO3
-rw-r--r--drivers/staging/msm/ebi2_l2f.c569
-rw-r--r--drivers/staging/msm/ebi2_lcd.c250
-rw-r--r--drivers/staging/msm/ebi2_tmd20.c1122
-rw-r--r--drivers/staging/msm/hdmi_sii9022.c248
-rw-r--r--drivers/staging/msm/lcdc.c239
-rw-r--r--drivers/staging/msm/lcdc_external.c54
-rw-r--r--drivers/staging/msm/lcdc_gordon.c446
-rw-r--r--drivers/staging/msm/lcdc_grapefruit.c60
-rw-r--r--drivers/staging/msm/lcdc_panel.c88
-rw-r--r--drivers/staging/msm/lcdc_prism.c64
-rw-r--r--drivers/staging/msm/lcdc_sharp_wvga_pt.c290
-rw-r--r--drivers/staging/msm/lcdc_st15.c237
-rw-r--r--drivers/staging/msm/lcdc_st1_wxga.c54
-rw-r--r--drivers/staging/msm/lcdc_toshiba_wvga_pt.c374
-rw-r--r--drivers/staging/msm/lcdc_wxga.c56
-rw-r--r--drivers/staging/msm/logo.c98
-rw-r--r--drivers/staging/msm/mddi.c375
-rw-r--r--drivers/staging/msm/mddi_ext.c320
-rw-r--r--drivers/staging/msm/mddi_ext_lcd.c91
-rw-r--r--drivers/staging/msm/mddi_prism.c114
-rw-r--r--drivers/staging/msm/mddi_sharp.c892
-rw-r--r--drivers/staging/msm/mddi_toshiba.c1741
-rw-r--r--drivers/staging/msm/mddi_toshiba.h52
-rw-r--r--drivers/staging/msm/mddi_toshiba_vga.c136
-rw-r--r--drivers/staging/msm/mddi_toshiba_wvga.c63
-rw-r--r--drivers/staging/msm/mddi_toshiba_wvga_pt.c64
-rw-r--r--drivers/staging/msm/mddihost.c377
-rw-r--r--drivers/staging/msm/mddihost.h225
-rw-r--r--drivers/staging/msm/mddihost_e.c63
-rw-r--r--drivers/staging/msm/mddihosti.c2239
-rw-r--r--drivers/staging/msm/mddihosti.h547
-rw-r--r--drivers/staging/msm/mdp.c1113
-rw-r--r--drivers/staging/msm/mdp.h695
-rw-r--r--drivers/staging/msm/mdp4.h352
-rw-r--r--drivers/staging/msm/mdp4_debugfs.c181
-rw-r--r--drivers/staging/msm/mdp4_overlay.c1259
-rw-r--r--drivers/staging/msm/mdp4_overlay_lcdc.c313
-rw-r--r--drivers/staging/msm/mdp4_overlay_mddi.c254
-rw-r--r--drivers/staging/msm/mdp4_util.c1686
-rw-r--r--drivers/staging/msm/mdp_cursor.c104
-rw-r--r--drivers/staging/msm/mdp_dma.c561
-rw-r--r--drivers/staging/msm/mdp_dma_lcdc.c379
-rw-r--r--drivers/staging/msm/mdp_dma_s.c139
-rw-r--r--drivers/staging/msm/mdp_dma_tv.c142
-rw-r--r--drivers/staging/msm/mdp_hw_init.c720
-rw-r--r--drivers/staging/msm/mdp_ppp.c1502
-rw-r--r--drivers/staging/msm/mdp_ppp_dq.c347
-rw-r--r--drivers/staging/msm/mdp_ppp_dq.h86
-rw-r--r--drivers/staging/msm/mdp_ppp_v20.c2486
-rw-r--r--drivers/staging/msm/mdp_ppp_v31.c828
-rw-r--r--drivers/staging/msm/mdp_vsync.c389
-rw-r--r--drivers/staging/msm/memory.c214
-rw-r--r--drivers/staging/msm/memory_ll.h61
-rw-r--r--drivers/staging/msm/msm_fb.c2354
-rw-r--r--drivers/staging/msm/msm_fb.h174
-rw-r--r--drivers/staging/msm/msm_fb_bl.c79
-rw-r--r--drivers/staging/msm/msm_fb_def.h201
-rw-r--r--drivers/staging/msm/msm_fb_panel.c136
-rw-r--r--drivers/staging/msm/msm_fb_panel.h145
-rw-r--r--drivers/staging/msm/msm_mdp.h245
-rw-r--r--drivers/staging/msm/staging-devices.c323
-rw-r--r--drivers/staging/msm/tv_ntsc.c163
-rw-r--r--drivers/staging/msm/tv_pal.c213
-rw-r--r--drivers/staging/msm/tvenc.c295
-rw-r--r--drivers/staging/msm/tvenc.h117
-rw-r--r--drivers/staging/phison/Kconfig2
-rw-r--r--drivers/staging/rt2860/sta_ioctl.c2
-rw-r--r--drivers/staging/sep/sep_driver.c52
-rw-r--r--drivers/staging/tm6000/Kconfig3
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c25
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c45
-rw-r--r--drivers/staging/tm6000/tm6000-core.c121
-rw-r--r--drivers/staging/tm6000/tm6000-dvb.c74
-rw-r--r--drivers/staging/tm6000/tm6000-video.c104
-rw-r--r--drivers/staging/tm6000/tm6000.h25
-rw-r--r--drivers/staging/vme/bridges/vme_ca91cx42.c2
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.c2
-rw-r--r--drivers/staging/wlags49_h2/Kconfig12
-rw-r--r--drivers/staging/wlags49_h25/Kconfig12
-rw-r--r--drivers/staging/xgifb/Kconfig11
-rw-r--r--drivers/staging/xgifb/Makefile4
-rw-r--r--drivers/staging/xgifb/TODO15
-rw-r--r--drivers/staging/xgifb/XGI.h10
-rw-r--r--drivers/staging/xgifb/XGI_accel.c596
-rw-r--r--drivers/staging/xgifb/XGI_accel.h511
-rw-r--r--drivers/staging/xgifb/XGI_main.h1023
-rw-r--r--drivers/staging/xgifb/XGI_main_26.c3773
-rw-r--r--drivers/staging/xgifb/XGIfb.h215
-rw-r--r--drivers/staging/xgifb/osdef.h153
-rw-r--r--drivers/staging/xgifb/vb_def.h1017
-rw-r--r--drivers/staging/xgifb/vb_ext.c1370
-rw-r--r--drivers/staging/xgifb/vb_ext.h32
-rw-r--r--drivers/staging/xgifb/vb_init.c3444
-rw-r--r--drivers/staging/xgifb/vb_init.h7
-rw-r--r--drivers/staging/xgifb/vb_setmode.c10736
-rw-r--r--drivers/staging/xgifb/vb_setmode.h40
-rw-r--r--drivers/staging/xgifb/vb_struct.h534
-rw-r--r--drivers/staging/xgifb/vb_table.h4406
-rw-r--r--drivers/staging/xgifb/vb_util.c263
-rw-r--r--drivers/staging/xgifb/vb_util.h15
-rw-r--r--drivers/staging/xgifb/vgatypes.h325
-rw-r--r--drivers/usb/class/cdc-acm.c6
-rw-r--r--drivers/usb/core/driver.c2
-rw-r--r--drivers/usb/gadget/Kconfig1
-rw-r--r--drivers/usb/gadget/f_audio.c4
-rw-r--r--drivers/usb/gadget/fsl_qe_udc.c4
-rw-r--r--drivers/usb/gadget/m66592-udc.h22
-rw-r--r--drivers/usb/gadget/r8a66597-udc.c4
-rw-r--r--drivers/usb/gadget/r8a66597-udc.h24
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c57
-rw-r--r--drivers/usb/host/ehci-hcd.c20
-rw-r--r--drivers/usb/host/ehci-xilinx-of.c2
-rw-r--r--drivers/usb/host/isp1362.h2
-rw-r--r--drivers/usb/host/r8a66597-hcd.c4
-rw-r--r--drivers/usb/host/r8a66597.h26
-rw-r--r--drivers/usb/host/xhci-pci.c2
-rw-r--r--drivers/usb/host/xhci-ring.c31
-rw-r--r--drivers/usb/host/xhci.c57
-rw-r--r--drivers/usb/host/xhci.h12
-rw-r--r--drivers/usb/serial/digi_acceleport.c3
-rw-r--r--drivers/usb/serial/ftdi_sio.c4
-rw-r--r--drivers/usb/serial/mos7840.c1
-rw-r--r--drivers/video/Kconfig6
-rw-r--r--drivers/video/aty/mach64_accel.c9
-rw-r--r--drivers/video/backlight/adp8860_bl.c2
-rw-r--r--drivers/video/backlight/tosa_bl.c2
-rw-r--r--drivers/video/bw2.c2
-rw-r--r--drivers/video/cg14.c2
-rw-r--r--drivers/video/cg3.c2
-rw-r--r--drivers/video/fb_defio.c52
-rw-r--r--drivers/video/leo.c2
-rw-r--r--drivers/video/mb862xx/mb862xxfb.c2
-rw-r--r--drivers/video/p9100.c2
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c6
-rw-r--r--drivers/video/tcx.c2
-rw-r--r--drivers/watchdog/gef_wdt.c2
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c2
-rw-r--r--drivers/xen/xenbus/xenbus_xs.c2
-rw-r--r--fs/afs/server.c5
-rw-r--r--fs/binfmt_elf_fdpic.c26
-rw-r--r--fs/binfmt_flat.c25
-rw-r--r--fs/cifs/file.c1
-rw-r--r--fs/compat.c2
-rw-r--r--fs/configfs/inode.c9
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext4/inode.c40
-rw-r--r--fs/ext4/move_extent.c3
-rw-r--r--fs/fcntl.c7
-rw-r--r--fs/fs-writeback.c64
-rw-r--r--fs/fscache/page.c36
-rw-r--r--fs/libfs.c3
-rw-r--r--fs/minix/dir.c4
-rw-r--r--fs/nilfs2/btree.h2
-rw-r--r--fs/nilfs2/segbuf.h2
-rw-r--r--fs/nilfs2/segment.h2
-rw-r--r--fs/nilfs2/super.c8
-rw-r--r--fs/pipe.c77
-rw-r--r--fs/splice.c2
-rw-r--r--fs/sync.c2
-rw-r--r--fs/sysfs/inode.c6
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c15
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c16
-rw-r--r--fs/xfs/linux-2.6/xfs_quotaops.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h356
-rw-r--r--fs/xfs/quota/xfs_qm.c4
-rw-r--r--fs/xfs/xfs_ag.h1
-rw-r--r--fs/xfs/xfs_iget.c29
-rw-r--r--fs/xfs/xfs_inode.c144
-rw-r--r--fs/xfs/xfs_log_recover.c11
-rw-r--r--fs/xfs/xfs_mount.c68
-rw-r--r--fs/xfs/xfs_rtalloc.c4
-rw-r--r--fs/xfs/xfs_rtalloc.h11
-rw-r--r--fs/xfs/xfs_trans.c446
-rw-r--r--fs/xfs/xfs_trans.h411
-rw-r--r--fs/xfs/xfs_vnodeops.c2
-rw-r--r--include/asm-generic/percpu.h10
-rw-r--r--include/asm-generic/vmlinux.lds.h38
-rw-r--r--include/drm/drm_crtc_helper.h3
-rw-r--r--include/drm/i915_drm.h5
-rw-r--r--include/drm/nouveau_drm.h1
-rw-r--r--include/drm/vmwgfx_drm.h26
-rw-r--r--include/linux/backing-dev.h2
-rw-r--r--include/linux/blkdev.h9
-rw-r--r--include/linux/cache.h2
-rw-r--r--include/linux/drbd.h2
-rw-r--r--include/linux/edac_mce.h31
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/init.h2
-rw-r--r--include/linux/init_task.h2
-rw-r--r--include/linux/iocontext.h1
-rw-r--r--include/linux/libata.h2
-rw-r--r--include/linux/linkage.h8
-rw-r--r--include/linux/mmc/sh_mmcif.h161
-rw-r--r--include/linux/module.h44
-rw-r--r--include/linux/netfilter/x_tables.h2
-rw-r--r--include/linux/pci.h1
-rw-r--r--include/linux/pci_ids.h52
-rw-r--r--include/linux/percpu-defs.h4
-rw-r--r--include/linux/perf_event.h9
-rw-r--r--include/linux/personality.h2
-rw-r--r--include/linux/pipe_fs_i.h4
-rw-r--r--include/linux/serial_sci.h4
-rw-r--r--include/linux/skbuff.h2
-rw-r--r--include/linux/spinlock.h2
-rw-r--r--include/linux/syscalls.h2
-rw-r--r--include/linux/usb/audio-v2.h31
-rw-r--r--include/linux/usb/audio.h90
-rw-r--r--include/linux/vgaarb.h21
-rw-r--r--include/linux/writeback.h10
-rw-r--r--include/media/rc-map.h3
-rw-r--r--include/media/soc_camera.h2
-rw-r--r--include/media/v4l2-mediabus.h21
-rw-r--r--include/media/v4l2-subdev.h2
-rw-r--r--include/net/dst.h6
-rw-r--r--include/net/sock.h15
-rw-r--r--include/scsi/scsi_host.h8
-rw-r--r--include/trace/events/sched.h19
-rw-r--r--include/trace/ftrace.h2
-rw-r--r--init/Kconfig8
-rw-r--r--ipc/mqueue.c1
-rw-r--r--kernel/cgroup.c2
-rw-r--r--kernel/cpu.c2
-rw-r--r--kernel/debug/kdb/kdb_main.c12
-rw-r--r--kernel/exec_domain.c18
-rw-r--r--kernel/module.c327
-rw-r--r--kernel/perf_event.c351
-rw-r--r--kernel/sched.c24
-rw-r--r--kernel/sched_fair.c22
-rw-r--r--kernel/softirq.c2
-rw-r--r--kernel/stop_machine.c2
-rw-r--r--kernel/sysctl.c8
-rw-r--r--kernel/timer.c2
-rw-r--r--kernel/trace/blktrace.c2
-rw-r--r--kernel/trace/trace_event_perf.c15
-rw-r--r--kernel/trace/trace_kprobe.c4
-rw-r--r--kernel/trace/trace_syscalls.c4
-rw-r--r--lib/atomic64_test.c3
-rw-r--r--lib/kobject_uevent.c3
-rw-r--r--mm/page-writeback.c4
-rw-r--r--mm/shmem.c5
-rw-r--r--mm/vmscan.c29
-rw-r--r--net/8021q/vlan_dev.c3
-rw-r--r--net/caif/cfserl.c6
-rw-r--r--net/core/dev.c8
-rw-r--r--net/core/skbuff.c42
-rw-r--r--net/ipv4/Kconfig10
-rw-r--r--net/ipv4/netfilter/ip_tables.c2
-rw-r--r--net/ipv4/syncookies.c2
-rw-r--r--net/ipv4/tcp_hybla.c4
-rw-r--r--net/ipv4/tcp_input.c4
-rw-r--r--net/ipv4/tcp_ipv4.c7
-rw-r--r--net/ipv4/udp.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c2
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/mac80211/agg-tx.c6
-rw-r--r--net/mac80211/chan.c2
-rw-r--r--net/mac80211/rx.c13
-rw-r--r--net/netfilter/x_tables.c17
-rw-r--r--net/phonet/pep.c6
-rw-r--r--net/rds/ib_cm.c1
-rw-r--r--net/rds/iw_cm.c1
-rw-r--r--net/sched/act_nat.c4
-rw-r--r--net/sched/act_pedit.c24
-rw-r--r--net/sched/cls_u32.c49
-rw-r--r--net/xfrm/xfrm_output.c4
-rw-r--r--net/xfrm/xfrm_policy.c1
-rw-r--r--scripts/Makefile.build2
-rw-r--r--scripts/Makefile.lib2
-rwxr-xr-xscripts/checkincludes.pl24
-rwxr-xr-xscripts/checkstack.pl16
-rwxr-xr-xscripts/checkversion.pl23
-rwxr-xr-xscripts/decodecode48
-rw-r--r--scripts/export_report.pl37
-rw-r--r--scripts/gen_initramfs_list.sh3
-rw-r--r--scripts/genksyms/genksyms.c4
-rwxr-xr-xscripts/headerdep.pl3
-rw-r--r--scripts/headers_check.pl11
-rw-r--r--scripts/headers_install.pl19
-rw-r--r--scripts/kallsyms.c6
-rw-r--r--scripts/kconfig/Makefile18
-rw-r--r--scripts/kconfig/expr.c27
-rw-r--r--scripts/kconfig/expr.h5
-rw-r--r--scripts/kconfig/gconf.c113
-rw-r--r--scripts/kconfig/gconf.glade26
-rw-r--r--scripts/kconfig/lkc.h7
-rw-r--r--scripts/kconfig/lkc_proto.h6
-rw-r--r--scripts/kconfig/lxdialog/inputbox.c4
-rw-r--r--scripts/kconfig/lxdialog/menubox.c22
-rw-r--r--scripts/kconfig/mconf.c36
-rw-r--r--scripts/kconfig/menu.c28
-rw-r--r--scripts/kconfig/nconf.c1568
-rw-r--r--scripts/kconfig/nconf.gui.c617
-rw-r--r--scripts/kconfig/nconf.h95
-rw-r--r--scripts/kconfig/symbol.c30
-rw-r--r--scripts/kconfig/util.c2
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped25
-rw-r--r--scripts/kconfig/zconf.y25
-rw-r--r--scripts/markup_oops.pl54
-rwxr-xr-xscripts/mkcompile_h5
-rw-r--r--scripts/mod/modpost.c152
-rwxr-xr-xscripts/namespace.pl65
-rw-r--r--scripts/package/builddeb2
-rwxr-xr-xscripts/package/mkspec2
-rw-r--r--scripts/profile2linkerlist.pl8
-rw-r--r--scripts/rt-tester/rt-tester.py2
-rwxr-xr-xscripts/show_delta2
-rwxr-xr-xscripts/tags.sh45
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c8
-rw-r--r--sound/atmel/ac97c.c2
-rw-r--r--sound/pci/asihpi/asihpi.c3
-rw-r--r--sound/pci/hda/hda_intel.c7
-rw-r--r--sound/pci/hda/patch_realtek.c39
-rw-r--r--sound/spi/at73c213.c1
-rw-r--r--sound/usb/Makefile3
-rw-r--r--sound/usb/card.c18
-rw-r--r--sound/usb/card.h1
-rw-r--r--sound/usb/clock.c315
-rw-r--r--sound/usb/clock.h12
-rw-r--r--sound/usb/endpoint.c57
-rw-r--r--sound/usb/format.c116
-rw-r--r--sound/usb/helper.h4
-rw-r--r--sound/usb/mixer.c232
-rw-r--r--sound/usb/mixer.h2
-rw-r--r--sound/usb/mixer_maps.c4
-rw-r--r--sound/usb/pcm.c98
-rw-r--r--sound/usb/usbaudio.h5
-rw-r--r--tools/perf/builtin-buildid-list.c4
-rw-r--r--tools/perf/builtin-record.c3
-rw-r--r--tools/perf/builtin-sched.c1
-rw-r--r--tools/perf/scripts/python/check-perf-trace.py3
-rw-r--r--tools/perf/util/event.c13
-rw-r--r--tools/perf/util/hist.c2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c50
903 files changed, 82124 insertions, 7107 deletions
diff --git a/.gitignore b/.gitignore
index a2939fc10b22..8faa6c02b39e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,7 @@ modules.builtin
28*.gz 28*.gz
29*.bz2 29*.bz2
30*.lzma 30*.lzma
31*.lzo
31*.patch 32*.patch
32*.gcno 33*.gcno
33 34
diff --git a/Documentation/.gitignore b/Documentation/.gitignore
new file mode 100644
index 000000000000..bcd907b4141f
--- /dev/null
+++ b/Documentation/.gitignore
@@ -0,0 +1,7 @@
1filesystems/dnotify_test
2laptops/dslm
3timers/hpet_example
4vm/hugepage-mmap
5vm/hugepage-shm
6vm/map_hugetlb
7
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 7583dc7cf64d..910c923a9b86 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -389,7 +389,7 @@
389 </para> 389 </para>
390 <para> 390 <para>
391 If your driver supports memory management (it should!), you'll 391 If your driver supports memory management (it should!), you'll
392 need to set that up at load time as well. How you intialize 392 need to set that up at load time as well. How you initialize
393 it depends on which memory manager you're using, TTM or GEM. 393 it depends on which memory manager you're using, TTM or GEM.
394 </para> 394 </para>
395 <sect3> 395 <sect3>
@@ -399,7 +399,7 @@
399 aperture space for graphics devices. TTM supports both UMA devices 399 aperture space for graphics devices. TTM supports both UMA devices
400 and devices with dedicated video RAM (VRAM), i.e. most discrete 400 and devices with dedicated video RAM (VRAM), i.e. most discrete
401 graphics devices. If your device has dedicated RAM, supporting 401 graphics devices. If your device has dedicated RAM, supporting
402 TTM is desireable. TTM also integrates tightly with your 402 TTM is desirable. TTM also integrates tightly with your
403 driver specific buffer execution function. See the radeon 403 driver specific buffer execution function. See the radeon
404 driver for examples. 404 driver for examples.
405 </para> 405 </para>
@@ -443,7 +443,7 @@
443 likely eventually calling ttm_bo_global_init and 443 likely eventually calling ttm_bo_global_init and
444 ttm_bo_global_release, respectively. Also like the previous 444 ttm_bo_global_release, respectively. Also like the previous
445 object, ttm_global_item_ref is used to create an initial reference 445 object, ttm_global_item_ref is used to create an initial reference
446 count for the TTM, which will call your initalization function. 446 count for the TTM, which will call your initialization function.
447 </para> 447 </para>
448 </sect3> 448 </sect3>
449 <sect3> 449 <sect3>
@@ -557,7 +557,7 @@ void intel_crt_init(struct drm_device *dev)
557 CRT connector and encoder combination is created. A device 557 CRT connector and encoder combination is created. A device
558 specific i2c bus is also created, for fetching EDID data and 558 specific i2c bus is also created, for fetching EDID data and
559 performing monitor detection. Once the process is complete, 559 performing monitor detection. Once the process is complete,
560 the new connector is regsitered with sysfs, to make its 560 the new connector is registered with sysfs, to make its
561 properties available to applications. 561 properties available to applications.
562 </para> 562 </para>
563 <sect4> 563 <sect4>
@@ -581,12 +581,12 @@ void intel_crt_init(struct drm_device *dev)
581 <para> 581 <para>
582 For each encoder, CRTC and connector, several functions must 582 For each encoder, CRTC and connector, several functions must
583 be provided, depending on the object type. Encoder objects 583 be provided, depending on the object type. Encoder objects
584 need should provide a DPMS (basically on/off) function, mode fixup 584 need to provide a DPMS (basically on/off) function, mode fixup
585 (for converting requested modes into native hardware timings), 585 (for converting requested modes into native hardware timings),
586 and prepare, set and commit functions for use by the core DRM 586 and prepare, set and commit functions for use by the core DRM
587 helper functions. Connector helpers need to provide mode fetch and 587 helper functions. Connector helpers need to provide mode fetch and
588 validity functions as well as an encoder matching function for 588 validity functions as well as an encoder matching function for
589 returing an ideal encoder for a given connector. The core 589 returning an ideal encoder for a given connector. The core
590 connector functions include a DPMS callback, (deprecated) 590 connector functions include a DPMS callback, (deprecated)
591 save/restore routines, detection, mode probing, property handling, 591 save/restore routines, detection, mode probing, property handling,
592 and cleanup functions. 592 and cleanup functions.
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml
index 9737243377a3..7c3c098d5d08 100644
--- a/Documentation/DocBook/v4l/v4l2.xml
+++ b/Documentation/DocBook/v4l/v4l2.xml
@@ -58,7 +58,7 @@ MPEG stream embedded, sliced VBI data format in this specification.
58</contrib> 58</contrib>
59 <affiliation> 59 <affiliation>
60 <address> 60 <address>
61 <email>awalls@radix.net</email> 61 <email>awalls@md.metrocast.net</email>
62 </address> 62 </address>
63 </affiliation> 63 </affiliation>
64 </author> 64 </author>
diff --git a/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml b/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
index 87e4f0f6151c..402229ee06f6 100644
--- a/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
+++ b/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
@@ -53,8 +53,10 @@ input</refpurpose>
53automatically, similar to sensing the video standard. To do so, applications 53automatically, similar to sensing the video standard. To do so, applications
54call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a 54call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a
55&v4l2-dv-preset; type. Once the hardware detects a preset, that preset is 55&v4l2-dv-preset; type. Once the hardware detects a preset, that preset is
56returned in the preset field of &v4l2-dv-preset;. When detection is not 56returned in the preset field of &v4l2-dv-preset;. If the preset could not be
57possible or fails, the value V4L2_DV_INVALID is returned.</para> 57detected because there was no signal, or the signal was unreliable, or the
58signal did not map to a supported preset, then the value V4L2_DV_INVALID is
59returned.</para>
58 </refsect1> 60 </refsect1>
59 61
60 <refsect1> 62 <refsect1>
diff --git a/Documentation/edac.txt b/Documentation/edac.txt
index 79c533223762..0b875e8da969 100644
--- a/Documentation/edac.txt
+++ b/Documentation/edac.txt
@@ -6,6 +6,8 @@ Written by Doug Thompson <dougthompson@xmission.com>
67 Dec 2005 67 Dec 2005
717 Jul 2007 Updated 717 Jul 2007 Updated
8 8
9(c) Mauro Carvalho Chehab <mchehab@redhat.com>
1005 Aug 2009 Nehalem interface
9 11
10EDAC is maintained and written by: 12EDAC is maintained and written by:
11 13
@@ -717,3 +719,153 @@ unique drivers for their hardware systems.
717The 'test_device_edac' sample driver is located at the 719The 'test_device_edac' sample driver is located at the
718bluesmoke.sourceforge.net project site for EDAC. 720bluesmoke.sourceforge.net project site for EDAC.
719 721
722=======================================================================
723NEHALEM USAGE OF EDAC APIs
724
725This chapter documents some EXPERIMENTAL mappings for EDAC API to handle
726Nehalem EDAC driver. They will likely be changed on future versions
727of the driver.
728
729Due to the way Nehalem exports Memory Controller data, some adjustments
730were done at i7core_edac driver. This chapter will cover those differences
731
7321) On Nehalem, there are one Memory Controller per Quick Patch Interconnect
733 (QPI). At the driver, the term "socket" means one QPI. This is
734 associated with a physical CPU socket.
735
736 Each MC have 3 physical read channels, 3 physical write channels and
737 3 logic channels. The driver currenty sees it as just 3 channels.
738 Each channel can have up to 3 DIMMs.
739
740 The minimum known unity is DIMMs. There are no information about csrows.
741 As EDAC API maps the minimum unity is csrows, the driver sequencially
742 maps channel/dimm into different csrows.
743
744 For example, suposing the following layout:
745 Ch0 phy rd0, wr0 (0x063f4031): 2 ranks, UDIMMs
746 dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400
747 dimm 1 1024 Mb offset: 4, bank: 8, rank: 1, row: 0x4000, col: 0x400
748 Ch1 phy rd1, wr1 (0x063f4031): 2 ranks, UDIMMs
749 dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400
750 Ch2 phy rd3, wr3 (0x063f4031): 2 ranks, UDIMMs
751 dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400
752 The driver will map it as:
753 csrow0: channel 0, dimm0
754 csrow1: channel 0, dimm1
755 csrow2: channel 1, dimm0
756 csrow3: channel 2, dimm0
757
758exports one
759 DIMM per csrow.
760
761 Each QPI is exported as a different memory controller.
762
7632) Nehalem MC has the hability to generate errors. The driver implements this
764 functionality via some error injection nodes:
765
766 For injecting a memory error, there are some sysfs nodes, under
767 /sys/devices/system/edac/mc/mc?/:
768
769 inject_addrmatch/*:
770 Controls the error injection mask register. It is possible to specify
771 several characteristics of the address to match an error code:
772 dimm = the affected dimm. Numbers are relative to a channel;
773 rank = the memory rank;
774 channel = the channel that will generate an error;
775 bank = the affected bank;
776 page = the page address;
777 column (or col) = the address column.
778 each of the above values can be set to "any" to match any valid value.
779
780 At driver init, all values are set to any.
781
782 For example, to generate an error at rank 1 of dimm 2, for any channel,
783 any bank, any page, any column:
784 echo 2 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/dimm
785 echo 1 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/rank
786
787 To return to the default behaviour of matching any, you can do:
788 echo any >/sys/devices/system/edac/mc/mc0/inject_addrmatch/dimm
789 echo any >/sys/devices/system/edac/mc/mc0/inject_addrmatch/rank
790
791 inject_eccmask:
792 specifies what bits will have troubles,
793
794 inject_section:
795 specifies what ECC cache section will get the error:
796 3 for both
797 2 for the highest
798 1 for the lowest
799
800 inject_type:
801 specifies the type of error, being a combination of the following bits:
802 bit 0 - repeat
803 bit 1 - ecc
804 bit 2 - parity
805
806 inject_enable starts the error generation when something different
807 than 0 is written.
808
809 All inject vars can be read. root permission is needed for write.
810
811 Datasheet states that the error will only be generated after a write on an
812 address that matches inject_addrmatch. It seems, however, that reading will
813 also produce an error.
814
815 For example, the following code will generate an error for any write access
816 at socket 0, on any DIMM/address on channel 2:
817
818 echo 2 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/channel
819 echo 2 >/sys/devices/system/edac/mc/mc0/inject_type
820 echo 64 >/sys/devices/system/edac/mc/mc0/inject_eccmask
821 echo 3 >/sys/devices/system/edac/mc/mc0/inject_section
822 echo 1 >/sys/devices/system/edac/mc/mc0/inject_enable
823 dd if=/dev/mem of=/dev/null seek=16k bs=4k count=1 >& /dev/null
824
825 For socket 1, it is needed to replace "mc0" by "mc1" at the above
826 commands.
827
828 The generated error message will look like:
829
830 EDAC MC0: UE row 0, channel-a= 0 channel-b= 0 labels "-": NON_FATAL (addr = 0x0075b980, socket=0, Dimm=0, Channel=2, syndrome=0x00000040, count=1, Err=8c0000400001009f:4000080482 (read error: read ECC error))
831
8323) Nehalem specific Corrected Error memory counters
833
834 Nehalem have some registers to count memory errors. The driver uses those
835 registers to report Corrected Errors on devices with Registered Dimms.
836
837 However, those counters don't work with Unregistered Dimms. As the chipset
838 offers some counters that also work with UDIMMS (but with a worse level of
839 granularity than the default ones), the driver exposes those registers for
840 UDIMM memories.
841
842 They can be read by looking at the contents of all_channel_counts/
843
844 $ for i in /sys/devices/system/edac/mc/mc0/all_channel_counts/*; do echo $i; cat $i; done
845 /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm0
846 0
847 /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm1
848 0
849 /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm2
850 0
851
852 What happens here is that errors on different csrows, but at the same
853 dimm number will increment the same counter.
854 So, in this memory mapping:
855 csrow0: channel 0, dimm0
856 csrow1: channel 0, dimm1
857 csrow2: channel 1, dimm0
858 csrow3: channel 2, dimm0
859 The hardware will increment udimm0 for an error at the first dimm at either
860 csrow0, csrow2 or csrow3;
861 The hardware will increment udimm1 for an error at the second dimm at either
862 csrow0, csrow2 or csrow3;
863 The hardware will increment udimm2 for an error at the third dimm at either
864 csrow0, csrow2 or csrow3;
865
8664) Standard error counters
867
868 The standard error counters are generated when an mcelog error is received
869 by the driver. Since, with udimm, this is counted by software, it is
870 possible that some errors could be lost. With rdimm's, they displays the
871 contents of the registers
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 672be0109d02..c268783bc4e7 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -578,15 +578,6 @@ Who: Avi Kivity <avi@redhat.com>
578 578
579---------------------------- 579----------------------------
580 580
581What: "acpi=ht" boot option
582When: 2.6.35
583Why: Useful in 2003, implementation is a hack.
584 Generally invoked by accident today.
585 Seen as doing more harm than good.
586Who: Len Brown <len.brown@intel.com>
587
588----------------------------
589
590What: iwlwifi 50XX module parameters 581What: iwlwifi 50XX module parameters
591When: 2.6.40 582When: 2.6.40
592Why: The "..50" modules parameters were used to configure 5000 series and 583Why: The "..50" modules parameters were used to configure 5000 series and
diff --git a/Documentation/filesystems/xfs-delayed-logging-design.txt b/Documentation/filesystems/xfs-delayed-logging-design.txt
index d8119e9d2d60..96d0df28bed3 100644
--- a/Documentation/filesystems/xfs-delayed-logging-design.txt
+++ b/Documentation/filesystems/xfs-delayed-logging-design.txt
@@ -794,11 +794,6 @@ designed.
794 794
795Roadmap: 795Roadmap:
796 796
7972.6.35 Inclusion in mainline as an experimental mount option
798 => approximately 2-3 months to merge window
799 => needs to be in xfs-dev tree in 4-6 weeks
800 => code is nearing readiness for review
801
8022.6.37 Remove experimental tag from mount option 7972.6.37 Remove experimental tag from mount option
803 => should be roughly 6 months after initial merge 798 => should be roughly 6 months after initial merge
804 => enough time to: 799 => enough time to:
diff --git a/Documentation/i2c/busses/i2c-ali1535 b/Documentation/i2c/busses/i2c-ali1535
index 0db3b4c74ad1..acbc65a08097 100644
--- a/Documentation/i2c/busses/i2c-ali1535
+++ b/Documentation/i2c/busses/i2c-ali1535
@@ -6,12 +6,12 @@ Supported adapters:
6 http://www.ali.com.tw/eng/support/datasheet_request.php 6 http://www.ali.com.tw/eng/support/datasheet_request.php
7 7
8Authors: 8Authors:
9 Frodo Looijaard <frodol@dds.nl>, 9 Frodo Looijaard <frodol@dds.nl>,
10 Philip Edelbrock <phil@netroedge.com>, 10 Philip Edelbrock <phil@netroedge.com>,
11 Mark D. Studebaker <mdsxyz123@yahoo.com>, 11 Mark D. Studebaker <mdsxyz123@yahoo.com>,
12 Dan Eaton <dan.eaton@rocketlogix.com>, 12 Dan Eaton <dan.eaton@rocketlogix.com>,
13 Stephen Rousset<stephen.rousset@rocketlogix.com> 13 Stephen Rousset<stephen.rousset@rocketlogix.com>
14 14
15Description 15Description
16----------- 16-----------
17 17
diff --git a/Documentation/i2c/busses/i2c-ali1563 b/Documentation/i2c/busses/i2c-ali1563
index 99ad4b9bcc32..54691698d2dd 100644
--- a/Documentation/i2c/busses/i2c-ali1563
+++ b/Documentation/i2c/busses/i2c-ali1563
@@ -18,7 +18,7 @@ For an overview of these chips see http://www.acerlabs.com
18The M1563 southbridge is deceptively similar to the M1533, with a few 18The M1563 southbridge is deceptively similar to the M1533, with a few
19notable exceptions. One of those happens to be the fact they upgraded the 19notable exceptions. One of those happens to be the fact they upgraded the
20i2c core to be SMBus 2.0 compliant, and happens to be almost identical to 20i2c core to be SMBus 2.0 compliant, and happens to be almost identical to
21the i2c controller found in the Intel 801 south bridges. 21the i2c controller found in the Intel 801 south bridges.
22 22
23Features 23Features
24-------- 24--------
diff --git a/Documentation/i2c/busses/i2c-ali15x3 b/Documentation/i2c/busses/i2c-ali15x3
index ff28d381bebe..600da90b8f12 100644
--- a/Documentation/i2c/busses/i2c-ali15x3
+++ b/Documentation/i2c/busses/i2c-ali15x3
@@ -6,8 +6,8 @@ Supported adapters:
6 http://www.ali.com.tw/eng/support/datasheet_request.php 6 http://www.ali.com.tw/eng/support/datasheet_request.php
7 7
8Authors: 8Authors:
9 Frodo Looijaard <frodol@dds.nl>, 9 Frodo Looijaard <frodol@dds.nl>,
10 Philip Edelbrock <phil@netroedge.com>, 10 Philip Edelbrock <phil@netroedge.com>,
11 Mark D. Studebaker <mdsxyz123@yahoo.com> 11 Mark D. Studebaker <mdsxyz123@yahoo.com>
12 12
13Module Parameters 13Module Parameters
@@ -40,10 +40,10 @@ M1541 and M1543C South Bridges.
40The M1543C is a South bridge for desktop systems. 40The M1543C is a South bridge for desktop systems.
41The M1541 is a South bridge for portable systems. 41The M1541 is a South bridge for portable systems.
42They are part of the following ALI chipsets: 42They are part of the following ALI chipsets:
43 43
44 * "Aladdin Pro 2" includes the M1621 Slot 1 North bridge with AGP and 44 * "Aladdin Pro 2" includes the M1621 Slot 1 North bridge with AGP and
45 100MHz CPU Front Side bus 45 100MHz CPU Front Side bus
46 * "Aladdin V" includes the M1541 Socket 7 North bridge with AGP and 100MHz 46 * "Aladdin V" includes the M1541 Socket 7 North bridge with AGP and 100MHz
47 CPU Front Side bus 47 CPU Front Side bus
48 Some Aladdin V motherboards: 48 Some Aladdin V motherboards:
49 Asus P5A 49 Asus P5A
@@ -77,7 +77,7 @@ output of lspci will show something similar to the following:
77** then run lspci. 77** then run lspci.
78** If you see the 1533 and 5229 devices but NOT the 7101 device, 78** If you see the 1533 and 5229 devices but NOT the 7101 device,
79** then you must enable ACPI, the PMU, SMB, or something similar 79** then you must enable ACPI, the PMU, SMB, or something similar
80** in the BIOS. 80** in the BIOS.
81** The driver won't work if it can't find the M7101 device. 81** The driver won't work if it can't find the M7101 device.
82 82
83The SMB controller is part of the M7101 device, which is an ACPI-compliant 83The SMB controller is part of the M7101 device, which is an ACPI-compliant
@@ -87,8 +87,8 @@ The whole M7101 device has to be enabled for the SMB to work. You can't
87just enable the SMB alone. The SMB and the ACPI have separate I/O spaces. 87just enable the SMB alone. The SMB and the ACPI have separate I/O spaces.
88We make sure that the SMB is enabled. We leave the ACPI alone. 88We make sure that the SMB is enabled. We leave the ACPI alone.
89 89
90Features 90Features
91-------- 91--------
92 92
93This driver controls the SMB Host only. The SMB Slave 93This driver controls the SMB Host only. The SMB Slave
94controller on the M15X3 is not enabled. This driver does not use 94controller on the M15X3 is not enabled. This driver does not use
diff --git a/Documentation/i2c/busses/i2c-pca-isa b/Documentation/i2c/busses/i2c-pca-isa
index 6fc8f4c27c3c..b044e5265488 100644
--- a/Documentation/i2c/busses/i2c-pca-isa
+++ b/Documentation/i2c/busses/i2c-pca-isa
@@ -1,10 +1,10 @@
1Kernel driver i2c-pca-isa 1Kernel driver i2c-pca-isa
2 2
3Supported adapters: 3Supported adapters:
4This driver supports ISA boards using the Philips PCA 9564 4This driver supports ISA boards using the Philips PCA 9564
5Parallel bus to I2C bus controller 5Parallel bus to I2C bus controller
6 6
7Author: Ian Campbell <icampbell@arcom.com>, Arcom Control Systems 7Author: Ian Campbell <icampbell@arcom.com>, Arcom Control Systems
8 8
9Module Parameters 9Module Parameters
10----------------- 10-----------------
@@ -12,12 +12,12 @@ Module Parameters
12* base int 12* base int
13 I/O base address 13 I/O base address
14* irq int 14* irq int
15 IRQ interrupt 15 IRQ interrupt
16* clock int 16* clock int
17 Clock rate as described in table 1 of PCA9564 datasheet 17 Clock rate as described in table 1 of PCA9564 datasheet
18 18
19Description 19Description
20----------- 20-----------
21 21
22This driver supports ISA boards using the Philips PCA 9564 22This driver supports ISA boards using the Philips PCA 9564
23Parallel bus to I2C bus controller 23Parallel bus to I2C bus controller
diff --git a/Documentation/i2c/busses/i2c-sis5595 b/Documentation/i2c/busses/i2c-sis5595
index cc47db7d00a9..ecd21fb49a8f 100644
--- a/Documentation/i2c/busses/i2c-sis5595
+++ b/Documentation/i2c/busses/i2c-sis5595
@@ -1,41 +1,41 @@
1Kernel driver i2c-sis5595 1Kernel driver i2c-sis5595
2 2
3Authors: 3Authors:
4 Frodo Looijaard <frodol@dds.nl>, 4 Frodo Looijaard <frodol@dds.nl>,
5 Mark D. Studebaker <mdsxyz123@yahoo.com>, 5 Mark D. Studebaker <mdsxyz123@yahoo.com>,
6 Philip Edelbrock <phil@netroedge.com> 6 Philip Edelbrock <phil@netroedge.com>
7 7
8Supported adapters: 8Supported adapters:
9 * Silicon Integrated Systems Corp. SiS5595 Southbridge 9 * Silicon Integrated Systems Corp. SiS5595 Southbridge
10 Datasheet: Publicly available at the Silicon Integrated Systems Corp. site. 10 Datasheet: Publicly available at the Silicon Integrated Systems Corp. site.
11 11
12Note: all have mfr. ID 0x1039. 12Note: all have mfr. ID 0x1039.
13 13
14 SUPPORTED PCI ID 14 SUPPORTED PCI ID
15 5595 0008 15 5595 0008
16 16
17 Note: these chips contain a 0008 device which is incompatible with the 17 Note: these chips contain a 0008 device which is incompatible with the
18 5595. We recognize these by the presence of the listed 18 5595. We recognize these by the presence of the listed
19 "blacklist" PCI ID and refuse to load. 19 "blacklist" PCI ID and refuse to load.
20 20
21 NOT SUPPORTED PCI ID BLACKLIST PCI ID 21 NOT SUPPORTED PCI ID BLACKLIST PCI ID
22 540 0008 0540 22 540 0008 0540
23 550 0008 0550 23 550 0008 0550
24 5513 0008 5511 24 5513 0008 5511
25 5581 0008 5597 25 5581 0008 5597
26 5582 0008 5597 26 5582 0008 5597
27 5597 0008 5597 27 5597 0008 5597
28 5598 0008 5597/5598 28 5598 0008 5597/5598
29 630 0008 0630 29 630 0008 0630
30 645 0008 0645 30 645 0008 0645
31 646 0008 0646 31 646 0008 0646
32 648 0008 0648 32 648 0008 0648
33 650 0008 0650 33 650 0008 0650
34 651 0008 0651 34 651 0008 0651
35 730 0008 0730 35 730 0008 0730
36 735 0008 0735 36 735 0008 0735
37 745 0008 0745 37 745 0008 0745
38 746 0008 0746 38 746 0008 0746
39 39
40Module Parameters 40Module Parameters
41----------------- 41-----------------
diff --git a/Documentation/i2c/busses/i2c-sis630 b/Documentation/i2c/busses/i2c-sis630
index 9aca6889f748..629ea2c356fd 100644
--- a/Documentation/i2c/busses/i2c-sis630
+++ b/Documentation/i2c/busses/i2c-sis630
@@ -14,9 +14,9 @@ Module Parameters
14* force = [1|0] Forcibly enable the SIS630. DANGEROUS! 14* force = [1|0] Forcibly enable the SIS630. DANGEROUS!
15 This can be interesting for chipsets not named 15 This can be interesting for chipsets not named
16 above to check if it works for you chipset, but DANGEROUS! 16 above to check if it works for you chipset, but DANGEROUS!
17 17
18* high_clock = [1|0] Forcibly set Host Master Clock to 56KHz (default, 18* high_clock = [1|0] Forcibly set Host Master Clock to 56KHz (default,
19 what your BIOS use). DANGEROUS! This should be a bit 19 what your BIOS use). DANGEROUS! This should be a bit
20 faster, but freeze some systems (i.e. my Laptop). 20 faster, but freeze some systems (i.e. my Laptop).
21 21
22 22
@@ -44,6 +44,6 @@ Philip Edelbrock <phil@netroedge.com>
44- testing SiS730 support 44- testing SiS730 support
45Mark M. Hoffman <mhoffman@lightlink.com> 45Mark M. Hoffman <mhoffman@lightlink.com>
46- bug fixes 46- bug fixes
47 47
48To anyone else which I forgot here ;), thanks! 48To anyone else which I forgot here ;), thanks!
49 49
diff --git a/Documentation/i2c/ten-bit-addresses b/Documentation/i2c/ten-bit-addresses
index 200074f81360..e9890709c508 100644
--- a/Documentation/i2c/ten-bit-addresses
+++ b/Documentation/i2c/ten-bit-addresses
@@ -1,17 +1,17 @@
1The I2C protocol knows about two kinds of device addresses: normal 7 bit 1The I2C protocol knows about two kinds of device addresses: normal 7 bit
2addresses, and an extended set of 10 bit addresses. The sets of addresses 2addresses, and an extended set of 10 bit addresses. The sets of addresses
3do not intersect: the 7 bit address 0x10 is not the same as the 10 bit 3do not intersect: the 7 bit address 0x10 is not the same as the 10 bit
4address 0x10 (though a single device could respond to both of them). You 4address 0x10 (though a single device could respond to both of them). You
5select a 10 bit address by adding an extra byte after the address 5select a 10 bit address by adding an extra byte after the address
6byte: 6byte:
7 S Addr7 Rd/Wr .... 7 S Addr7 Rd/Wr ....
8becomes 8becomes
9 S 11110 Addr10 Rd/Wr 9 S 11110 Addr10 Rd/Wr
10S is the start bit, Rd/Wr the read/write bit, and if you count the number 10S is the start bit, Rd/Wr the read/write bit, and if you count the number
11of bits, you will see the there are 8 after the S bit for 7 bit addresses, 11of bits, you will see the there are 8 after the S bit for 7 bit addresses,
12and 16 after the S bit for 10 bit addresses. 12and 16 after the S bit for 10 bit addresses.
13 13
14WARNING! The current 10 bit address support is EXPERIMENTAL. There are 14WARNING! The current 10 bit address support is EXPERIMENTAL. There are
15several places in the code that will cause SEVERE PROBLEMS with 10 bit 15several places in the code that will cause SEVERE PROBLEMS with 10 bit
16addresses, even though there is some basic handling and hooks. Also, 16addresses, even though there is some basic handling and hooks. Also,
17almost no supported adapter handles the 10 bit addresses correctly. 17almost no supported adapter handles the 10 bit addresses correctly.
diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt
index 6f8c1cabbc5d..634c625da8ce 100644
--- a/Documentation/kbuild/kbuild.txt
+++ b/Documentation/kbuild/kbuild.txt
@@ -65,7 +65,7 @@ CROSS_COMPILE
65Specify an optional fixed part of the binutils filename. 65Specify an optional fixed part of the binutils filename.
66CROSS_COMPILE can be a part of the filename or the full path. 66CROSS_COMPILE can be a part of the filename or the full path.
67 67
68CROSS_COMPILE is also used for ccache is some setups. 68CROSS_COMPILE is also used for ccache in some setups.
69 69
70CF 70CF
71-------------------------------------------------- 71--------------------------------------------------
@@ -162,3 +162,7 @@ For tags/TAGS/cscope targets, you can specify more than one arch
162to be included in the databases, separated by blank space. E.g.: 162to be included in the databases, separated by blank space. E.g.:
163 163
164 $ make ALLSOURCE_ARCHS="x86 mips arm" tags 164 $ make ALLSOURCE_ARCHS="x86 mips arm" tags
165
166To get all available archs you can also specify all. E.g.:
167
168 $ make ALLSOURCE_ARCHS=all tags
diff --git a/Documentation/mutex-design.txt b/Documentation/mutex-design.txt
index aa60d1f627e5..c91ccc0720fa 100644
--- a/Documentation/mutex-design.txt
+++ b/Documentation/mutex-design.txt
@@ -66,14 +66,14 @@ of advantages of mutexes:
66 66
67 c0377ccb <mutex_lock>: 67 c0377ccb <mutex_lock>:
68 c0377ccb: f0 ff 08 lock decl (%eax) 68 c0377ccb: f0 ff 08 lock decl (%eax)
69 c0377cce: 78 0e js c0377cde <.text.lock.mutex> 69 c0377cce: 78 0e js c0377cde <.text..lock.mutex>
70 c0377cd0: c3 ret 70 c0377cd0: c3 ret
71 71
72 the unlocking fastpath is equally tight: 72 the unlocking fastpath is equally tight:
73 73
74 c0377cd1 <mutex_unlock>: 74 c0377cd1 <mutex_unlock>:
75 c0377cd1: f0 ff 00 lock incl (%eax) 75 c0377cd1: f0 ff 00 lock incl (%eax)
76 c0377cd4: 7e 0f jle c0377ce5 <.text.lock.mutex+0x7> 76 c0377cd4: 7e 0f jle c0377ce5 <.text..lock.mutex+0x7>
77 c0377cd6: c3 ret 77 c0377cd6: c3 ret
78 78
79 - 'struct mutex' semantics are well-defined and are enforced if 79 - 'struct mutex' semantics are well-defined and are enforced if
diff --git a/Documentation/timers/Makefile b/Documentation/timers/Makefile
index c85625f4ab25..73f75f8a87dc 100644
--- a/Documentation/timers/Makefile
+++ b/Documentation/timers/Makefile
@@ -2,7 +2,7 @@
2obj- := dummy.o 2obj- := dummy.o
3 3
4# List of programs to build 4# List of programs to build
5hostprogs-y := hpet_example 5hostprogs-$(CONFIG_X86) := hpet_example
6 6
7# Tell kbuild to always build the programs 7# Tell kbuild to always build the programs
8always := $(hostprogs-y) 8always := $(hostprogs-y)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 070f2576707e..1387a69ae3aa 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -176,5 +176,6 @@
176175 -> Leadtek Winfast DTV1000S [107d:6655] 176175 -> Leadtek Winfast DTV1000S [107d:6655]
177176 -> Beholder BeholdTV 505 RDS [0000:5051] 177176 -> Beholder BeholdTV 505 RDS [0000:5051]
178177 -> Hawell HW-404M7 178177 -> Hawell HW-404M7
179179 -> Beholder BeholdTV H7 [5ace:7190] 179178 -> Beholder BeholdTV H7 [5ace:7190]
180180 -> Beholder BeholdTV A7 [5ace:7090] 180179 -> Beholder BeholdTV A7 [5ace:7090]
181180 -> Avermedia M733A [1461:4155,1461:4255]
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 8f3f5d33327c..f13eb036c439 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -290,6 +290,7 @@ sonixb 0c45:602e Genius VideoCam Messenger
290sonixj 0c45:6040 Speed NVC 350K 290sonixj 0c45:6040 Speed NVC 350K
291sonixj 0c45:607c Sonix sn9c102p Hv7131R 291sonixj 0c45:607c Sonix sn9c102p Hv7131R
292sonixj 0c45:60c0 Sangha Sn535 292sonixj 0c45:60c0 Sangha Sn535
293sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067)
293sonixj 0c45:60ec SN9C105+MO4000 294sonixj 0c45:60ec SN9C105+MO4000
294sonixj 0c45:60fb Surfer NoName 295sonixj 0c45:60fb Surfer NoName
295sonixj 0c45:60fc LG-LIC300 296sonixj 0c45:60fc LG-LIC300
diff --git a/MAINTAINERS b/MAINTAINERS
index 13608bd2e791..67accd730ac9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1731,7 +1731,7 @@ S: Maintained
1731F: sound/pci/cs5535audio/ 1731F: sound/pci/cs5535audio/
1732 1732
1733CX18 VIDEO4LINUX DRIVER 1733CX18 VIDEO4LINUX DRIVER
1734M: Andy Walls <awalls@radix.net> 1734M: Andy Walls <awalls@md.metrocast.net>
1735L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) 1735L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
1736L: linux-media@vger.kernel.org 1736L: linux-media@vger.kernel.org
1737T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git 1737T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
@@ -3165,7 +3165,7 @@ F: Documentation/hwmon/it87
3165F: drivers/hwmon/it87.c 3165F: drivers/hwmon/it87.c
3166 3166
3167IVTV VIDEO4LINUX DRIVER 3167IVTV VIDEO4LINUX DRIVER
3168M: Andy Walls <awalls@radix.net> 3168M: Andy Walls <awalls@md.metrocast.net>
3169L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) 3169L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
3170L: linux-media@vger.kernel.org 3170L: linux-media@vger.kernel.org
3171T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git 3171T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
@@ -3242,7 +3242,7 @@ L: autofs@linux.kernel.org
3242S: Maintained 3242S: Maintained
3243F: fs/autofs4/ 3243F: fs/autofs4/
3244 3244
3245KERNEL BUILD 3245KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
3246M: Michal Marek <mmarek@suse.cz> 3246M: Michal Marek <mmarek@suse.cz>
3247T: git git://repo.or.cz/linux-kbuild.git for-next 3247T: git git://repo.or.cz/linux-kbuild.git for-next
3248T: git git://repo.or.cz/linux-kbuild.git for-linus 3248T: git git://repo.or.cz/linux-kbuild.git for-linus
@@ -3251,6 +3251,9 @@ S: Maintained
3251F: Documentation/kbuild/ 3251F: Documentation/kbuild/
3252F: Makefile 3252F: Makefile
3253F: scripts/Makefile.* 3253F: scripts/Makefile.*
3254F: scripts/basic/
3255F: scripts/mk*
3256F: scripts/package/
3254 3257
3255KERNEL JANITORS 3258KERNEL JANITORS
3256L: kernel-janitors@vger.kernel.org 3259L: kernel-janitors@vger.kernel.org
@@ -3500,9 +3503,8 @@ F: arch/powerpc/platforms/83xx/
3500 3503
3501LINUX FOR POWERPC PA SEMI PWRFICIENT 3504LINUX FOR POWERPC PA SEMI PWRFICIENT
3502M: Olof Johansson <olof@lixom.net> 3505M: Olof Johansson <olof@lixom.net>
3503W: http://www.pasemi.com/
3504L: linuxppc-dev@ozlabs.org 3506L: linuxppc-dev@ozlabs.org
3505S: Supported 3507S: Maintained
3506F: arch/powerpc/platforms/pasemi/ 3508F: arch/powerpc/platforms/pasemi/
3507F: drivers/*/*pasemi* 3509F: drivers/*/*pasemi*
3508F: drivers/*/*/*pasemi* 3510F: drivers/*/*/*pasemi*
diff --git a/Makefile b/Makefile
index 6e39ec701cbf..654c31aaec64 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
1VERSION = 2 1VERSION = 2
2PATCHLEVEL = 6 2PATCHLEVEL = 6
3SUBLEVEL = 35 3SUBLEVEL = 35
4EXTRAVERSION = -rc1 4EXTRAVERSION = -rc2
5NAME = Sheep on Meth 5NAME = Sheep on Meth
6 6
7# *DOCUMENTATION* 7# *DOCUMENTATION*
@@ -183,11 +183,14 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
183# CROSS_COMPILE can be set on the command line 183# CROSS_COMPILE can be set on the command line
184# make CROSS_COMPILE=ia64-linux- 184# make CROSS_COMPILE=ia64-linux-
185# Alternatively CROSS_COMPILE can be set in the environment. 185# Alternatively CROSS_COMPILE can be set in the environment.
186# A third alternative is to store a setting in .config so that plain
187# "make" in the configured kernel build directory always uses that.
186# Default value for CROSS_COMPILE is not to prefix executables 188# Default value for CROSS_COMPILE is not to prefix executables
187# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile 189# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
188export KBUILD_BUILDHOST := $(SUBARCH) 190export KBUILD_BUILDHOST := $(SUBARCH)
189ARCH ?= $(SUBARCH) 191ARCH ?= $(SUBARCH)
190CROSS_COMPILE ?= 192CROSS_COMPILE ?=
193CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
191 194
192# Architecture as present in compile.h 195# Architecture as present in compile.h
193UTS_MACHINE := $(ARCH) 196UTS_MACHINE := $(ARCH)
@@ -576,9 +579,6 @@ KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
576# disable invalid "can't wrap" optimizations for signed / pointers 579# disable invalid "can't wrap" optimizations for signed / pointers
577KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) 580KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
578 581
579# revert to pre-gcc-4.4 behaviour of .eh_frame
580KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
581
582# conserve stack if available 582# conserve stack if available
583KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) 583KBUILD_CFLAGS += $(call cc-option,-fconserve-stack)
584 584
@@ -882,9 +882,6 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
882PHONY += $(vmlinux-dirs) 882PHONY += $(vmlinux-dirs)
883$(vmlinux-dirs): prepare scripts 883$(vmlinux-dirs): prepare scripts
884 $(Q)$(MAKE) $(build)=$@ 884 $(Q)$(MAKE) $(build)=$@
885ifdef CONFIG_MODULES
886 $(Q)$(MAKE) $(modbuiltin)=$@
887endif
888 885
889# Build the kernel release string 886# Build the kernel release string
890# 887#
@@ -907,14 +904,19 @@ endif
907# $(localver) 904# $(localver)
908# localversion* (files without backups, containing '~') 905# localversion* (files without backups, containing '~')
909# $(CONFIG_LOCALVERSION) (from kernel config setting) 906# $(CONFIG_LOCALVERSION) (from kernel config setting)
910# $(localver-auto) (only if CONFIG_LOCALVERSION_AUTO is set) 907# $(LOCALVERSION) (from make command line, if provided)
911# ./scripts/setlocalversion (SCM tag, if one exists) 908# $(localver-extra)
912# $(LOCALVERSION) (from make command line if provided) 909# $(scm-identifier) (unique SCM tag, if one exists)
910# ./scripts/setlocalversion (only with CONFIG_LOCALVERSION_AUTO)
911# .scmversion (only with CONFIG_LOCALVERSION_AUTO)
912# + (only without CONFIG_LOCALVERSION_AUTO
913# and without LOCALVERSION= and
914# repository is at non-tagged commit)
913# 915#
914# Note how the final $(localver-auto) string is included *only* if the 916# For kernels without CONFIG_LOCALVERSION_AUTO compiled from an SCM that has
915# kernel config option CONFIG_LOCALVERSION_AUTO is selected. Also, at the 917# been revised beyond a tagged commit, `+' is appended to the version string
916# moment, only git is supported but other SCMs can edit the script 918# when not overridden by using "make LOCALVERSION=". This indicates that the
917# scripts/setlocalversion and add the appropriate checks as needed. 919# kernel is not a vanilla release version and has been modified.
918 920
919pattern = ".*/localversion[^~]*" 921pattern = ".*/localversion[^~]*"
920string = $(shell cat /dev/null \ 922string = $(shell cat /dev/null \
@@ -923,26 +925,32 @@ string = $(shell cat /dev/null \
923localver = $(subst $(space),, $(string) \ 925localver = $(subst $(space),, $(string) \
924 $(patsubst "%",%,$(CONFIG_LOCALVERSION))) 926 $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
925 927
926# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called 928# scripts/setlocalversion is called to create a unique identifier if the source
927# and if the SCM is know a tag from the SCM is appended. 929# is managed by a known SCM and the repository has been revised since the last
928# The appended tag is determined by the SCM used. 930# tagged (release) commit. The format of the identifier is determined by the
931# SCM's implementation.
929# 932#
930# .scmversion is used when generating rpm packages so we do not loose 933# .scmversion is used when generating rpm packages so we do not loose
931# the version information from the SCM when we do the build of the kernel 934# the version information from the SCM when we do the build of the kernel
932# from the copied source 935# from the copied source
933ifdef CONFIG_LOCALVERSION_AUTO
934
935ifeq ($(wildcard .scmversion),) 936ifeq ($(wildcard .scmversion),)
936 _localver-auto = $(shell $(CONFIG_SHELL) \ 937 scm-identifier = $(shell $(CONFIG_SHELL) \
937 $(srctree)/scripts/setlocalversion $(srctree)) 938 $(srctree)/scripts/setlocalversion $(srctree))
938else 939else
939 _localver-auto = $(shell cat .scmversion 2> /dev/null) 940 scm-identifier = $(shell cat .scmversion 2> /dev/null)
940endif 941endif
941 942
942 localver-auto = $(LOCALVERSION)$(_localver-auto) 943ifdef CONFIG_LOCALVERSION_AUTO
944 localver-extra = $(scm-identifier)
945else
946 ifneq ($(scm-identifier),)
947 ifeq ($(LOCALVERSION),)
948 localver-extra = +
949 endif
950 endif
943endif 951endif
944 952
945localver-full = $(localver)$(localver-auto) 953localver-full = $(localver)$(LOCALVERSION)$(localver-extra)
946 954
947# Store (new) KERNELRELASE string in include/config/kernel.release 955# Store (new) KERNELRELASE string in include/config/kernel.release
948kernelrelease = $(KERNELVERSION)$(localver-full) 956kernelrelease = $(KERNELVERSION)$(localver-full)
@@ -1089,11 +1097,16 @@ all: modules
1089PHONY += modules 1097PHONY += modules
1090modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) 1098modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
1091 $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order 1099 $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
1092 $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.builtin) > $(objtree)/modules.builtin
1093 @$(kecho) ' Building modules, stage 2.'; 1100 @$(kecho) ' Building modules, stage 2.';
1094 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost 1101 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
1095 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild 1102 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild
1096 1103
1104modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
1105 $(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin
1106
1107%/modules.builtin: include/config/auto.conf
1108 $(Q)$(MAKE) $(modbuiltin)=$*
1109
1097 1110
1098# Target to prepare building external modules 1111# Target to prepare building external modules
1099PHONY += modules_prepare 1112PHONY += modules_prepare
@@ -1104,7 +1117,7 @@ PHONY += modules_install
1104modules_install: _modinst_ _modinst_post 1117modules_install: _modinst_ _modinst_post
1105 1118
1106PHONY += _modinst_ 1119PHONY += _modinst_
1107_modinst_: 1120_modinst_: modules.builtin
1108 @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \ 1121 @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
1109 echo "Warning: you may need to install module-init-tools"; \ 1122 echo "Warning: you may need to install module-init-tools"; \
1110 echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\ 1123 echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\
@@ -1247,7 +1260,9 @@ help:
1247 @echo ' firmware_install- Install all firmware to INSTALL_FW_PATH' 1260 @echo ' firmware_install- Install all firmware to INSTALL_FW_PATH'
1248 @echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)' 1261 @echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
1249 @echo ' dir/ - Build all files in dir and below' 1262 @echo ' dir/ - Build all files in dir and below'
1250 @echo ' dir/file.[ois] - Build specified target only' 1263 @echo ' dir/file.[oisS] - Build specified target only'
1264 @echo ' dir/file.lst - Build specified mixed source/assembly target only'
1265 @echo ' (requires a recent binutils and recent build (System.map))'
1251 @echo ' dir/file.ko - Build module including final link' 1266 @echo ' dir/file.ko - Build module including final link'
1252 @echo ' modules_prepare - Set up for building external modules' 1267 @echo ' modules_prepare - Set up for building external modules'
1253 @echo ' tags/TAGS - Generate tags file for editors' 1268 @echo ' tags/TAGS - Generate tags file for editors'
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c
index 77630df94343..884275629ef7 100644
--- a/arch/cris/arch-v10/drivers/ds1302.c
+++ b/arch/cris/arch-v10/drivers/ds1302.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/miscdevice.h> 20#include <linux/miscdevice.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/smp_lock.h>
22#include <linux/bcd.h> 23#include <linux/bcd.h>
23#include <linux/capability.h> 24#include <linux/capability.h>
24 25
@@ -238,9 +239,7 @@ static unsigned char days_in_mo[] =
238 239
239/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */ 240/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */
240 241
241static int 242static int rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
242rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
243 unsigned long arg)
244{ 243{
245 unsigned long flags; 244 unsigned long flags;
246 245
@@ -354,6 +353,17 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
354 } 353 }
355} 354}
356 355
356static long rtc_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
357{
358 int ret;
359
360 lock_kernel();
361 ret = rtc_ioctl(file, cmd, arg);
362 unlock_kernel();
363
364 return ret;
365}
366
357static void 367static void
358print_rtc_status(void) 368print_rtc_status(void)
359{ 369{
@@ -375,8 +385,8 @@ print_rtc_status(void)
375/* The various file operations we support. */ 385/* The various file operations we support. */
376 386
377static const struct file_operations rtc_fops = { 387static const struct file_operations rtc_fops = {
378 .owner = THIS_MODULE, 388 .owner = THIS_MODULE,
379 .ioctl = rtc_ioctl, 389 .unlocked_ioctl = rtc_unlocked_ioctl,
380}; 390};
381 391
382/* Probe for the chip by writing something to its RAM and try reading it back. */ 392/* Probe for the chip by writing something to its RAM and try reading it back. */
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 1e90c1a9c849..7dcb1f85f42b 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -27,6 +27,7 @@
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/bcd.h> 28#include <linux/bcd.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/smp_lock.h>
30 31
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
32#include <asm/system.h> 33#include <asm/system.h>
@@ -53,7 +54,7 @@ static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
53static const unsigned char days_in_month[] = 54static const unsigned char days_in_month[] =
54 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 55 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
55 56
56int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); 57static long pcf8563_unlocked_ioctl(struct file *, unsigned int, unsigned long);
57 58
58/* Cache VL bit value read at driver init since writing the RTC_SECOND 59/* Cache VL bit value read at driver init since writing the RTC_SECOND
59 * register clears the VL status. 60 * register clears the VL status.
@@ -62,7 +63,7 @@ static int voltage_low;
62 63
63static const struct file_operations pcf8563_fops = { 64static const struct file_operations pcf8563_fops = {
64 .owner = THIS_MODULE, 65 .owner = THIS_MODULE,
65 .ioctl = pcf8563_ioctl, 66 .unlocked_ioctl = pcf8563_unlocked_ioctl,
66}; 67};
67 68
68unsigned char 69unsigned char
@@ -212,8 +213,7 @@ pcf8563_exit(void)
212 * ioctl calls for this driver. Why return -ENOTTY upon error? Because 213 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
213 * POSIX says so! 214 * POSIX says so!
214 */ 215 */
215int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 216static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
216 unsigned long arg)
217{ 217{
218 /* Some sanity checks. */ 218 /* Some sanity checks. */
219 if (_IOC_TYPE(cmd) != RTC_MAGIC) 219 if (_IOC_TYPE(cmd) != RTC_MAGIC)
@@ -339,6 +339,17 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
339 return 0; 339 return 0;
340} 340}
341 341
342static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
343{
344 int ret;
345
346 lock_kernel();
347 return pcf8563_ioctl(filp, cmd, arg);
348 unlock_kernel();
349
350 return ret;
351}
352
342static int __init pcf8563_register(void) 353static int __init pcf8563_register(void)
343{ 354{
344 if (pcf8563_init() < 0) { 355 if (pcf8563_init() < 0) {
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 1a61efc13982..a0c0df8be9c8 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -17,8 +17,8 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h> 18#include <linux/init.h>
19 19
20#define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); 20#define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
21#define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); 21#define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));
22 22
23/* don't use set_int_vector, it bypasses the linux interrupt handlers. it is 23/* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
24 * global just so that the kernel gdb can use it. 24 * global just so that the kernel gdb can use it.
@@ -116,12 +116,12 @@ static unsigned int startup_crisv10_irq(unsigned int irq)
116 116
117static void enable_crisv10_irq(unsigned int irq) 117static void enable_crisv10_irq(unsigned int irq)
118{ 118{
119 unmask_irq(irq); 119 crisv10_unmask_irq(irq);
120} 120}
121 121
122static void disable_crisv10_irq(unsigned int irq) 122static void disable_crisv10_irq(unsigned int irq)
123{ 123{
124 mask_irq(irq); 124 crisv10_mask_irq(irq);
125} 125}
126 126
127static void ack_crisv10_irq(unsigned int irq) 127static void ack_crisv10_irq(unsigned int irq)
diff --git a/arch/cris/arch-v10/lib/dmacopy.c b/arch/cris/arch-v10/lib/dmacopy.c
index e5fb44f505c5..49f5b8ca5b47 100644
--- a/arch/cris/arch-v10/lib/dmacopy.c
+++ b/arch/cris/arch-v10/lib/dmacopy.c
@@ -1,5 +1,4 @@
1/* $Id: dmacopy.c,v 1.1 2001/12/17 13:59:27 bjornw Exp $ 1/*
2 *
3 * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax 2 * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax
4 */ 3 */
5 4
@@ -13,11 +12,11 @@ void *dma_memcpy(void *pdst,
13 unsigned int pn) 12 unsigned int pn)
14{ 13{
15 static etrax_dma_descr indma, outdma; 14 static etrax_dma_descr indma, outdma;
16 15
17 D(printk("dma_memcpy %d bytes... ", pn)); 16 D(printk(KERN_DEBUG "dma_memcpy %d bytes... ", pn));
18 17
19#if 0 18#if 0
20 *R_GEN_CONFIG = genconfig_shadow = 19 *R_GEN_CONFIG = genconfig_shadow =
21 (genconfig_shadow & ~0x3c0000) | 20 (genconfig_shadow & ~0x3c0000) |
22 IO_STATE(R_GEN_CONFIG, dma6, intdma7) | 21 IO_STATE(R_GEN_CONFIG, dma6, intdma7) |
23 IO_STATE(R_GEN_CONFIG, dma7, intdma6); 22 IO_STATE(R_GEN_CONFIG, dma7, intdma6);
@@ -32,11 +31,11 @@ void *dma_memcpy(void *pdst,
32 *R_DMA_CH7_FIRST = &outdma; 31 *R_DMA_CH7_FIRST = &outdma;
33 *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start); 32 *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start);
34 *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start); 33 *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start);
35
36 while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ;
37 34
38 D(printk("done\n")); 35 while (*R_DMA_CH7_CMD == 1)
36 /* wait for completion */;
39 37
38 D(printk(KERN_DEBUG "done\n"));
40} 39}
41 40
42 41
diff --git a/arch/cris/arch-v10/lib/hw_settings.S b/arch/cris/arch-v10/lib/hw_settings.S
index 56905aaa7b6e..c09f19f478a5 100644
--- a/arch/cris/arch-v10/lib/hw_settings.S
+++ b/arch/cris/arch-v10/lib/hw_settings.S
@@ -1,13 +1,11 @@
1/* 1/*
2 * $Id: hw_settings.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
3 *
4 * This table is used by some tools to extract hardware parameters. 2 * This table is used by some tools to extract hardware parameters.
5 * The table should be included in the kernel and the decompressor. 3 * The table should be included in the kernel and the decompressor.
6 * Don't forget to update the tools if you change this table. 4 * Don't forget to update the tools if you change this table.
7 * 5 *
8 * Copyright (C) 2001 Axis Communications AB 6 * Copyright (C) 2001 Axis Communications AB
9 * 7 *
10 * Authors: Mikael Starvik (starvik@axis.com) 8 * Authors: Mikael Starvik (starvik@axis.com)
11 */ 9 */
12 10
13#define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \ 11#define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \
@@ -15,13 +13,13 @@
15#define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \ 13#define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \
16 (CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \ 14 (CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \
17 (CONFIG_ETRAX_DEF_R_PORT_PB_DATA)) 15 (CONFIG_ETRAX_DEF_R_PORT_PB_DATA))
18 16
19 .ascii "HW_PARAM_MAGIC" ; Magic number 17 .ascii "HW_PARAM_MAGIC" ; Magic number
20 .dword 0xc0004000 ; Kernel start address 18 .dword 0xc0004000 ; Kernel start address
21 19
22 ; Debug port 20 ; Debug port
23#ifdef CONFIG_ETRAX_DEBUG_PORT0 21#ifdef CONFIG_ETRAX_DEBUG_PORT0
24 .dword 0 22 .dword 0
25#elif defined(CONFIG_ETRAX_DEBUG_PORT1) 23#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
26 .dword 1 24 .dword 1
27#elif defined(CONFIG_ETRAX_DEBUG_PORT2) 25#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
@@ -30,7 +28,7 @@
30 .dword 3 28 .dword 3
31#else 29#else
32 .dword 4 ; No debug 30 .dword 4 ; No debug
33#endif 31#endif
34 32
35 ; SDRAM or EDO DRAM? 33 ; SDRAM or EDO DRAM?
36#ifdef CONFIG_ETRAX_SDRAM 34#ifdef CONFIG_ETRAX_SDRAM
@@ -39,7 +37,7 @@
39 .dword 0 37 .dword 0
40#endif 38#endif
41 39
42 ; Register values 40 ; Register values
43 .dword R_WAITSTATES 41 .dword R_WAITSTATES
44 .dword CONFIG_ETRAX_DEF_R_WAITSTATES 42 .dword CONFIG_ETRAX_DEF_R_WAITSTATES
45 .dword R_BUS_CONFIG 43 .dword R_BUS_CONFIG
@@ -56,7 +54,7 @@
56 .dword CONFIG_ETRAX_DEF_R_DRAM_TIMING 54 .dword CONFIG_ETRAX_DEF_R_DRAM_TIMING
57#endif 55#endif
58 .dword R_PORT_PA_SET 56 .dword R_PORT_PA_SET
59 .dword PA_SET_VALUE 57 .dword PA_SET_VALUE
60 .dword R_PORT_PB_SET 58 .dword R_PORT_PB_SET
61 .dword PB_SET_VALUE 59 .dword PB_SET_VALUE
62 .dword 0 ; No more register values 60 .dword 0 ; No more register values
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index b9e328e688be..a2dd740c5907 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -360,24 +360,10 @@ config ETRAX_SER4_DSR_BIT
360 string "Ser 4 DSR bit (empty = not used)" 360 string "Ser 4 DSR bit (empty = not used)"
361 depends on ETRAX_SERIAL_PORT4 361 depends on ETRAX_SERIAL_PORT4
362 362
363config ETRAX_SER3_CD_BIT 363config ETRAX_SER4_CD_BIT
364 string "Ser 4 CD bit (empty = not used)" 364 string "Ser 4 CD bit (empty = not used)"
365 depends on ETRAX_SERIAL_PORT4 365 depends on ETRAX_SERIAL_PORT4
366 366
367config ETRAX_RS485
368 bool "RS-485 support"
369 depends on ETRAXFS_SERIAL
370 help
371 Enables support for RS-485 serial communication. For a primer on
372 RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
373
374config ETRAX_RS485_DISABLE_RECEIVER
375 bool "Disable serial receiver"
376 depends on ETRAX_RS485
377 help
378 It is necessary to disable the serial receiver to avoid serial
379 loopback. Not all products are able to do this in software only.
380
381config ETRAX_SYNCHRONOUS_SERIAL 367config ETRAX_SYNCHRONOUS_SERIAL
382 bool "Synchronous serial-port support" 368 bool "Synchronous serial-port support"
383 depends on ETRAX_ARCH_V32 369 depends on ETRAX_ARCH_V32
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
index 506826399ae7..2fd6a740d895 100644
--- a/arch/cris/arch-v32/drivers/i2c.c
+++ b/arch/cris/arch-v32/drivers/i2c.c
@@ -649,10 +649,10 @@ i2c_release(struct inode *inode, struct file *filp)
649/* Main device API. ioctl's to write or read to/from i2c registers. 649/* Main device API. ioctl's to write or read to/from i2c registers.
650 */ 650 */
651 651
652static int 652static long
653i2c_ioctl(struct inode *inode, struct file *file, 653i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
654 unsigned int cmd, unsigned long arg)
655{ 654{
655 int ret;
656 if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { 656 if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
657 return -ENOTTY; 657 return -ENOTTY;
658 } 658 }
@@ -665,9 +665,13 @@ i2c_ioctl(struct inode *inode, struct file *file,
665 I2C_ARGREG(arg), 665 I2C_ARGREG(arg),
666 I2C_ARGVALUE(arg))); 666 I2C_ARGVALUE(arg)));
667 667
668 return i2c_writereg(I2C_ARGSLAVE(arg), 668 lock_kernel();
669 ret = i2c_writereg(I2C_ARGSLAVE(arg),
669 I2C_ARGREG(arg), 670 I2C_ARGREG(arg),
670 I2C_ARGVALUE(arg)); 671 I2C_ARGVALUE(arg));
672 unlock_kernel();
673 return ret;
674
671 case I2C_READREG: 675 case I2C_READREG:
672 { 676 {
673 unsigned char val; 677 unsigned char val;
@@ -675,7 +679,9 @@ i2c_ioctl(struct inode *inode, struct file *file,
675 D(printk("i2cr %d %d ", 679 D(printk("i2cr %d %d ",
676 I2C_ARGSLAVE(arg), 680 I2C_ARGSLAVE(arg),
677 I2C_ARGREG(arg))); 681 I2C_ARGREG(arg)));
682 lock_kernel();
678 val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg)); 683 val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
684 unlock_kernel();
679 D(printk("= %d\n", val)); 685 D(printk("= %d\n", val));
680 return val; 686 return val;
681 } 687 }
@@ -688,10 +694,10 @@ i2c_ioctl(struct inode *inode, struct file *file,
688} 694}
689 695
690static const struct file_operations i2c_fops = { 696static const struct file_operations i2c_fops = {
691 .owner = THIS_MODULE, 697 .owner = THIS_MODULE,
692 .ioctl = i2c_ioctl, 698 .unlocked_ioctl = i2c_ioctl,
693 .open = i2c_open, 699 .open = i2c_open,
694 .release = i2c_release, 700 .release = i2c_release,
695}; 701};
696 702
697static int __init i2c_init(void) 703static int __init i2c_init(void)
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index f4478506e52c..bef6eb53b153 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -24,6 +24,7 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/ioctl.h> 26#include <linux/ioctl.h>
27#include <linux/smp_lock.h>
27#include <linux/delay.h> 28#include <linux/delay.h>
28#include <linux/bcd.h> 29#include <linux/bcd.h>
29#include <linux/mutex.h> 30#include <linux/mutex.h>
@@ -49,7 +50,7 @@ static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
49static const unsigned char days_in_month[] = 50static const unsigned char days_in_month[] =
50 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 51 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
51 52
52int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); 53static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
53 54
54/* Cache VL bit value read at driver init since writing the RTC_SECOND 55/* Cache VL bit value read at driver init since writing the RTC_SECOND
55 * register clears the VL status. 56 * register clears the VL status.
@@ -57,8 +58,8 @@ int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
57static int voltage_low; 58static int voltage_low;
58 59
59static const struct file_operations pcf8563_fops = { 60static const struct file_operations pcf8563_fops = {
60 .owner = THIS_MODULE, 61 .owner = THIS_MODULE,
61 .ioctl = pcf8563_ioctl 62 .unlocked_ioctl = pcf8563_unlocked_ioctl,
62}; 63};
63 64
64unsigned char 65unsigned char
@@ -208,8 +209,7 @@ pcf8563_exit(void)
208 * ioctl calls for this driver. Why return -ENOTTY upon error? Because 209 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
209 * POSIX says so! 210 * POSIX says so!
210 */ 211 */
211int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 212static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
212 unsigned long arg)
213{ 213{
214 /* Some sanity checks. */ 214 /* Some sanity checks. */
215 if (_IOC_TYPE(cmd) != RTC_MAGIC) 215 if (_IOC_TYPE(cmd) != RTC_MAGIC)
@@ -335,6 +335,17 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
335 return 0; 335 return 0;
336} 336}
337 337
338static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
339{
340 int ret;
341
342 lock_kernel();
343 return pcf8563_ioctl(filp, cmd, arg);
344 unlock_kernel();
345
346 return ret;
347}
348
338static int __init pcf8563_register(void) 349static int __init pcf8563_register(void)
339{ 350{
340 if (pcf8563_init() < 0) { 351 if (pcf8563_init() < 0) {
diff --git a/arch/cris/arch-v32/kernel/crisksyms.c b/arch/cris/arch-v32/kernel/crisksyms.c
index 64933e2c0f5b..bde8d1a10cad 100644
--- a/arch/cris/arch-v32/kernel/crisksyms.c
+++ b/arch/cris/arch-v32/kernel/crisksyms.c
@@ -24,5 +24,5 @@ EXPORT_SYMBOL(crisv32_io_get_name);
24EXPORT_SYMBOL(crisv32_io_get); 24EXPORT_SYMBOL(crisv32_io_get);
25 25
26/* Functions masking/unmasking interrupts */ 26/* Functions masking/unmasking interrupts */
27EXPORT_SYMBOL(mask_irq); 27EXPORT_SYMBOL(crisv32_mask_irq);
28EXPORT_SYMBOL(unmask_irq); 28EXPORT_SYMBOL(crisv32_unmask_irq);
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index b6241198fb98..0b1febe44aa3 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -280,8 +280,7 @@ out:
280 return cpu; 280 return cpu;
281} 281}
282 282
283void 283void crisv32_mask_irq(int irq)
284mask_irq(int irq)
285{ 284{
286 int cpu; 285 int cpu;
287 286
@@ -289,8 +288,7 @@ mask_irq(int irq)
289 block_irq(irq, cpu); 288 block_irq(irq, cpu);
290} 289}
291 290
292void 291void crisv32_unmask_irq(int irq)
293unmask_irq(int irq)
294{ 292{
295 unblock_irq(irq, irq_cpu(irq)); 293 unblock_irq(irq, irq_cpu(irq));
296} 294}
@@ -298,23 +296,23 @@ unmask_irq(int irq)
298 296
299static unsigned int startup_crisv32_irq(unsigned int irq) 297static unsigned int startup_crisv32_irq(unsigned int irq)
300{ 298{
301 unmask_irq(irq); 299 crisv32_unmask_irq(irq);
302 return 0; 300 return 0;
303} 301}
304 302
305static void shutdown_crisv32_irq(unsigned int irq) 303static void shutdown_crisv32_irq(unsigned int irq)
306{ 304{
307 mask_irq(irq); 305 crisv32_mask_irq(irq);
308} 306}
309 307
310static void enable_crisv32_irq(unsigned int irq) 308static void enable_crisv32_irq(unsigned int irq)
311{ 309{
312 unmask_irq(irq); 310 crisv32_unmask_irq(irq);
313} 311}
314 312
315static void disable_crisv32_irq(unsigned int irq) 313static void disable_crisv32_irq(unsigned int irq)
316{ 314{
317 mask_irq(irq); 315 crisv32_mask_irq(irq);
318} 316}
319 317
320static void ack_crisv32_irq(unsigned int irq) 318static void ack_crisv32_irq(unsigned int irq)
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 058adddf4e4b..84fed3b4b079 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -168,8 +168,8 @@ void __init smp_callin(void)
168 168
169 /* Enable IRQ and idle */ 169 /* Enable IRQ and idle */
170 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); 170 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask);
171 unmask_irq(IPI_INTR_VECT); 171 crisv32_unmask_irq(IPI_INTR_VECT);
172 unmask_irq(TIMER0_INTR_VECT); 172 crisv32_unmask_irq(TIMER0_INTR_VECT);
173 preempt_disable(); 173 preempt_disable();
174 notify_cpu_starting(cpu); 174 notify_cpu_starting(cpu);
175 local_irq_enable(); 175 local_irq_enable();
diff --git a/arch/cris/include/arch-v10/arch/irq.h b/arch/cris/include/arch-v10/arch/irq.h
index 6248004eca1c..7d345947b3ee 100644
--- a/arch/cris/include/arch-v10/arch/irq.h
+++ b/arch/cris/include/arch-v10/arch/irq.h
@@ -93,15 +93,16 @@ void set_break_vector(int n, irqvectptr addr);
93 "push $r10\n\t" /* push orig_r10 */ \ 93 "push $r10\n\t" /* push orig_r10 */ \
94 "clear.d [$sp=$sp-4]\n\t" /* frametype - this is a normal stackframe */ 94 "clear.d [$sp=$sp-4]\n\t" /* frametype - this is a normal stackframe */
95 95
96 /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq */ 96/* BLOCK_IRQ and UNBLOCK_IRQ do the same as
97 * crisv10_mask_irq and crisv10_unmask_irq */
97 98
98#define BLOCK_IRQ(mask,nr) \ 99#define BLOCK_IRQ(mask,nr) \
99 "move.d " #mask ",$r0\n\t" \ 100 "move.d " #mask ",$r0\n\t" \
100 "move.d $r0,[0xb00000d8]\n\t" 101 "move.d $r0,[0xb00000d8]\n\t"
101 102
102#define UNBLOCK_IRQ(mask) \ 103#define UNBLOCK_IRQ(mask) \
103 "move.d " #mask ",$r0\n\t" \ 104 "move.d " #mask ",$r0\n\t" \
104 "move.d $r0,[0xb00000dc]\n\t" 105 "move.d $r0,[0xb00000dc]\n\t"
105 106
106#define IRQ_NAME2(nr) nr##_interrupt(void) 107#define IRQ_NAME2(nr) nr##_interrupt(void)
107#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) 108#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
diff --git a/arch/cris/include/arch-v32/arch/irq.h b/arch/cris/include/arch-v32/arch/irq.h
index 9e4c9fbdfddf..b31e9984f849 100644
--- a/arch/cris/include/arch-v32/arch/irq.h
+++ b/arch/cris/include/arch-v32/arch/irq.h
@@ -23,8 +23,8 @@ struct etrax_interrupt_vector {
23 23
24extern struct etrax_interrupt_vector *etrax_irv; /* head.S */ 24extern struct etrax_interrupt_vector *etrax_irv; /* head.S */
25 25
26void mask_irq(int irq); 26void crisv32_mask_irq(int irq);
27void unmask_irq(int irq); 27void crisv32_unmask_irq(int irq);
28 28
29void set_exception_vector(int n, irqvectptr addr); 29void set_exception_vector(int n, irqvectptr addr);
30 30
diff --git a/arch/cris/include/asm/param.h b/arch/cris/include/asm/param.h
index 0e47994e40be..484fcf8667c0 100644
--- a/arch/cris/include/asm/param.h
+++ b/arch/cris/include/asm/param.h
@@ -2,22 +2,9 @@
2#define _ASMCRIS_PARAM_H 2#define _ASMCRIS_PARAM_H
3 3
4/* Currently we assume that HZ=100 is good for CRIS. */ 4/* Currently we assume that HZ=100 is good for CRIS. */
5#ifdef __KERNEL__
6# define HZ CONFIG_HZ /* Internal kernel timer frequency */
7# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
8# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
9#endif
10
11#ifndef HZ
12#define HZ 100
13#endif
14 5
15#define EXEC_PAGESIZE 8192 6#define EXEC_PAGESIZE 8192
16 7
17#ifndef NOGROUP 8#include <asm-generic/param.h>
18#define NOGROUP (-1)
19#endif
20
21#define MAXHOSTNAMELEN 64 /* max length of hostname */
22 9
23#endif 10#endif /* _ASMCRIS_PARAM_H */
diff --git a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S
index bd0bdf908d93..cbb6958a3147 100644
--- a/arch/frv/kernel/break.S
+++ b/arch/frv/kernel/break.S
@@ -21,7 +21,7 @@
21# 21#
22# the break handler has its own stack 22# the break handler has its own stack
23# 23#
24 .section .bss.stack 24 .section .bss..stack
25 .globl __break_user_context 25 .globl __break_user_context
26 .balign THREAD_SIZE 26 .balign THREAD_SIZE
27__break_stack: 27__break_stack:
@@ -63,7 +63,7 @@ __break_trace_through_exceptions:
63# entry point for Break Exceptions/Interrupts 63# entry point for Break Exceptions/Interrupts
64# 64#
65############################################################################### 65###############################################################################
66 .section .text.break 66 .section .text..break
67 .balign 4 67 .balign 4
68 .globl __entry_break 68 .globl __entry_break
69__entry_break: 69__entry_break:
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 189397ec012a..63d579bf1c29 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -38,7 +38,7 @@
38 38
39#define nr_syscalls ((syscall_table_size)/4) 39#define nr_syscalls ((syscall_table_size)/4)
40 40
41 .section .text.entry 41 .section .text..entry
42 .balign 4 42 .balign 4
43 43
44.macro LEDS val 44.macro LEDS val
diff --git a/arch/frv/kernel/head.S b/arch/frv/kernel/head.S
index b825ef3f2d54..e9a8cc63ac94 100644
--- a/arch/frv/kernel/head.S
+++ b/arch/frv/kernel/head.S
@@ -542,7 +542,7 @@ __head_end:
542 .size _boot, .-_boot 542 .size _boot, .-_boot
543 543
544 # provide a point for GDB to place a break 544 # provide a point for GDB to place a break
545 .section .text.start,"ax" 545 .section .text..start,"ax"
546 .globl _start 546 .globl _start
547 .balign 4 547 .balign 4
548_start: 548_start:
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index cbe811fccfcc..8b973f3cc90e 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -57,10 +57,10 @@ SECTIONS
57 _text = .; 57 _text = .;
58 _stext = .; 58 _stext = .;
59 .text : { 59 .text : {
60 *(.text.start) 60 *(.text..start)
61 *(.text.entry) 61 *(.text..entry)
62 *(.text.break) 62 *(.text..break)
63 *(.text.tlbmiss) 63 *(.text..tlbmiss)
64 TEXT_TEXT 64 TEXT_TEXT
65 SCHED_TEXT 65 SCHED_TEXT
66 LOCK_TEXT 66 LOCK_TEXT
@@ -114,7 +114,7 @@ SECTIONS
114 114
115 .sbss : { *(.sbss .sbss.*) } 115 .sbss : { *(.sbss .sbss.*) }
116 .bss : { *(.bss .bss.*) } 116 .bss : { *(.bss .bss.*) }
117 .bss.stack : { *(.bss) } 117 .bss..stack : { *(.bss) }
118 118
119 __bss_stop = .; 119 __bss_stop = .;
120 _end = . ; 120 _end = . ;
diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c
index 30f5d100a81c..a325d57a83d5 100644
--- a/arch/frv/mm/fault.c
+++ b/arch/frv/mm/fault.c
@@ -257,10 +257,10 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
257 */ 257 */
258 out_of_memory: 258 out_of_memory:
259 up_read(&mm->mmap_sem); 259 up_read(&mm->mmap_sem);
260 printk("VM: killing process %s\n", current->comm); 260 if (!user_mode(__frame))
261 if (user_mode(__frame)) 261 goto no_context;
262 do_group_exit(SIGKILL); 262 pagefault_out_of_memory();
263 goto no_context; 263 return;
264 264
265 do_sigbus: 265 do_sigbus:
266 up_read(&mm->mmap_sem); 266 up_read(&mm->mmap_sem);
diff --git a/arch/frv/mm/tlb-miss.S b/arch/frv/mm/tlb-miss.S
index 7f392bc651a3..f3ac019bb18b 100644
--- a/arch/frv/mm/tlb-miss.S
+++ b/arch/frv/mm/tlb-miss.S
@@ -15,7 +15,7 @@
15#include <asm/pgtable.h> 15#include <asm/pgtable.h>
16#include <asm/spr-regs.h> 16#include <asm/spr-regs.h>
17 17
18 .section .text.tlbmiss 18 .section .text..tlbmiss
19 .balign 4 19 .balign 4
20 20
21 .globl __entry_insn_mmu_miss 21 .globl __entry_insn_mmu_miss
diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S
index 985a81a2435a..10e9a2d1cc6c 100644
--- a/arch/h8300/boot/compressed/head.S
+++ b/arch/h8300/boot/compressed/head.S
@@ -9,7 +9,7 @@
9 9
10#define SRAM_START 0xff4000 10#define SRAM_START 0xff4000
11 11
12 .section .text.startup 12 .section .text..startup
13 .global startup 13 .global startup
14startup: 14startup:
15 mov.l #SRAM_START+0x8000, sp 15 mov.l #SRAM_START+0x8000, sp
diff --git a/arch/h8300/boot/compressed/vmlinux.lds b/arch/h8300/boot/compressed/vmlinux.lds
index 65e2a0d1ae39..a0a3a0ed54ef 100644
--- a/arch/h8300/boot/compressed/vmlinux.lds
+++ b/arch/h8300/boot/compressed/vmlinux.lds
@@ -4,7 +4,7 @@ SECTIONS
4 { 4 {
5 __stext = . ; 5 __stext = . ;
6 __text = .; 6 __text = .;
7 *(.text.startup) 7 *(.text..startup)
8 *(.text) 8 *(.text)
9 __etext = . ; 9 __etext = . ;
10 } 10 }
diff --git a/arch/ia64/include/asm/asmmacro.h b/arch/ia64/include/asm/asmmacro.h
index c1642fd64029..3ab6d75aa3db 100644
--- a/arch/ia64/include/asm/asmmacro.h
+++ b/arch/ia64/include/asm/asmmacro.h
@@ -70,12 +70,12 @@ name:
70 * path (ivt.S - TLB miss processing) or in places where it might not be 70 * path (ivt.S - TLB miss processing) or in places where it might not be
71 * safe to use a "tpa" instruction (mca_asm.S - error recovery). 71 * safe to use a "tpa" instruction (mca_asm.S - error recovery).
72 */ 72 */
73 .section ".data.patch.vtop", "a" // declare section & section attributes 73 .section ".data..patch.vtop", "a" // declare section & section attributes
74 .previous 74 .previous
75 75
76#define LOAD_PHYSICAL(pr, reg, obj) \ 76#define LOAD_PHYSICAL(pr, reg, obj) \
77[1:](pr)movl reg = obj; \ 77[1:](pr)movl reg = obj; \
78 .xdata4 ".data.patch.vtop", 1b-. 78 .xdata4 ".data..patch.vtop", 1b-.
79 79
80/* 80/*
81 * For now, we always put in the McKinley E9 workaround. On CPUs that don't need it, 81 * For now, we always put in the McKinley E9 workaround. On CPUs that don't need it,
@@ -84,11 +84,11 @@ name:
84#define DO_MCKINLEY_E9_WORKAROUND 84#define DO_MCKINLEY_E9_WORKAROUND
85 85
86#ifdef DO_MCKINLEY_E9_WORKAROUND 86#ifdef DO_MCKINLEY_E9_WORKAROUND
87 .section ".data.patch.mckinley_e9", "a" 87 .section ".data..patch.mckinley_e9", "a"
88 .previous 88 .previous
89/* workaround for Itanium 2 Errata 9: */ 89/* workaround for Itanium 2 Errata 9: */
90# define FSYS_RETURN \ 90# define FSYS_RETURN \
91 .xdata4 ".data.patch.mckinley_e9", 1f-.; \ 91 .xdata4 ".data..patch.mckinley_e9", 1f-.; \
921:{ .mib; \ 921:{ .mib; \
93 nop.m 0; \ 93 nop.m 0; \
94 mov r16=ar.pfs; \ 94 mov r16=ar.pfs; \
@@ -107,11 +107,11 @@ name:
107 * If physical stack register size is different from DEF_NUM_STACK_REG, 107 * If physical stack register size is different from DEF_NUM_STACK_REG,
108 * dynamically patch the kernel for correct size. 108 * dynamically patch the kernel for correct size.
109 */ 109 */
110 .section ".data.patch.phys_stack_reg", "a" 110 .section ".data..patch.phys_stack_reg", "a"
111 .previous 111 .previous
112#define LOAD_PHYS_STACK_REG_SIZE(reg) \ 112#define LOAD_PHYS_STACK_REG_SIZE(reg) \
113[1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \ 113[1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \
114 .xdata4 ".data.patch.phys_stack_reg", 1b-. 114 .xdata4 ".data..patch.phys_stack_reg", 1b-.
115 115
116/* 116/*
117 * Up until early 2004, use of .align within a function caused bad unwind info. 117 * Up until early 2004, use of .align within a function caused bad unwind info.
diff --git a/arch/ia64/include/asm/cache.h b/arch/ia64/include/asm/cache.h
index e7482bd628ff..988254a7d349 100644
--- a/arch/ia64/include/asm/cache.h
+++ b/arch/ia64/include/asm/cache.h
@@ -24,6 +24,6 @@
24# define SMP_CACHE_BYTES (1 << 3) 24# define SMP_CACHE_BYTES (1 << 3)
25#endif 25#endif
26 26
27#define __read_mostly __attribute__((__section__(".data.read_mostly"))) 27#define __read_mostly __attribute__((__section__(".data..read_mostly")))
28 28
29#endif /* _ASM_IA64_CACHE_H */ 29#endif /* _ASM_IA64_CACHE_H */
diff --git a/arch/ia64/include/asm/percpu.h b/arch/ia64/include/asm/percpu.h
index 1bd408265694..14aa1c58912b 100644
--- a/arch/ia64/include/asm/percpu.h
+++ b/arch/ia64/include/asm/percpu.h
@@ -31,7 +31,7 @@ extern void *per_cpu_init(void);
31 31
32#endif /* SMP */ 32#endif /* SMP */
33 33
34#define PER_CPU_BASE_SECTION ".data.percpu" 34#define PER_CPU_BASE_SECTION ".data..percpu"
35 35
36/* 36/*
37 * Be extremely careful when taking the address of this variable! Due to virtual 37 * Be extremely careful when taking the address of this variable! Due to virtual
diff --git a/arch/ia64/kernel/Makefile.gate b/arch/ia64/kernel/Makefile.gate
index ab9b03a9adcc..ceeffc509764 100644
--- a/arch/ia64/kernel/Makefile.gate
+++ b/arch/ia64/kernel/Makefile.gate
@@ -21,7 +21,7 @@ GATECFLAGS_gate-syms.o = -r
21$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE 21$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
22 $(call if_changed,gate) 22 $(call if_changed,gate)
23 23
24# gate-data.o contains the gate DSO image as data in section .data.gate. 24# gate-data.o contains the gate DSO image as data in section .data..gate.
25# We must build gate.so before we can assemble it. 25# We must build gate.so before we can assemble it.
26# Note: kbuild does not track this dependency due to usage of .incbin 26# Note: kbuild does not track this dependency due to usage of .incbin
27$(obj)/gate-data.o: $(obj)/gate.so 27$(obj)/gate-data.o: $(obj)/gate.so
diff --git a/arch/ia64/kernel/gate-data.S b/arch/ia64/kernel/gate-data.S
index 258c0a3238fb..b3ef1c72e132 100644
--- a/arch/ia64/kernel/gate-data.S
+++ b/arch/ia64/kernel/gate-data.S
@@ -1,3 +1,3 @@
1 .section .data.gate, "aw" 1 .section .data..gate, "aw"
2 2
3 .incbin "arch/ia64/kernel/gate.so" 3 .incbin "arch/ia64/kernel/gate.so"
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
index cf5e0a105e16..245d3e1ec7e1 100644
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -21,18 +21,18 @@
21 * to targets outside the shared object) and to avoid multi-phase kernel builds, we 21 * to targets outside the shared object) and to avoid multi-phase kernel builds, we
22 * simply create minimalistic "patch lists" in special ELF sections. 22 * simply create minimalistic "patch lists" in special ELF sections.
23 */ 23 */
24 .section ".data.patch.fsyscall_table", "a" 24 .section ".data..patch.fsyscall_table", "a"
25 .previous 25 .previous
26#define LOAD_FSYSCALL_TABLE(reg) \ 26#define LOAD_FSYSCALL_TABLE(reg) \
27[1:] movl reg=0; \ 27[1:] movl reg=0; \
28 .xdata4 ".data.patch.fsyscall_table", 1b-. 28 .xdata4 ".data..patch.fsyscall_table", 1b-.
29 29
30 .section ".data.patch.brl_fsys_bubble_down", "a" 30 .section ".data..patch.brl_fsys_bubble_down", "a"
31 .previous 31 .previous
32#define BRL_COND_FSYS_BUBBLE_DOWN(pr) \ 32#define BRL_COND_FSYS_BUBBLE_DOWN(pr) \
33[1:](pr)brl.cond.sptk 0; \ 33[1:](pr)brl.cond.sptk 0; \
34 ;; \ 34 ;; \
35 .xdata4 ".data.patch.brl_fsys_bubble_down", 1b-. 35 .xdata4 ".data..patch.brl_fsys_bubble_down", 1b-.
36 36
37GLOBAL_ENTRY(__kernel_syscall_via_break) 37GLOBAL_ENTRY(__kernel_syscall_via_break)
38 .prologue 38 .prologue
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S
index 88c64ed47c36..d32b0855110a 100644
--- a/arch/ia64/kernel/gate.lds.S
+++ b/arch/ia64/kernel/gate.lds.S
@@ -33,21 +33,21 @@ SECTIONS
33 */ 33 */
34 . = GATE_ADDR + 0x600; 34 . = GATE_ADDR + 0x600;
35 35
36 .data.patch : { 36 .data..patch : {
37 __paravirt_start_gate_mckinley_e9_patchlist = .; 37 __paravirt_start_gate_mckinley_e9_patchlist = .;
38 *(.data.patch.mckinley_e9) 38 *(.data..patch.mckinley_e9)
39 __paravirt_end_gate_mckinley_e9_patchlist = .; 39 __paravirt_end_gate_mckinley_e9_patchlist = .;
40 40
41 __paravirt_start_gate_vtop_patchlist = .; 41 __paravirt_start_gate_vtop_patchlist = .;
42 *(.data.patch.vtop) 42 *(.data..patch.vtop)
43 __paravirt_end_gate_vtop_patchlist = .; 43 __paravirt_end_gate_vtop_patchlist = .;
44 44
45 __paravirt_start_gate_fsyscall_patchlist = .; 45 __paravirt_start_gate_fsyscall_patchlist = .;
46 *(.data.patch.fsyscall_table) 46 *(.data..patch.fsyscall_table)
47 __paravirt_end_gate_fsyscall_patchlist = .; 47 __paravirt_end_gate_fsyscall_patchlist = .;
48 48
49 __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .; 49 __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .;
50 *(.data.patch.brl_fsys_bubble_down) 50 *(.data..patch.brl_fsys_bubble_down)
51 __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .; 51 __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .;
52 } :readable 52 } :readable
53 53
diff --git a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c
index e253ab8fcbc8..f9efe9739d3f 100644
--- a/arch/ia64/kernel/init_task.c
+++ b/arch/ia64/kernel/init_task.c
@@ -23,7 +23,7 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
23 * Initial task structure. 23 * Initial task structure.
24 * 24 *
25 * We need to make sure that this is properly aligned due to the way process stacks are 25 * We need to make sure that this is properly aligned due to the way process stacks are
26 * handled. This is done by having a special ".data.init_task" section... 26 * handled. This is done by having a special ".data..init_task" section...
27 */ 27 */
28#define init_thread_info init_task_mem.s.thread_info 28#define init_thread_info init_task_mem.s.thread_info
29 29
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index 179fd122e837..d93e396bf599 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -82,7 +82,7 @@
82 mov r19=n;; /* prepare to save predicates */ \ 82 mov r19=n;; /* prepare to save predicates */ \
83 br.sptk.many dispatch_to_fault_handler 83 br.sptk.many dispatch_to_fault_handler
84 84
85 .section .text.ivt,"ax" 85 .section .text..ivt,"ax"
86 86
87 .align 32768 // align on 32KB boundary 87 .align 32768 // align on 32KB boundary
88 .global ia64_ivt 88 .global ia64_ivt
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
index 292e214a3b84..d56753a11636 100644
--- a/arch/ia64/kernel/minstate.h
+++ b/arch/ia64/kernel/minstate.h
@@ -16,7 +16,7 @@
16#define ACCOUNT_SYS_ENTER 16#define ACCOUNT_SYS_ENTER
17#endif 17#endif
18 18
19.section ".data.patch.rse", "a" 19.section ".data..patch.rse", "a"
20.previous 20.previous
21 21
22/* 22/*
@@ -215,7 +215,7 @@
215(pUStk) extr.u r17=r18,3,6; \ 215(pUStk) extr.u r17=r18,3,6; \
216(pUStk) sub r16=r18,r22; \ 216(pUStk) sub r16=r18,r22; \
217[1:](pKStk) br.cond.sptk.many 1f; \ 217[1:](pKStk) br.cond.sptk.many 1f; \
218 .xdata4 ".data.patch.rse",1b-. \ 218 .xdata4 ".data..patch.rse",1b-. \
219 ;; \ 219 ;; \
220 cmp.ge p6,p7 = 33,r17; \ 220 cmp.ge p6,p7 = 33,r17; \
221 ;; \ 221 ;; \
diff --git a/arch/ia64/kernel/paravirtentry.S b/arch/ia64/kernel/paravirtentry.S
index 6158560d7f17..92d880c4d3d1 100644
--- a/arch/ia64/kernel/paravirtentry.S
+++ b/arch/ia64/kernel/paravirtentry.S
@@ -28,7 +28,7 @@
28#include "entry.h" 28#include "entry.h"
29 29
30#define DATA8(sym, init_value) \ 30#define DATA8(sym, init_value) \
31 .pushsection .data.read_mostly ; \ 31 .pushsection .data..read_mostly ; \
32 .align 8 ; \ 32 .align 8 ; \
33 .global sym ; \ 33 .global sym ; \
34 sym: ; \ 34 sym: ; \
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 1295ba327f6f..e07218a2577f 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -8,7 +8,7 @@
8 8
9#define IVT_TEXT \ 9#define IVT_TEXT \
10 VMLINUX_SYMBOL(__start_ivt_text) = .; \ 10 VMLINUX_SYMBOL(__start_ivt_text) = .; \
11 *(.text.ivt) \ 11 *(.text..ivt) \
12 VMLINUX_SYMBOL(__end_ivt_text) = .; 12 VMLINUX_SYMBOL(__end_ivt_text) = .;
13 13
14OUTPUT_FORMAT("elf64-ia64-little") 14OUTPUT_FORMAT("elf64-ia64-little")
@@ -54,8 +54,8 @@ SECTIONS
54 .text2 : AT(ADDR(.text2) - LOAD_OFFSET) 54 .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
55 { *(.text2) } 55 { *(.text2) }
56#ifdef CONFIG_SMP 56#ifdef CONFIG_SMP
57 .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) 57 .text..lock : AT(ADDR(.text..lock) - LOAD_OFFSET)
58 { *(.text.lock) } 58 { *(.text..lock) }
59#endif 59#endif
60 _etext = .; 60 _etext = .;
61 61
@@ -75,10 +75,10 @@ SECTIONS
75 __stop___mca_table = .; 75 __stop___mca_table = .;
76 } 76 }
77 77
78 .data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET) 78 .data..patch.phys_stack_reg : AT(ADDR(.data..patch.phys_stack_reg) - LOAD_OFFSET)
79 { 79 {
80 __start___phys_stack_reg_patchlist = .; 80 __start___phys_stack_reg_patchlist = .;
81 *(.data.patch.phys_stack_reg) 81 *(.data..patch.phys_stack_reg)
82 __end___phys_stack_reg_patchlist = .; 82 __end___phys_stack_reg_patchlist = .;
83 } 83 }
84 84
@@ -110,24 +110,24 @@ SECTIONS
110 INIT_TEXT_SECTION(PAGE_SIZE) 110 INIT_TEXT_SECTION(PAGE_SIZE)
111 INIT_DATA_SECTION(16) 111 INIT_DATA_SECTION(16)
112 112
113 .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) 113 .data..patch.vtop : AT(ADDR(.data..patch.vtop) - LOAD_OFFSET)
114 { 114 {
115 __start___vtop_patchlist = .; 115 __start___vtop_patchlist = .;
116 *(.data.patch.vtop) 116 *(.data..patch.vtop)
117 __end___vtop_patchlist = .; 117 __end___vtop_patchlist = .;
118 } 118 }
119 119
120 .data.patch.rse : AT(ADDR(.data.patch.rse) - LOAD_OFFSET) 120 .data..patch.rse : AT(ADDR(.data..patch.rse) - LOAD_OFFSET)
121 { 121 {
122 __start___rse_patchlist = .; 122 __start___rse_patchlist = .;
123 *(.data.patch.rse) 123 *(.data..patch.rse)
124 __end___rse_patchlist = .; 124 __end___rse_patchlist = .;
125 } 125 }
126 126
127 .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET) 127 .data..patch.mckinley_e9 : AT(ADDR(.data..patch.mckinley_e9) - LOAD_OFFSET)
128 { 128 {
129 __start___mckinley_e9_bundles = .; 129 __start___mckinley_e9_bundles = .;
130 *(.data.patch.mckinley_e9) 130 *(.data..patch.mckinley_e9)
131 __end___mckinley_e9_bundles = .; 131 __end___mckinley_e9_bundles = .;
132 } 132 }
133 133
@@ -175,17 +175,17 @@ SECTIONS
175 . = ALIGN(PAGE_SIZE); 175 . = ALIGN(PAGE_SIZE);
176 __init_end = .; 176 __init_end = .;
177 177
178 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) 178 .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET)
179 { 179 {
180 PAGE_ALIGNED_DATA(PAGE_SIZE) 180 PAGE_ALIGNED_DATA(PAGE_SIZE)
181 . = ALIGN(PAGE_SIZE); 181 . = ALIGN(PAGE_SIZE);
182 __start_gate_section = .; 182 __start_gate_section = .;
183 *(.data.gate) 183 *(.data..gate)
184 __stop_gate_section = .; 184 __stop_gate_section = .;
185#ifdef CONFIG_XEN 185#ifdef CONFIG_XEN
186 . = ALIGN(PAGE_SIZE); 186 . = ALIGN(PAGE_SIZE);
187 __xen_start_gate_section = .; 187 __xen_start_gate_section = .;
188 *(.data.gate.xen) 188 *(.data..gate.xen)
189 __xen_stop_gate_section = .; 189 __xen_stop_gate_section = .;
190#endif 190#endif
191 } 191 }
diff --git a/arch/ia64/kvm/vmm_ivt.S b/arch/ia64/kvm/vmm_ivt.S
index 40920c630649..24018484c6e9 100644
--- a/arch/ia64/kvm/vmm_ivt.S
+++ b/arch/ia64/kvm/vmm_ivt.S
@@ -104,7 +104,7 @@ GLOBAL_ENTRY(kvm_vmm_panic)
104 br.call.sptk.many b6=vmm_panic_handler; 104 br.call.sptk.many b6=vmm_panic_handler;
105END(kvm_vmm_panic) 105END(kvm_vmm_panic)
106 106
107 .section .text.ivt,"ax" 107 .section .text..ivt,"ax"
108 108
109 .align 32768 // align on 32KB boundary 109 .align 32768 // align on 32KB boundary
110 .global kvm_ia64_ivt 110 .global kvm_ia64_ivt
diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py
index c27849889e19..2bfd941ff7c7 100644
--- a/arch/ia64/scripts/unwcheck.py
+++ b/arch/ia64/scripts/unwcheck.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python 1#!/usr/bin/python
2# 2#
3# Usage: unwcheck.py FILE 3# Usage: unwcheck.py FILE
4# 4#
diff --git a/arch/ia64/xen/gate-data.S b/arch/ia64/xen/gate-data.S
index 7d4830afc91d..6f95b6b32a4e 100644
--- a/arch/ia64/xen/gate-data.S
+++ b/arch/ia64/xen/gate-data.S
@@ -1,3 +1,3 @@
1 .section .data.gate.xen, "aw" 1 .section .data..gate.xen, "aw"
2 2
3 .incbin "arch/ia64/xen/gate.so" 3 .incbin "arch/ia64/xen/gate.so"
diff --git a/arch/ia64/xen/xensetup.S b/arch/ia64/xen/xensetup.S
index aff8346ea193..b820ed02ab9f 100644
--- a/arch/ia64/xen/xensetup.S
+++ b/arch/ia64/xen/xensetup.S
@@ -14,7 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <xen/interface/elfnote.h> 15#include <xen/interface/elfnote.h>
16 16
17 .section .data.read_mostly 17 .section .data..read_mostly
18 .align 8 18 .align 8
19 .global xen_domain_type 19 .global xen_domain_type
20xen_domain_type: 20xen_domain_type:
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index 28ee389e5f5a..b8ec002aef8e 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -188,7 +188,6 @@ good_area:
188 if ((error_code & ACE_INSTRUCTION) && !(vma->vm_flags & VM_EXEC)) 188 if ((error_code & ACE_INSTRUCTION) && !(vma->vm_flags & VM_EXEC))
189 goto bad_area; 189 goto bad_area;
190 190
191survive:
192 /* 191 /*
193 * If for any reason at all we couldn't handle the fault, 192 * If for any reason at all we couldn't handle the fault,
194 * make sure we exit gracefully rather than endlessly redo 193 * make sure we exit gracefully rather than endlessly redo
@@ -271,15 +270,10 @@ no_context:
271 */ 270 */
272out_of_memory: 271out_of_memory:
273 up_read(&mm->mmap_sem); 272 up_read(&mm->mmap_sem);
274 if (is_global_init(tsk)) { 273 if (!(error_code & ACE_USERMODE))
275 yield(); 274 goto no_context;
276 down_read(&mm->mmap_sem); 275 pagefault_out_of_memory();
277 goto survive; 276 return;
278 }
279 printk("VM: killing process %s\n", tsk->comm);
280 if (error_code & ACE_USERMODE)
281 do_group_exit(SIGKILL);
282 goto no_context;
283 277
284do_sigbus: 278do_sigbus:
285 up_read(&mm->mmap_sem); 279 up_read(&mm->mmap_sem);
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 9f1784f586b9..a91b2713451d 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -57,7 +57,7 @@ SECTIONS {
57 .romvec : { 57 .romvec : {
58 __rom_start = . ; 58 __rom_start = . ;
59 _romvec = .; 59 _romvec = .;
60 *(.data.initvect) 60 *(.data..initvect)
61 } > romvec 61 } > romvec
62#endif 62#endif
63 63
@@ -68,7 +68,7 @@ SECTIONS {
68 TEXT_TEXT 68 TEXT_TEXT
69 SCHED_TEXT 69 SCHED_TEXT
70 LOCK_TEXT 70 LOCK_TEXT
71 *(.text.lock) 71 *(.text..lock)
72 72
73 . = ALIGN(16); /* Exception table */ 73 . = ALIGN(16); /* Exception table */
74 __start___ex_table = .; 74 __start___ex_table = .;
diff --git a/arch/m68knommu/platform/68360/head-ram.S b/arch/m68knommu/platform/68360/head-ram.S
index 2ef06242398b..8eb94fb6b971 100644
--- a/arch/m68knommu/platform/68360/head-ram.S
+++ b/arch/m68knommu/platform/68360/head-ram.S
@@ -280,7 +280,7 @@ _dprbase:
280 * and then overwritten as needed. 280 * and then overwritten as needed.
281 */ 281 */
282 282
283.section ".data.initvect","awx" 283.section ".data..initvect","awx"
284 .long RAMEND /* Reset: Initial Stack Pointer - 0. */ 284 .long RAMEND /* Reset: Initial Stack Pointer - 0. */
285 .long _start /* Reset: Initial Program Counter - 1. */ 285 .long _start /* Reset: Initial Program Counter - 1. */
286 .long buserr /* Bus Error - 2. */ 286 .long buserr /* Bus Error - 2. */
diff --git a/arch/m68knommu/platform/68360/head-rom.S b/arch/m68knommu/platform/68360/head-rom.S
index 62ecf4144b3b..97510e55b802 100644
--- a/arch/m68knommu/platform/68360/head-rom.S
+++ b/arch/m68knommu/platform/68360/head-rom.S
@@ -291,7 +291,7 @@ _dprbase:
291 * and then overwritten as needed. 291 * and then overwritten as needed.
292 */ 292 */
293 293
294.section ".data.initvect","awx" 294.section ".data..initvect","awx"
295 .long RAMEND /* Reset: Initial Stack Pointer - 0. */ 295 .long RAMEND /* Reset: Initial Stack Pointer - 0. */
296 .long _start /* Reset: Initial Program Counter - 1. */ 296 .long _start /* Reset: Initial Program Counter - 1. */
297 .long buserr /* Bus Error - 2. */ 297 .long buserr /* Bus Error - 2. */
diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S
index efb95f2609c2..e0ecda92c40a 100644
--- a/arch/mips/lasat/image/head.S
+++ b/arch/mips/lasat/image/head.S
@@ -1,7 +1,7 @@
1#include <asm/lasat/head.h> 1#include <asm/lasat/head.h>
2 2
3 .text 3 .text
4 .section .text.start, "ax" 4 .section .text..start, "ax"
5 .set noreorder 5 .set noreorder
6 .set mips3 6 .set mips3
7 7
diff --git a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal
index 988f8ad189cb..0864c963e188 100644
--- a/arch/mips/lasat/image/romscript.normal
+++ b/arch/mips/lasat/image/romscript.normal
@@ -4,7 +4,7 @@ SECTIONS
4{ 4{
5 .text : 5 .text :
6 { 6 {
7 *(.text.start) 7 *(.text..start)
8 } 8 }
9 9
10 /* Data in ROM */ 10 /* Data in ROM */
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c
index 53bb17d0f068..81f153fa51b4 100644
--- a/arch/mn10300/mm/fault.c
+++ b/arch/mn10300/mm/fault.c
@@ -338,11 +338,10 @@ no_context:
338 */ 338 */
339out_of_memory: 339out_of_memory:
340 up_read(&mm->mmap_sem); 340 up_read(&mm->mmap_sem);
341 monitor_signal(regs); 341 if ((fault_code & MMUFCR_xFC_ACCESS) != MMUFCR_xFC_ACCESS_USR)
342 printk(KERN_ALERT "VM: killing process %s\n", tsk->comm); 342 goto no_context;
343 if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR) 343 pagefault_out_of_memory();
344 do_exit(SIGKILL); 344 return;
345 goto no_context;
346 345
347do_sigbus: 346do_sigbus:
348 up_read(&mm->mmap_sem); 347 up_read(&mm->mmap_sem);
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
index 32c2cca74345..45effe6978fa 100644
--- a/arch/parisc/include/asm/cache.h
+++ b/arch/parisc/include/asm/cache.h
@@ -28,7 +28,7 @@
28 28
29#define SMP_CACHE_BYTES L1_CACHE_BYTES 29#define SMP_CACHE_BYTES L1_CACHE_BYTES
30 30
31#define __read_mostly __attribute__((__section__(".data.read_mostly"))) 31#define __read_mostly __attribute__((__section__(".data..read_mostly")))
32 32
33void parisc_cache_init(void); /* initializes cache-flushing */ 33void parisc_cache_init(void); /* initializes cache-flushing */
34void disable_sr_hashing_asm(int); /* low level support for above */ 34void disable_sr_hashing_asm(int); /* low level support for above */
diff --git a/arch/parisc/include/asm/system.h b/arch/parisc/include/asm/system.h
index 4653c77bf9d1..2ab4af58ecb9 100644
--- a/arch/parisc/include/asm/system.h
+++ b/arch/parisc/include/asm/system.h
@@ -174,7 +174,7 @@ static inline void set_eiem(unsigned long val)
174}) 174})
175 175
176#ifdef CONFIG_SMP 176#ifdef CONFIG_SMP
177# define __lock_aligned __attribute__((__section__(".data.lock_aligned"))) 177# define __lock_aligned __attribute__((__section__(".data..lock_aligned")))
178#endif 178#endif
179 179
180#define arch_align_stack(x) (x) 180#define arch_align_stack(x) (x)
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index 0e3d9f9b9e33..4dbdf0ed6fa0 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -345,7 +345,7 @@ smp_slave_stext:
345ENDPROC(stext) 345ENDPROC(stext)
346 346
347#ifndef CONFIG_64BIT 347#ifndef CONFIG_64BIT
348 .section .data.read_mostly 348 .section .data..read_mostly
349 349
350 .align 4 350 .align 4
351 .export $global$,data 351 .export $global$,data
diff --git a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c
index d020eae6525c..4a91e433416f 100644
--- a/arch/parisc/kernel/init_task.c
+++ b/arch/parisc/kernel/init_task.c
@@ -53,11 +53,11 @@ union thread_union init_thread_union __init_task_data
53 * guarantee that global objects will be laid out in memory in the same order 53 * guarantee that global objects will be laid out in memory in the same order
54 * as the order of declaration, so put these in different sections and use 54 * as the order of declaration, so put these in different sections and use
55 * the linker script to order them. */ 55 * the linker script to order them. */
56pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data.vm0.pmd"), aligned(PAGE_SIZE))); 56pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data..vm0.pmd"), aligned(PAGE_SIZE)));
57#endif 57#endif
58 58
59pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data.vm0.pgd"), aligned(PAGE_SIZE))); 59pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE)));
60pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data.vm0.pte"), aligned(PAGE_SIZE))); 60pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE)));
61 61
62/* 62/*
63 * Initial task structure. 63 * Initial task structure.
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 9dab4a4e09f7..d64a6bbec2aa 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -94,8 +94,8 @@ SECTIONS
94 94
95 /* PA-RISC locks requires 16-byte alignment */ 95 /* PA-RISC locks requires 16-byte alignment */
96 . = ALIGN(16); 96 . = ALIGN(16);
97 .data.lock_aligned : { 97 .data..lock_aligned : {
98 *(.data.lock_aligned) 98 *(.data..lock_aligned)
99 } 99 }
100 100
101 /* End of data section */ 101 /* End of data section */
@@ -105,10 +105,10 @@ SECTIONS
105 __bss_start = .; 105 __bss_start = .;
106 /* page table entries need to be PAGE_SIZE aligned */ 106 /* page table entries need to be PAGE_SIZE aligned */
107 . = ALIGN(PAGE_SIZE); 107 . = ALIGN(PAGE_SIZE);
108 .data.vmpages : { 108 .data..vmpages : {
109 *(.data.vm0.pmd) 109 *(.data..vm0.pmd)
110 *(.data.vm0.pgd) 110 *(.data..vm0.pgd)
111 *(.data.vm0.pte) 111 *(.data..vm0.pte)
112 } 112 }
113 .bss : { 113 .bss : {
114 *(.bss) 114 *(.bss)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 66a315e06dce..328774bd41ee 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -351,7 +351,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
351 351
352config KEXEC 352config KEXEC
353 bool "kexec system call (EXPERIMENTAL)" 353 bool "kexec system call (EXPERIMENTAL)"
354 depends on PPC_BOOK3S && EXPERIMENTAL 354 depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL
355 help 355 help
356 kexec is a system call that implements the ability to shutdown your 356 kexec is a system call that implements the ability to shutdown your
357 current kernel, and to start another kernel. It is like a reboot 357 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 1a54a3b3a3fa..42dcd3f4ad7b 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -112,6 +112,11 @@ KBUILD_CFLAGS += $(call cc-option,-mspe=no)
112# kernel considerably. 112# kernel considerably.
113KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) 113KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
114 114
115# FIXME: the module load should be taught about the additional relocs
116# generated by this.
117# revert to pre-gcc-4.4 behaviour of .eh_frame
118KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
119
115# Never use string load/store instructions as they are 120# Never use string load/store instructions as they are
116# often slow when they are implemented at all 121# often slow when they are implemented at all
117KBUILD_CFLAGS += -mno-string 122KBUILD_CFLAGS += -mno-string
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 27db8938827a..9d3bd4c45a24 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -519,7 +519,7 @@ void ibm440ep_fixup_clocks(unsigned int sys_clk,
519{ 519{
520 unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0); 520 unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0);
521 521
522 /* serial clocks beed fixup based on int/ext */ 522 /* serial clocks need fixup based on int/ext */
523 eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk); 523 eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk);
524 eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk); 524 eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk);
525 eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk); 525 eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk);
@@ -532,7 +532,7 @@ void ibm440gx_fixup_clocks(unsigned int sys_clk,
532{ 532{
533 unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); 533 unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
534 534
535 /* serial clocks beed fixup based on int/ext */ 535 /* serial clocks need fixup based on int/ext */
536 eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk); 536 eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk);
537 eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk); 537 eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk);
538} 538}
@@ -543,10 +543,10 @@ void ibm440spe_fixup_clocks(unsigned int sys_clk,
543{ 543{
544 unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); 544 unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
545 545
546 /* serial clocks beed fixup based on int/ext */ 546 /* serial clocks need fixup based on int/ext */
547 eplike_fixup_uart_clk(0, "/plb/opb/serial@10000200", ser_clk, plb_clk); 547 eplike_fixup_uart_clk(0, "/plb/opb/serial@f0000200", ser_clk, plb_clk);
548 eplike_fixup_uart_clk(1, "/plb/opb/serial@10000300", ser_clk, plb_clk); 548 eplike_fixup_uart_clk(1, "/plb/opb/serial@f0000300", ser_clk, plb_clk);
549 eplike_fixup_uart_clk(2, "/plb/opb/serial@10000600", ser_clk, plb_clk); 549 eplike_fixup_uart_clk(2, "/plb/opb/serial@f0000600", ser_clk, plb_clk);
550} 550}
551 551
552void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) 552void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
diff --git a/arch/powerpc/boot/dts/icon.dts b/arch/powerpc/boot/dts/icon.dts
new file mode 100644
index 000000000000..abcd0caeccae
--- /dev/null
+++ b/arch/powerpc/boot/dts/icon.dts
@@ -0,0 +1,447 @@
1/*
2 * Device Tree Source for Mosaix Technologies, Inc. ICON board
3 *
4 * Copyright 2010 DENX Software Engineering, Stefan Roese <sr@denx.de>
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without
8 * any warranty of any kind, whether express or implied.
9 */
10
11/dts-v1/;
12
13/ {
14 #address-cells = <2>;
15 #size-cells = <2>;
16 model = "mosaixtech,icon";
17 compatible = "mosaixtech,icon";
18 dcr-parent = <&{/cpus/cpu@0}>;
19
20 aliases {
21 ethernet0 = &EMAC0;
22 serial0 = &UART0;
23 serial1 = &UART1;
24 serial2 = &UART2;
25 };
26
27 cpus {
28 #address-cells = <1>;
29 #size-cells = <0>;
30
31 cpu@0 {
32 device_type = "cpu";
33 model = "PowerPC,440SPe";
34 reg = <0x00000000>;
35 clock-frequency = <0>; /* Filled in by U-Boot */
36 timebase-frequency = <0>; /* Filled in by U-Boot */
37 i-cache-line-size = <32>;
38 d-cache-line-size = <32>;
39 i-cache-size = <32768>;
40 d-cache-size = <32768>;
41 dcr-controller;
42 dcr-access-method = "native";
43 reset-type = <2>; /* Use chip-reset */
44 };
45 };
46
47 memory {
48 device_type = "memory";
49 reg = <0x0 0x00000000 0x0 0x00000000>; /* Filled in by U-Boot */
50 };
51
52 UIC0: interrupt-controller0 {
53 compatible = "ibm,uic-440spe","ibm,uic";
54 interrupt-controller;
55 cell-index = <0>;
56 dcr-reg = <0x0c0 0x009>;
57 #address-cells = <0>;
58 #size-cells = <0>;
59 #interrupt-cells = <2>;
60 };
61
62 UIC1: interrupt-controller1 {
63 compatible = "ibm,uic-440spe","ibm,uic";
64 interrupt-controller;
65 cell-index = <1>;
66 dcr-reg = <0x0d0 0x009>;
67 #address-cells = <0>;
68 #size-cells = <0>;
69 #interrupt-cells = <2>;
70 interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
71 interrupt-parent = <&UIC0>;
72 };
73
74 UIC2: interrupt-controller2 {
75 compatible = "ibm,uic-440spe","ibm,uic";
76 interrupt-controller;
77 cell-index = <2>;
78 dcr-reg = <0x0e0 0x009>;
79 #address-cells = <0>;
80 #size-cells = <0>;
81 #interrupt-cells = <2>;
82 interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
83 interrupt-parent = <&UIC0>;
84 };
85
86 UIC3: interrupt-controller3 {
87 compatible = "ibm,uic-440spe","ibm,uic";
88 interrupt-controller;
89 cell-index = <3>;
90 dcr-reg = <0x0f0 0x009>;
91 #address-cells = <0>;
92 #size-cells = <0>;
93 #interrupt-cells = <2>;
94 interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
95 interrupt-parent = <&UIC0>;
96 };
97
98 SDR0: sdr {
99 compatible = "ibm,sdr-440spe";
100 dcr-reg = <0x00e 0x002>;
101 };
102
103 CPR0: cpr {
104 compatible = "ibm,cpr-440spe";
105 dcr-reg = <0x00c 0x002>;
106 };
107
108 MQ0: mq {
109 compatible = "ibm,mq-440spe";
110 dcr-reg = <0x040 0x020>;
111 };
112
113 plb {
114 compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4";
115 #address-cells = <2>;
116 #size-cells = <1>;
117 /* addr-child addr-parent size */
118 ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000
119 0x4 0x00200000 0x4 0x00200000 0x00000400
120 0x4 0xe0000000 0x4 0xe0000000 0x20000000
121 0xc 0x00000000 0xc 0x00000000 0x20000000
122 0xd 0x00000000 0xd 0x00000000 0x80000000
123 0xd 0x80000000 0xd 0x80000000 0x80000000
124 0xe 0x00000000 0xe 0x00000000 0x80000000
125 0xe 0x80000000 0xe 0x80000000 0x80000000
126 0xf 0x00000000 0xf 0x00000000 0x80000000
127 0xf 0x80000000 0xf 0x80000000 0x80000000>;
128 clock-frequency = <0>; /* Filled in by U-Boot */
129
130 SDRAM0: sdram {
131 compatible = "ibm,sdram-440spe", "ibm,sdram-405gp";
132 dcr-reg = <0x010 0x002>;
133 };
134
135 MAL0: mcmal {
136 compatible = "ibm,mcmal-440spe", "ibm,mcmal2";
137 dcr-reg = <0x180 0x062>;
138 num-tx-chans = <2>;
139 num-rx-chans = <1>;
140 interrupt-parent = <&MAL0>;
141 interrupts = <0x0 0x1 0x2 0x3 0x4>;
142 #interrupt-cells = <1>;
143 #address-cells = <0>;
144 #size-cells = <0>;
145 interrupt-map = </*TXEOB*/ 0x0 &UIC1 0x6 0x4
146 /*RXEOB*/ 0x1 &UIC1 0x7 0x4
147 /*SERR*/ 0x2 &UIC1 0x1 0x4
148 /*TXDE*/ 0x3 &UIC1 0x2 0x4
149 /*RXDE*/ 0x4 &UIC1 0x3 0x4>;
150 };
151
152 POB0: opb {
153 compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
154 #address-cells = <1>;
155 #size-cells = <1>;
156 ranges = <0xe0000000 0x00000004 0xe0000000 0x20000000>;
157 clock-frequency = <0>; /* Filled in by U-Boot */
158
159 EBC0: ebc {
160 compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc";
161 dcr-reg = <0x012 0x002>;
162 #address-cells = <2>;
163 #size-cells = <1>;
164 clock-frequency = <0>; /* Filled in by U-Boot */
165 /* ranges property is supplied by U-Boot */
166 interrupts = <0x5 0x1>;
167 interrupt-parent = <&UIC1>;
168
169 nor_flash@0,0 {
170 compatible = "cfi-flash";
171 bank-width = <2>;
172 reg = <0x00000000 0x00000000 0x01000000>;
173 #address-cells = <1>;
174 #size-cells = <1>;
175 partition@0 {
176 label = "kernel";
177 reg = <0x00000000 0x001e0000>;
178 };
179 partition@1e0000 {
180 label = "dtb";
181 reg = <0x001e0000 0x00020000>;
182 };
183 partition@200000 {
184 label = "root";
185 reg = <0x00200000 0x00200000>;
186 };
187 partition@400000 {
188 label = "user";
189 reg = <0x00400000 0x00b60000>;
190 };
191 partition@f60000 {
192 label = "env";
193 reg = <0x00f60000 0x00040000>;
194 };
195 partition@fa0000 {
196 label = "u-boot";
197 reg = <0x00fa0000 0x00060000>;
198 };
199 };
200
201 SysACE_CompactFlash: sysace@1,0 {
202 compatible = "xlnx,sysace";
203 interrupt-parent = <&UIC2>;
204 interrupts = <24 0x4>;
205 reg = <0x00000001 0x00000000 0x10000>;
206 };
207 };
208
209 UART0: serial@f0000200 {
210 device_type = "serial";
211 compatible = "ns16550";
212 reg = <0xf0000200 0x00000008>;
213 virtual-reg = <0xa0000200>;
214 clock-frequency = <0>; /* Filled in by U-Boot */
215 current-speed = <115200>;
216 interrupt-parent = <&UIC0>;
217 interrupts = <0x0 0x4>;
218 };
219
220 UART1: serial@f0000300 {
221 device_type = "serial";
222 compatible = "ns16550";
223 reg = <0xf0000300 0x00000008>;
224 virtual-reg = <0xa0000300>;
225 clock-frequency = <0>;
226 current-speed = <0>;
227 interrupt-parent = <&UIC0>;
228 interrupts = <0x1 0x4>;
229 };
230
231
232 UART2: serial@f0000600 {
233 device_type = "serial";
234 compatible = "ns16550";
235 reg = <0xf0000600 0x00000008>;
236 virtual-reg = <0xa0000600>;
237 clock-frequency = <0>;
238 current-speed = <0>;
239 interrupt-parent = <&UIC1>;
240 interrupts = <0x5 0x4>;
241 };
242
243 IIC0: i2c@f0000400 {
244 compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
245 reg = <0xf0000400 0x00000014>;
246 interrupt-parent = <&UIC0>;
247 interrupts = <0x2 0x4>;
248 };
249
250 IIC1: i2c@f0000500 {
251 compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
252 reg = <0xf0000500 0x00000014>;
253 interrupt-parent = <&UIC0>;
254 interrupts = <0x3 0x4>;
255 #address-cells = <1>;
256 #size-cells = <0>;
257
258 rtc@68 {
259 compatible = "stm,m41t00";
260 reg = <0x68>;
261 };
262 };
263
264 EMAC0: ethernet@f0000800 {
265 linux,network-index = <0x0>;
266 device_type = "network";
267 compatible = "ibm,emac-440spe", "ibm,emac4";
268 interrupt-parent = <&UIC1>;
269 interrupts = <0x1c 0x4 0x1d 0x4>;
270 reg = <0xf0000800 0x00000074>;
271 local-mac-address = [000000000000];
272 mal-device = <&MAL0>;
273 mal-tx-channel = <0>;
274 mal-rx-channel = <0>;
275 cell-index = <0>;
276 max-frame-size = <9000>;
277 rx-fifo-size = <4096>;
278 tx-fifo-size = <2048>;
279 phy-mode = "gmii";
280 phy-map = <0x00000000>;
281 has-inverted-stacr-oc;
282 has-new-stacr-staopc;
283 };
284 };
285
286 PCIX0: pci@c0ec00000 {
287 device_type = "pci";
288 #interrupt-cells = <1>;
289 #size-cells = <2>;
290 #address-cells = <3>;
291 compatible = "ibm,plb-pcix-440spe", "ibm,plb-pcix";
292 primary;
293 large-inbound-windows;
294 enable-msi-hole;
295 reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */
296 0x00000000 0x00000000 0x00000000 /* no IACK cycles */
297 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */
298 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */
299 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */
300
301 /* Outbound ranges, one memory and one IO,
302 * later cannot be changed
303 */
304 ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
305 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
306
307 /* Inbound 4GB range starting at 0 */
308 dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
309
310 /* This drives busses 0 to 0xf */
311 bus-range = <0x0 0xf>;
312
313 /* PCI-X interrupt (SM502) is routed to extIRQ10 (UIC1, 19) */
314 interrupt-map-mask = <0x0 0x0 0x0 0x0>;
315 interrupt-map = <0x0 0x0 0x0 0x0 &UIC1 19 0x8>;
316 };
317
318 PCIE0: pciex@d00000000 {
319 device_type = "pci";
320 #interrupt-cells = <1>;
321 #size-cells = <2>;
322 #address-cells = <3>;
323 compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex";
324 primary;
325 port = <0x0>; /* port number */
326 reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */
327 0x0000000c 0x10000000 0x00001000>; /* Registers */
328 dcr-reg = <0x100 0x020>;
329 sdr-base = <0x300>;
330
331 /* Outbound ranges, one memory and one IO,
332 * later cannot be changed
333 */
334 ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
335 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
336
337 /* Inbound 4GB range starting at 0 */
338 dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
339
340 /* This drives busses 0x10 to 0x1f */
341 bus-range = <0x10 0x1f>;
342
343 /* Legacy interrupts (note the weird polarity, the bridge seems
344 * to invert PCIe legacy interrupts).
345 * We are de-swizzling here because the numbers are actually for
346 * port of the root complex virtual P2P bridge. But I want
347 * to avoid putting a node for it in the tree, so the numbers
348 * below are basically de-swizzled numbers.
349 * The real slot is on idsel 0, so the swizzling is 1:1
350 */
351 interrupt-map-mask = <0x0 0x0 0x0 0x7>;
352 interrupt-map = <
353 0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */
354 0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */
355 0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */
356 0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>;
357 };
358
359 PCIE1: pciex@d20000000 {
360 device_type = "pci";
361 #interrupt-cells = <1>;
362 #size-cells = <2>;
363 #address-cells = <3>;
364 compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex";
365 primary;
366 port = <0x1>; /* port number */
367 reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */
368 0x0000000c 0x10001000 0x00001000>; /* Registers */
369 dcr-reg = <0x120 0x020>;
370 sdr-base = <0x340>;
371
372 /* Outbound ranges, one memory and one IO,
373 * later cannot be changed
374 */
375 ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
376 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
377
378 /* Inbound 4GB range starting at 0 */
379 dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
380
381 /* This drives busses 0x20 to 0x2f */
382 bus-range = <0x20 0x2f>;
383
384 /* Legacy interrupts (note the weird polarity, the bridge seems
385 * to invert PCIe legacy interrupts).
386 * We are de-swizzling here because the numbers are actually for
387 * port of the root complex virtual P2P bridge. But I want
388 * to avoid putting a node for it in the tree, so the numbers
389 * below are basically de-swizzled numbers.
390 * The real slot is on idsel 0, so the swizzling is 1:1
391 */
392 interrupt-map-mask = <0x0 0x0 0x0 0x7>;
393 interrupt-map = <
394 0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */
395 0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */
396 0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */
397 0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>;
398 };
399
400 I2O: i2o@400100000 {
401 compatible = "ibm,i2o-440spe";
402 reg = <0x00000004 0x00100000 0x100>;
403 dcr-reg = <0x060 0x020>;
404 };
405
406 DMA0: dma0@400100100 {
407 compatible = "ibm,dma-440spe";
408 cell-index = <0>;
409 reg = <0x00000004 0x00100100 0x100>;
410 dcr-reg = <0x060 0x020>;
411 interrupt-parent = <&DMA0>;
412 interrupts = <0 1>;
413 #interrupt-cells = <1>;
414 #address-cells = <0>;
415 #size-cells = <0>;
416 interrupt-map = <
417 0 &UIC0 0x14 4
418 1 &UIC1 0x16 4>;
419 };
420
421 DMA1: dma1@400100200 {
422 compatible = "ibm,dma-440spe";
423 cell-index = <1>;
424 reg = <0x00000004 0x00100200 0x100>;
425 dcr-reg = <0x060 0x020>;
426 interrupt-parent = <&DMA1>;
427 interrupts = <0 1>;
428 #interrupt-cells = <1>;
429 #address-cells = <0>;
430 #size-cells = <0>;
431 interrupt-map = <
432 0 &UIC0 0x16 4
433 1 &UIC1 0x16 4>;
434 };
435
436 xor-accel@400200000 {
437 compatible = "amcc,xor-accelerator";
438 reg = <0x00000004 0x00200000 0x400>;
439 interrupt-parent = <&UIC1>;
440 interrupts = <0x1f 4>;
441 };
442 };
443
444 chosen {
445 linux,stdout-path = "/plb/opb/serial@f0000200";
446 };
447};
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index 8cf2c0c88c05..7c3be5e45748 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -44,6 +44,7 @@
44 d-cache-size = <32768>; 44 d-cache-size = <32768>;
45 dcr-controller; 45 dcr-controller;
46 dcr-access-method = "native"; 46 dcr-access-method = "native";
47 reset-type = <2>; /* Use chip-reset */
47 }; 48 };
48 }; 49 };
49 50
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index 4173af387c63..0f5262452682 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -20,10 +20,8 @@
20 aliases { 20 aliases {
21 ethernet0 = &enet0; 21 ethernet0 = &enet0;
22 ethernet1 = &enet1; 22 ethernet1 = &enet1;
23/*
24 ethernet2 = &enet2; 23 ethernet2 = &enet2;
25 ethernet3 = &enet3; 24 ethernet3 = &enet3;
26*/
27 serial0 = &serial0; 25 serial0 = &serial0;
28 serial1 = &serial1; 26 serial1 = &serial1;
29 pci0 = &pci0; 27 pci0 = &pci0;
@@ -254,7 +252,6 @@
254 }; 252 };
255 }; 253 };
256 254
257/* eTSEC 3/4 are currently broken
258 enet2: ethernet@26000 { 255 enet2: ethernet@26000 {
259 #address-cells = <1>; 256 #address-cells = <1>;
260 #size-cells = <1>; 257 #size-cells = <1>;
@@ -310,7 +307,6 @@
310 }; 307 };
311 }; 308 };
312 }; 309 };
313 */
314 310
315 serial0: serial@4500 { 311 serial0: serial@4500 {
316 cell-index = <0>; 312 cell-index = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
index 5bd1011fde96..3375c2ab0c32 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
@@ -215,6 +215,18 @@
215 clock-frequency = <0>; 215 clock-frequency = <0>;
216 }; 216 };
217 217
218 msi@41600 {
219 compatible = "fsl,mpc8572-msi", "fsl,mpic-msi";
220 reg = <0x41600 0x80>;
221 msi-available-ranges = <0 0x80>;
222 interrupts = <
223 0xe0 0
224 0xe1 0
225 0xe2 0
226 0xe3 0>;
227 interrupt-parent = <&mpic>;
228 };
229
218 global-utilities@e0000 { //global utilities block 230 global-utilities@e0000 { //global utilities block
219 compatible = "fsl,mpc8572-guts"; 231 compatible = "fsl,mpc8572-guts";
220 reg = <0xe0000 0x1000>; 232 reg = <0xe0000 0x1000>;
@@ -243,8 +255,7 @@
243 protected-sources = < 255 protected-sources = <
244 31 32 33 37 38 39 /* enet2 enet3 */ 256 31 32 33 37 38 39 /* enet2 enet3 */
245 76 77 78 79 26 42 /* dma2 pci2 serial*/ 257 76 77 78 79 26 42 /* dma2 pci2 serial*/
246 0xe0 0xe1 0xe2 0xe3 /* msi */ 258 0xe4 0xe5 0xe6 0xe7 /* msi */
247 0xe4 0xe5 0xe6 0xe7
248 >; 259 >;
249 }; 260 };
250 }; 261 };
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
index 0efc3456e297..e7b477f6a3fe 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
@@ -154,12 +154,8 @@
154 msi@41600 { 154 msi@41600 {
155 compatible = "fsl,mpc8572-msi", "fsl,mpic-msi"; 155 compatible = "fsl,mpc8572-msi", "fsl,mpic-msi";
156 reg = <0x41600 0x80>; 156 reg = <0x41600 0x80>;
157 msi-available-ranges = <0 0x100>; 157 msi-available-ranges = <0x80 0x80>;
158 interrupts = < 158 interrupts = <
159 0xe0 0
160 0xe1 0
161 0xe2 0
162 0xe3 0
163 0xe4 0 159 0xe4 0
164 0xe5 0 160 0xe5 0
165 0xe6 0 161 0xe6 0
@@ -190,6 +186,7 @@
190 0x1 0x2 0x3 0x4 /* pci slot */ 186 0x1 0x2 0x3 0x4 /* pci slot */
191 0x9 0xa 0xb 0xc /* usb */ 187 0x9 0xa 0xb 0xc /* usb */
192 0x6 0x7 0xe 0x5 /* Audio elgacy SATA */ 188 0x6 0x7 0xe 0x5 /* Audio elgacy SATA */
189 0xe0 0xe1 0xe2 0xe3 /* msi */
193 >; 190 >;
194 }; 191 };
195 }; 192 };
diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts
new file mode 100644
index 000000000000..7fad2df25981
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1021mds.dts
@@ -0,0 +1,698 @@
1/*
2 * P1021 MDS Device Tree Source
3 *
4 * Copyright 2010 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12/dts-v1/;
13/ {
14 model = "fsl,P1021";
15 compatible = "fsl,P1021MDS";
16 #address-cells = <2>;
17 #size-cells = <2>;
18
19 aliases {
20 serial0 = &serial0;
21 serial1 = &serial1;
22 ethernet0 = &enet0;
23 ethernet1 = &enet1;
24 ethernet2 = &enet2;
25 ethernet3 = &enet3;
26 ethernet4 = &enet4;
27 pci0 = &pci0;
28 pci1 = &pci1;
29 };
30
31 cpus {
32 #address-cells = <1>;
33 #size-cells = <0>;
34
35 PowerPC,P1021@0 {
36 device_type = "cpu";
37 reg = <0x0>;
38 next-level-cache = <&L2>;
39 };
40
41 PowerPC,P1021@1 {
42 device_type = "cpu";
43 reg = <0x1>;
44 next-level-cache = <&L2>;
45 };
46 };
47
48 memory {
49 device_type = "memory";
50 };
51
52 localbus@ffe05000 {
53 #address-cells = <2>;
54 #size-cells = <1>;
55 compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus";
56 reg = <0 0xffe05000 0 0x1000>;
57 interrupts = <19 2>;
58 interrupt-parent = <&mpic>;
59
60 /* NAND Flash, BCSR, PMC0/1*/
61 ranges = <0x0 0x0 0x0 0xfc000000 0x02000000
62 0x1 0x0 0x0 0xf8000000 0x00008000
63 0x2 0x0 0x0 0xf8010000 0x00020000
64 0x3 0x0 0x0 0xf8020000 0x00020000>;
65
66 nand@0,0 {
67 #address-cells = <1>;
68 #size-cells = <1>;
69 compatible = "fsl,p1021-fcm-nand",
70 "fsl,elbc-fcm-nand";
71 reg = <0x0 0x0 0x40000>;
72
73 partition@0 {
74 /* This location must not be altered */
75 /* 1MB for u-boot Bootloader Image */
76 reg = <0x0 0x00100000>;
77 label = "NAND (RO) U-Boot Image";
78 read-only;
79 };
80
81 partition@100000 {
82 /* 1MB for DTB Image */
83 reg = <0x00100000 0x00100000>;
84 label = "NAND (RO) DTB Image";
85 read-only;
86 };
87
88 partition@200000 {
89 /* 4MB for Linux Kernel Image */
90 reg = <0x00200000 0x00400000>;
91 label = "NAND (RO) Linux Kernel Image";
92 read-only;
93 };
94
95 partition@600000 {
96 /* 5MB for Compressed Root file System Image */
97 reg = <0x00600000 0x00500000>;
98 label = "NAND (RO) Compressed RFS Image";
99 read-only;
100 };
101
102 partition@b00000 {
103 /* 6MB for JFFS2 based Root file System */
104 reg = <0x00a00000 0x00600000>;
105 label = "NAND (RW) JFFS2 Root File System";
106 };
107
108 partition@1100000 {
109 /* 14MB for JFFS2 based Root file System */
110 reg = <0x01100000 0x00e00000>;
111 label = "NAND (RW) Writable User area";
112 };
113
114 partition@1f00000 {
115 /* 1MB for microcode */
116 reg = <0x01f00000 0x00100000>;
117 label = "NAND (RO) QE Ucode";
118 read-only;
119 };
120 };
121
122 bcsr@1,0 {
123 #address-cells = <1>;
124 #size-cells = <1>;
125 compatible = "fsl,p1021mds-bcsr";
126 reg = <1 0 0x8000>;
127 ranges = <0 1 0 0x8000>;
128 };
129
130 pib@2,0 {
131 compatible = "fsl,p1021mds-pib";
132 reg = <2 0 0x10000>;
133 };
134
135 pib@3,0 {
136 compatible = "fsl,p1021mds-pib";
137 reg = <3 0 0x10000>;
138 };
139 };
140
141 soc@ffe00000 {
142
143 #address-cells = <1>;
144 #size-cells = <1>;
145 device_type = "soc";
146 compatible = "fsl,p1021-immr", "simple-bus";
147 ranges = <0x0 0x0 0xffe00000 0x100000>;
148 bus-frequency = <0>; // Filled out by uboot.
149
150 ecm-law@0 {
151 compatible = "fsl,ecm-law";
152 reg = <0x0 0x1000>;
153 fsl,num-laws = <12>;
154 };
155
156 ecm@1000 {
157 compatible = "fsl,p1021-ecm", "fsl,ecm";
158 reg = <0x1000 0x1000>;
159 interrupts = <16 2>;
160 interrupt-parent = <&mpic>;
161 };
162
163 memory-controller@2000 {
164 compatible = "fsl,p1021-memory-controller";
165 reg = <0x2000 0x1000>;
166 interrupt-parent = <&mpic>;
167 interrupts = <16 2>;
168 };
169
170 i2c@3000 {
171 #address-cells = <1>;
172 #size-cells = <0>;
173 cell-index = <0>;
174 compatible = "fsl-i2c";
175 reg = <0x3000 0x100>;
176 interrupts = <43 2>;
177 interrupt-parent = <&mpic>;
178 dfsrr;
179 rtc@68 {
180 compatible = "dallas,ds1374";
181 reg = <0x68>;
182 };
183 };
184
185 i2c@3100 {
186 #address-cells = <1>;
187 #size-cells = <0>;
188 cell-index = <1>;
189 compatible = "fsl-i2c";
190 reg = <0x3100 0x100>;
191 interrupts = <43 2>;
192 interrupt-parent = <&mpic>;
193 dfsrr;
194 };
195
196 serial0: serial@4500 {
197 cell-index = <0>;
198 device_type = "serial";
199 compatible = "ns16550";
200 reg = <0x4500 0x100>;
201 clock-frequency = <0>;
202 interrupts = <42 2>;
203 interrupt-parent = <&mpic>;
204 };
205
206 serial1: serial@4600 {
207 cell-index = <1>;
208 device_type = "serial";
209 compatible = "ns16550";
210 reg = <0x4600 0x100>;
211 clock-frequency = <0>;
212 interrupts = <42 2>;
213 interrupt-parent = <&mpic>;
214 };
215
216 spi@7000 {
217 cell-index = <0>;
218 #address-cells = <1>;
219 #size-cells = <0>;
220 compatible = "fsl,espi";
221 reg = <0x7000 0x1000>;
222 interrupts = <59 0x2>;
223 interrupt-parent = <&mpic>;
224 espi,num-ss-bits = <4>;
225 mode = "cpu";
226
227 fsl_m25p80@0 {
228 #address-cells = <1>;
229 #size-cells = <1>;
230 compatible = "fsl,espi-flash";
231 reg = <0>;
232 linux,modalias = "fsl_m25p80";
233 spi-max-frequency = <40000000>; /* input clock */
234 partition@u-boot {
235 label = "u-boot-spi";
236 reg = <0x00000000 0x00100000>;
237 read-only;
238 };
239 partition@kernel {
240 label = "kernel-spi";
241 reg = <0x00100000 0x00500000>;
242 read-only;
243 };
244 partition@dtb {
245 label = "dtb-spi";
246 reg = <0x00600000 0x00100000>;
247 read-only;
248 };
249 partition@fs {
250 label = "file system-spi";
251 reg = <0x00700000 0x00900000>;
252 };
253 };
254 };
255
256 gpio: gpio-controller@f000 {
257 #gpio-cells = <2>;
258 compatible = "fsl,mpc8572-gpio";
259 reg = <0xf000 0x100>;
260 interrupts = <47 0x2>;
261 interrupt-parent = <&mpic>;
262 gpio-controller;
263 };
264
265 L2: l2-cache-controller@20000 {
266 compatible = "fsl,p1021-l2-cache-controller";
267 reg = <0x20000 0x1000>;
268 cache-line-size = <32>; // 32 bytes
269 cache-size = <0x40000>; // L2,256K
270 interrupt-parent = <&mpic>;
271 interrupts = <16 2>;
272 };
273
274 dma@21300 {
275 #address-cells = <1>;
276 #size-cells = <1>;
277 compatible = "fsl,eloplus-dma";
278 reg = <0x21300 0x4>;
279 ranges = <0x0 0x21100 0x200>;
280 cell-index = <0>;
281 dma-channel@0 {
282 compatible = "fsl,eloplus-dma-channel";
283 reg = <0x0 0x80>;
284 cell-index = <0>;
285 interrupt-parent = <&mpic>;
286 interrupts = <20 2>;
287 };
288 dma-channel@80 {
289 compatible = "fsl,eloplus-dma-channel";
290 reg = <0x80 0x80>;
291 cell-index = <1>;
292 interrupt-parent = <&mpic>;
293 interrupts = <21 2>;
294 };
295 dma-channel@100 {
296 compatible = "fsl,eloplus-dma-channel";
297 reg = <0x100 0x80>;
298 cell-index = <2>;
299 interrupt-parent = <&mpic>;
300 interrupts = <22 2>;
301 };
302 dma-channel@180 {
303 compatible = "fsl,eloplus-dma-channel";
304 reg = <0x180 0x80>;
305 cell-index = <3>;
306 interrupt-parent = <&mpic>;
307 interrupts = <23 2>;
308 };
309 };
310
311 usb@22000 {
312 #address-cells = <1>;
313 #size-cells = <0>;
314 compatible = "fsl-usb2-dr";
315 reg = <0x22000 0x1000>;
316 interrupt-parent = <&mpic>;
317 interrupts = <28 0x2>;
318 phy_type = "ulpi";
319 };
320
321 mdio@24000 {
322 #address-cells = <1>;
323 #size-cells = <0>;
324 compatible = "fsl,etsec2-mdio";
325 reg = <0x24000 0x1000 0xb0030 0x4>;
326
327 phy0: ethernet-phy@0 {
328 interrupt-parent = <&mpic>;
329 interrupts = <1 1>;
330 reg = <0x0>;
331 };
332 phy1: ethernet-phy@1 {
333 interrupt-parent = <&mpic>;
334 interrupts = <2 1>;
335 reg = <0x1>;
336 };
337 phy4: ethernet-phy@4 {
338 interrupt-parent = <&mpic>;
339 reg = <0x4>;
340 };
341 };
342
343 mdio@25000 {
344 #address-cells = <1>;
345 #size-cells = <0>;
346 compatible = "fsl,etsec2-tbi";
347 reg = <0x25000 0x1000 0xb1030 0x4>;
348 tbi0: tbi-phy@11 {
349 reg = <0x11>;
350 device_type = "tbi-phy";
351 };
352 };
353
354 enet0: ethernet@B0000 {
355 #address-cells = <1>;
356 #size-cells = <1>;
357 cell-index = <0>;
358 device_type = "network";
359 model = "eTSEC";
360 compatible = "fsl,etsec2";
361 fsl,num_rx_queues = <0x8>;
362 fsl,num_tx_queues = <0x8>;
363 local-mac-address = [ 00 00 00 00 00 00 ];
364 interrupt-parent = <&mpic>;
365 phy-handle = <&phy0>;
366 phy-connection-type = "rgmii-id";
367 queue-group@0{
368 #address-cells = <1>;
369 #size-cells = <1>;
370 reg = <0xB0000 0x1000>;
371 interrupts = <29 2 30 2 34 2>;
372 };
373 queue-group@1{
374 #address-cells = <1>;
375 #size-cells = <1>;
376 reg = <0xB4000 0x1000>;
377 interrupts = <17 2 18 2 24 2>;
378 };
379 };
380
381 enet1: ethernet@B1000 {
382 #address-cells = <1>;
383 #size-cells = <1>;
384 cell-index = <0>;
385 device_type = "network";
386 model = "eTSEC";
387 compatible = "fsl,etsec2";
388 fsl,num_rx_queues = <0x8>;
389 fsl,num_tx_queues = <0x8>;
390 local-mac-address = [ 00 00 00 00 00 00 ];
391 interrupt-parent = <&mpic>;
392 phy-handle = <&phy4>;
393 tbi-handle = <&tbi0>;
394 phy-connection-type = "sgmii";
395 queue-group@0{
396 #address-cells = <1>;
397 #size-cells = <1>;
398 reg = <0xB1000 0x1000>;
399 interrupts = <35 2 36 2 40 2>;
400 };
401 queue-group@1{
402 #address-cells = <1>;
403 #size-cells = <1>;
404 reg = <0xB5000 0x1000>;
405 interrupts = <51 2 52 2 67 2>;
406 };
407 };
408
409 enet2: ethernet@B2000 {
410 #address-cells = <1>;
411 #size-cells = <1>;
412 cell-index = <0>;
413 device_type = "network";
414 model = "eTSEC";
415 compatible = "fsl,etsec2";
416 fsl,num_rx_queues = <0x8>;
417 fsl,num_tx_queues = <0x8>;
418 local-mac-address = [ 00 00 00 00 00 00 ];
419 interrupt-parent = <&mpic>;
420 phy-handle = <&phy1>;
421 phy-connection-type = "rgmii-id";
422 queue-group@0{
423 #address-cells = <1>;
424 #size-cells = <1>;
425 reg = <0xB2000 0x1000>;
426 interrupts = <31 2 32 2 33 2>;
427 };
428 queue-group@1{
429 #address-cells = <1>;
430 #size-cells = <1>;
431 reg = <0xB6000 0x1000>;
432 interrupts = <25 2 26 2 27 2>;
433 };
434 };
435
436 sdhci@2e000 {
437 compatible = "fsl,p1021-esdhc", "fsl,esdhc";
438 reg = <0x2e000 0x1000>;
439 interrupts = <72 0x2>;
440 interrupt-parent = <&mpic>;
441 /* Filled in by U-Boot */
442 clock-frequency = <0>;
443 };
444
445 crypto@30000 {
446 compatible = "fsl,sec3.3", "fsl,sec3.1",
447 "fsl,sec3.0", "fsl,sec2.4",
448 "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
449 reg = <0x30000 0x10000>;
450 interrupts = <45 2 58 2>;
451 interrupt-parent = <&mpic>;
452 fsl,num-channels = <4>;
453 fsl,channel-fifo-len = <24>;
454 fsl,exec-units-mask = <0x97c>;
455 fsl,descriptor-types-mask = <0x3a30abf>;
456 };
457
458 mpic: pic@40000 {
459 interrupt-controller;
460 #address-cells = <0>;
461 #interrupt-cells = <2>;
462 reg = <0x40000 0x40000>;
463 compatible = "chrp,open-pic";
464 device_type = "open-pic";
465 };
466
467 msi@41600 {
468 compatible = "fsl,p1021-msi", "fsl,mpic-msi";
469 reg = <0x41600 0x80>;
470 msi-available-ranges = <0 0x100>;
471 interrupts = <
472 0xe0 0
473 0xe1 0
474 0xe2 0
475 0xe3 0
476 0xe4 0
477 0xe5 0
478 0xe6 0
479 0xe7 0>;
480 interrupt-parent = <&mpic>;
481 };
482
483 global-utilities@e0000 { //global utilities block
484 compatible = "fsl,p1021-guts";
485 reg = <0xe0000 0x1000>;
486 fsl,has-rstcr;
487 };
488
489 par_io@e0100 {
490 #address-cells = <1>;
491 #size-cells = <1>;
492 reg = <0xe0100 0x60>;
493 ranges = <0x0 0xe0100 0x60>;
494 device_type = "par_io";
495 num-ports = <3>;
496 pio1: ucc_pin@01 {
497 pio-map = <
498 /* port pin dir open_drain assignment has_irq */
499 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
500 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
501 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
502 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9
503*/
504 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
505 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
506 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
507 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
508 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
509 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
510 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
511 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
512 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
513 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
514 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
515 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
516 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
517 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
518 };
519
520 pio2: ucc_pin@02 {
521 pio-map = <
522 /* port pin dir open_drain assignment has_irq */
523 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
524 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
525 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
526 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
527 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
528 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
529 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
530 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
531 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
532 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
533 };
534 };
535 };
536
537 pci0: pcie@ffe09000 {
538 compatible = "fsl,mpc8548-pcie";
539 device_type = "pci";
540 #interrupt-cells = <1>;
541 #size-cells = <2>;
542 #address-cells = <3>;
543 reg = <0 0xffe09000 0 0x1000>;
544 bus-range = <0 255>;
545 ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
546 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
547 clock-frequency = <33333333>;
548 interrupt-parent = <&mpic>;
549 interrupts = <16 2>;
550 interrupt-map-mask = <0xf800 0 0 7>;
551 interrupt-map = <
552 /* IDSEL 0x0 */
553 0000 0 0 1 &mpic 4 1
554 0000 0 0 2 &mpic 5 1
555 0000 0 0 3 &mpic 6 1
556 0000 0 0 4 &mpic 7 1
557 >;
558 pcie@0 {
559 reg = <0x0 0x0 0x0 0x0 0x0>;
560 #size-cells = <2>;
561 #address-cells = <3>;
562 device_type = "pci";
563 ranges = <0x2000000 0x0 0xa0000000
564 0x2000000 0x0 0xa0000000
565 0x0 0x20000000
566
567 0x1000000 0x0 0x0
568 0x1000000 0x0 0x0
569 0x0 0x100000>;
570 };
571 };
572
573 pci1: pcie@ffe0a000 {
574 compatible = "fsl,mpc8548-pcie";
575 device_type = "pci";
576 #interrupt-cells = <1>;
577 #size-cells = <2>;
578 #address-cells = <3>;
579 reg = <0 0xffe0a000 0 0x1000>;
580 bus-range = <0 255>;
581 ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
582 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
583 clock-frequency = <33333333>;
584 interrupt-parent = <&mpic>;
585 interrupts = <16 2>;
586 interrupt-map-mask = <0xf800 0 0 7>;
587 interrupt-map = <
588 /* IDSEL 0x0 */
589 0000 0 0 1 &mpic 0 1
590 0000 0 0 2 &mpic 1 1
591 0000 0 0 3 &mpic 2 1
592 0000 0 0 4 &mpic 3 1
593 >;
594 pcie@0 {
595 reg = <0x0 0x0 0x0 0x0 0x0>;
596 #size-cells = <2>;
597 #address-cells = <3>;
598 device_type = "pci";
599 ranges = <0x2000000 0x0 0xc0000000
600 0x2000000 0x0 0xc0000000
601 0x0 0x20000000
602
603 0x1000000 0x0 0x0
604 0x1000000 0x0 0x0
605 0x0 0x100000>;
606 };
607 };
608
609 qe@ffe80000 {
610 #address-cells = <1>;
611 #size-cells = <1>;
612 device_type = "qe";
613 compatible = "fsl,qe";
614 ranges = <0x0 0x0 0xffe80000 0x40000>;
615 reg = <0 0xffe80000 0 0x480>;
616 brg-frequency = <0>;
617 bus-frequency = <0>;
618 fsl,qe-num-riscs = <1>;
619 fsl,qe-num-snums = <28>;
620
621 qeic: interrupt-controller@80 {
622 interrupt-controller;
623 compatible = "fsl,qe-ic";
624 #address-cells = <0>;
625 #interrupt-cells = <1>;
626 reg = <0x80 0x80>;
627 interrupts = <63 2 60 2>; //high:47 low:44
628 interrupt-parent = <&mpic>;
629 };
630
631 enet3: ucc@2000 {
632 device_type = "network";
633 compatible = "ucc_geth";
634 cell-index = <1>;
635 reg = <0x2000 0x200>;
636 interrupts = <32>;
637 interrupt-parent = <&qeic>;
638 local-mac-address = [ 00 00 00 00 00 00 ];
639 rx-clock-name = "clk12";
640 tx-clock-name = "clk9";
641 pio-handle = <&pio1>;
642 phy-handle = <&qe_phy0>;
643 phy-connection-type = "mii";
644 };
645
646 mdio@2120 {
647 #address-cells = <1>;
648 #size-cells = <0>;
649 reg = <0x2120 0x18>;
650 compatible = "fsl,ucc-mdio";
651
652 qe_phy0: ethernet-phy@0 {
653 interrupt-parent = <&mpic>;
654 interrupts = <4 1>;
655 reg = <0x0>;
656 device_type = "ethernet-phy";
657 };
658 qe_phy1: ethernet-phy@03 {
659 interrupt-parent = <&mpic>;
660 interrupts = <5 1>;
661 reg = <0x3>;
662 device_type = "ethernet-phy";
663 };
664 tbi-phy@11 {
665 reg = <0x11>;
666 device_type = "tbi-phy";
667 };
668 };
669
670 enet4: ucc@2400 {
671 device_type = "network";
672 compatible = "ucc_geth";
673 cell-index = <5>;
674 reg = <0x2400 0x200>;
675 interrupts = <40>;
676 interrupt-parent = <&qeic>;
677 local-mac-address = [ 00 00 00 00 00 00 ];
678 rx-clock-name = "none";
679 tx-clock-name = "clk13";
680 pio-handle = <&pio2>;
681 phy-handle = <&qe_phy1>;
682 phy-connection-type = "rmii";
683 };
684
685 muram@10000 {
686 #address-cells = <1>;
687 #size-cells = <1>;
688 compatible = "fsl,qe-muram", "fsl,cpm-muram";
689 ranges = <0x0 0x10000 0x6000>;
690
691 data-only@0 {
692 compatible = "fsl,qe-muram-data",
693 "fsl,cpm-muram-data";
694 reg = <0x0 0x6000>;
695 };
696 };
697 };
698};
diff --git a/arch/powerpc/boot/dts/redwood.dts b/arch/powerpc/boot/dts/redwood.dts
index d2af32e2bf7a..81636c01d906 100644
--- a/arch/powerpc/boot/dts/redwood.dts
+++ b/arch/powerpc/boot/dts/redwood.dts
@@ -234,10 +234,132 @@
234 has-inverted-stacr-oc; 234 has-inverted-stacr-oc;
235 has-new-stacr-staopc; 235 has-new-stacr-staopc;
236 }; 236 };
237 };
238 PCIE0: pciex@d00000000 {
239 device_type = "pci";
240 #interrupt-cells = <1>;
241 #size-cells = <2>;
242 #address-cells = <3>;
243 compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex";
244 primary;
245 port = <0x0>; /* port number */
246 reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */
247 0x0000000c 0x10000000 0x00001000>; /* Registers */
248 dcr-reg = <0x100 0x020>;
249 sdr-base = <0x300>;
250
251 /* Outbound ranges, one memory and one IO,
252 * later cannot be changed
253 */
254 ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
255 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
256
257 /* Inbound 2GB range starting at 0 */
258 dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
237 259
260 /* This drives busses 10 to 0x1f */
261 bus-range = <0x10 0x1f>;
262
263 /* Legacy interrupts (note the weird polarity, the bridge seems
264 * to invert PCIe legacy interrupts).
265 * We are de-swizzling here because the numbers are actually for
266 * port of the root complex virtual P2P bridge. But I want
267 * to avoid putting a node for it in the tree, so the numbers
268 * below are basically de-swizzled numbers.
269 * The real slot is on idsel 0, so the swizzling is 1:1
270 */
271 interrupt-map-mask = <0x0 0x0 0x0 0x7>;
272 interrupt-map = <
273 0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */
274 0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */
275 0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */
276 0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>;
277 };
278
279 PCIE1: pciex@d20000000 {
280 device_type = "pci";
281 #interrupt-cells = <1>;
282 #size-cells = <2>;
283 #address-cells = <3>;
284 compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex";
285 primary;
286 port = <0x1>; /* port number */
287 reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */
288 0x0000000c 0x10001000 0x00001000>; /* Registers */
289 dcr-reg = <0x120 0x020>;
290 sdr-base = <0x340>;
291
292 /* Outbound ranges, one memory and one IO,
293 * later cannot be changed
294 */
295 ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
296 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
297
298 /* Inbound 2GB range starting at 0 */
299 dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
300
301 /* This drives busses 10 to 0x1f */
302 bus-range = <0x20 0x2f>;
303
304 /* Legacy interrupts (note the weird polarity, the bridge seems
305 * to invert PCIe legacy interrupts).
306 * We are de-swizzling here because the numbers are actually for
307 * port of the root complex virtual P2P bridge. But I want
308 * to avoid putting a node for it in the tree, so the numbers
309 * below are basically de-swizzled numbers.
310 * The real slot is on idsel 0, so the swizzling is 1:1
311 */
312 interrupt-map-mask = <0x0 0x0 0x0 0x7>;
313 interrupt-map = <
314 0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */
315 0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */
316 0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */
317 0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>;
318 };
319
320 PCIE2: pciex@d40000000 {
321 device_type = "pci";
322 #interrupt-cells = <1>;
323 #size-cells = <2>;
324 #address-cells = <3>;
325 compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex";
326 primary;
327 port = <0x2>; /* port number */
328 reg = <0x0000000d 0x40000000 0x20000000 /* Config space access */
329 0x0000000c 0x10002000 0x00001000>; /* Registers */
330 dcr-reg = <0x140 0x020>;
331 sdr-base = <0x370>;
332
333 /* Outbound ranges, one memory and one IO,
334 * later cannot be changed
335 */
336 ranges = <0x02000000 0x00000000 0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000
337 0x01000000 0x00000000 0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>;
338
339 /* Inbound 2GB range starting at 0 */
340 dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
341
342 /* This drives busses 10 to 0x1f */
343 bus-range = <0x30 0x3f>;
344
345 /* Legacy interrupts (note the weird polarity, the bridge seems
346 * to invert PCIe legacy interrupts).
347 * We are de-swizzling here because the numbers are actually for
348 * port of the root complex virtual P2P bridge. But I want
349 * to avoid putting a node for it in the tree, so the numbers
350 * below are basically de-swizzled numbers.
351 * The real slot is on idsel 0, so the swizzling is 1:1
352 */
353 interrupt-map-mask = <0x0 0x0 0x0 0x7>;
354 interrupt-map = <
355 0x0 0x0 0x0 0x1 &UIC3 0x8 0x4 /* swizzled int A */
356 0x0 0x0 0x0 0x2 &UIC3 0x9 0x4 /* swizzled int B */
357 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */
358 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
238 }; 359 };
239 360
240 }; 361 };
362
241 chosen { 363 chosen {
242 linux,stdout-path = "/plb/opb/serial@ef600200"; 364 linux,stdout-path = "/plb/opb/serial@ef600200";
243 }; 365 };
diff --git a/arch/powerpc/configs/44x/icon_defconfig b/arch/powerpc/configs/44x/icon_defconfig
new file mode 100644
index 000000000000..277f88c2750f
--- /dev/null
+++ b/arch/powerpc/configs/44x/icon_defconfig
@@ -0,0 +1,1451 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.34-rc7
4# Fri May 21 17:40:22 2010
5#
6# CONFIG_PPC64 is not set
7
8#
9# Processor support
10#
11# CONFIG_PPC_BOOK3S_32 is not set
12# CONFIG_PPC_85xx is not set
13# CONFIG_PPC_8xx is not set
14# CONFIG_40x is not set
15CONFIG_44x=y
16# CONFIG_E200 is not set
17CONFIG_4xx=y
18CONFIG_BOOKE=y
19CONFIG_PTE_64BIT=y
20CONFIG_PHYS_64BIT=y
21CONFIG_PPC_MMU_NOHASH=y
22CONFIG_PPC_MMU_NOHASH_32=y
23# CONFIG_PPC_MM_SLICES is not set
24CONFIG_NOT_COHERENT_CACHE=y
25CONFIG_PPC32=y
26CONFIG_WORD_SIZE=32
27CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
28CONFIG_MMU=y
29CONFIG_GENERIC_CMOS_UPDATE=y
30CONFIG_GENERIC_TIME=y
31CONFIG_GENERIC_TIME_VSYSCALL=y
32CONFIG_GENERIC_CLOCKEVENTS=y
33CONFIG_GENERIC_HARDIRQS=y
34CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
35# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
36# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
37CONFIG_IRQ_PER_CPU=y
38CONFIG_NR_IRQS=512
39CONFIG_STACKTRACE_SUPPORT=y
40CONFIG_HAVE_LATENCYTOP_SUPPORT=y
41CONFIG_TRACE_IRQFLAGS_SUPPORT=y
42CONFIG_LOCKDEP_SUPPORT=y
43CONFIG_RWSEM_XCHGADD_ALGORITHM=y
44CONFIG_ARCH_HAS_ILOG2_U32=y
45CONFIG_GENERIC_HWEIGHT=y
46CONFIG_GENERIC_FIND_NEXT_BIT=y
47# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
48CONFIG_PPC=y
49CONFIG_EARLY_PRINTK=y
50CONFIG_GENERIC_NVRAM=y
51CONFIG_SCHED_OMIT_FRAME_POINTER=y
52CONFIG_ARCH_MAY_HAVE_PC_FDC=y
53CONFIG_PPC_OF=y
54CONFIG_OF=y
55CONFIG_PPC_UDBG_16550=y
56# CONFIG_GENERIC_TBSYNC is not set
57CONFIG_AUDIT_ARCH=y
58CONFIG_GENERIC_BUG=y
59CONFIG_DTC=y
60# CONFIG_DEFAULT_UIMAGE is not set
61CONFIG_ARCH_HIBERNATION_POSSIBLE=y
62CONFIG_PPC_DCR_NATIVE=y
63# CONFIG_PPC_DCR_MMIO is not set
64CONFIG_PPC_DCR=y
65CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
66CONFIG_PPC_ADV_DEBUG_REGS=y
67CONFIG_PPC_ADV_DEBUG_IACS=4
68CONFIG_PPC_ADV_DEBUG_DACS=2
69CONFIG_PPC_ADV_DEBUG_DVCS=2
70CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
71CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
72CONFIG_CONSTRUCTORS=y
73
74#
75# General setup
76#
77CONFIG_EXPERIMENTAL=y
78CONFIG_BROKEN_ON_SMP=y
79CONFIG_INIT_ENV_ARG_LIMIT=32
80CONFIG_LOCALVERSION=""
81CONFIG_LOCALVERSION_AUTO=y
82CONFIG_SWAP=y
83CONFIG_SYSVIPC=y
84CONFIG_SYSVIPC_SYSCTL=y
85CONFIG_POSIX_MQUEUE=y
86CONFIG_POSIX_MQUEUE_SYSCTL=y
87# CONFIG_BSD_PROCESS_ACCT is not set
88# CONFIG_TASKSTATS is not set
89# CONFIG_AUDIT is not set
90
91#
92# RCU Subsystem
93#
94CONFIG_TREE_RCU=y
95# CONFIG_TREE_PREEMPT_RCU is not set
96# CONFIG_TINY_RCU is not set
97# CONFIG_RCU_TRACE is not set
98CONFIG_RCU_FANOUT=32
99# CONFIG_RCU_FANOUT_EXACT is not set
100# CONFIG_TREE_RCU_TRACE is not set
101# CONFIG_IKCONFIG is not set
102CONFIG_LOG_BUF_SHIFT=14
103# CONFIG_CGROUPS is not set
104CONFIG_SYSFS_DEPRECATED=y
105CONFIG_SYSFS_DEPRECATED_V2=y
106# CONFIG_RELAY is not set
107# CONFIG_NAMESPACES is not set
108CONFIG_BLK_DEV_INITRD=y
109CONFIG_INITRAMFS_SOURCE=""
110CONFIG_RD_GZIP=y
111# CONFIG_RD_BZIP2 is not set
112# CONFIG_RD_LZMA is not set
113# CONFIG_RD_LZO is not set
114# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
115CONFIG_SYSCTL=y
116CONFIG_ANON_INODES=y
117CONFIG_EMBEDDED=y
118CONFIG_SYSCTL_SYSCALL=y
119CONFIG_KALLSYMS=y
120# CONFIG_KALLSYMS_ALL is not set
121# CONFIG_KALLSYMS_EXTRA_PASS is not set
122CONFIG_HOTPLUG=y
123CONFIG_PRINTK=y
124# CONFIG_LOGBUFFER is not set
125CONFIG_BUG=y
126CONFIG_ELF_CORE=y
127CONFIG_BASE_FULL=y
128CONFIG_FUTEX=y
129CONFIG_EPOLL=y
130CONFIG_SIGNALFD=y
131CONFIG_TIMERFD=y
132CONFIG_EVENTFD=y
133CONFIG_SHMEM=y
134CONFIG_AIO=y
135CONFIG_HAVE_PERF_EVENTS=y
136
137#
138# Kernel Performance Events And Counters
139#
140# CONFIG_PERF_EVENTS is not set
141# CONFIG_PERF_COUNTERS is not set
142CONFIG_VM_EVENT_COUNTERS=y
143CONFIG_PCI_QUIRKS=y
144CONFIG_SLUB_DEBUG=y
145CONFIG_COMPAT_BRK=y
146# CONFIG_SLAB is not set
147CONFIG_SLUB=y
148# CONFIG_SLOB is not set
149# CONFIG_PROFILING is not set
150CONFIG_HAVE_OPROFILE=y
151# CONFIG_KPROBES is not set
152CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
153CONFIG_HAVE_IOREMAP_PROT=y
154CONFIG_HAVE_KPROBES=y
155CONFIG_HAVE_KRETPROBES=y
156CONFIG_HAVE_ARCH_TRACEHOOK=y
157CONFIG_HAVE_DMA_ATTRS=y
158CONFIG_HAVE_DMA_API_DEBUG=y
159
160#
161# GCOV-based kernel profiling
162#
163# CONFIG_SLOW_WORK is not set
164# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
165CONFIG_SLABINFO=y
166CONFIG_RT_MUTEXES=y
167CONFIG_BASE_SMALL=0
168CONFIG_MODULES=y
169# CONFIG_MODULE_FORCE_LOAD is not set
170CONFIG_MODULE_UNLOAD=y
171# CONFIG_MODULE_FORCE_UNLOAD is not set
172# CONFIG_MODVERSIONS is not set
173# CONFIG_MODULE_SRCVERSION_ALL is not set
174CONFIG_BLOCK=y
175CONFIG_LBDAF=y
176# CONFIG_BLK_DEV_BSG is not set
177# CONFIG_BLK_DEV_INTEGRITY is not set
178
179#
180# IO Schedulers
181#
182CONFIG_IOSCHED_NOOP=y
183CONFIG_IOSCHED_DEADLINE=y
184CONFIG_IOSCHED_CFQ=y
185# CONFIG_DEFAULT_DEADLINE is not set
186CONFIG_DEFAULT_CFQ=y
187# CONFIG_DEFAULT_NOOP is not set
188CONFIG_DEFAULT_IOSCHED="cfq"
189# CONFIG_INLINE_SPIN_TRYLOCK is not set
190# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
191# CONFIG_INLINE_SPIN_LOCK is not set
192# CONFIG_INLINE_SPIN_LOCK_BH is not set
193# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
194# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
195CONFIG_INLINE_SPIN_UNLOCK=y
196# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
197CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
198# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
199# CONFIG_INLINE_READ_TRYLOCK is not set
200# CONFIG_INLINE_READ_LOCK is not set
201# CONFIG_INLINE_READ_LOCK_BH is not set
202# CONFIG_INLINE_READ_LOCK_IRQ is not set
203# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
204CONFIG_INLINE_READ_UNLOCK=y
205# CONFIG_INLINE_READ_UNLOCK_BH is not set
206CONFIG_INLINE_READ_UNLOCK_IRQ=y
207# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
208# CONFIG_INLINE_WRITE_TRYLOCK is not set
209# CONFIG_INLINE_WRITE_LOCK is not set
210# CONFIG_INLINE_WRITE_LOCK_BH is not set
211# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
212# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
213CONFIG_INLINE_WRITE_UNLOCK=y
214# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
215CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
216# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
217# CONFIG_MUTEX_SPIN_ON_OWNER is not set
218# CONFIG_FREEZER is not set
219CONFIG_PPC4xx_PCI_EXPRESS=y
220
221#
222# Platform support
223#
224# CONFIG_PPC_CELL is not set
225# CONFIG_PPC_CELL_NATIVE is not set
226# CONFIG_PQ2ADS is not set
227# CONFIG_BAMBOO is not set
228# CONFIG_EBONY is not set
229# CONFIG_SAM440EP is not set
230# CONFIG_SEQUOIA is not set
231# CONFIG_TAISHAN is not set
232# CONFIG_KATMAI is not set
233# CONFIG_RAINIER is not set
234# CONFIG_WARP is not set
235# CONFIG_ARCHES is not set
236# CONFIG_CANYONLANDS is not set
237# CONFIG_GLACIER is not set
238# CONFIG_REDWOOD is not set
239# CONFIG_EIGER is not set
240# CONFIG_YOSEMITE is not set
241CONFIG_ICON=y
242# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
243CONFIG_PPC44x_SIMPLE=y
244# CONFIG_PPC4xx_GPIO is not set
245CONFIG_440SPe=y
246CONFIG_STDBINUTILS=y
247# CONFIG_IPIC is not set
248# CONFIG_MPIC is not set
249# CONFIG_MPIC_WEIRD is not set
250# CONFIG_PPC_I8259 is not set
251# CONFIG_PPC_RTAS is not set
252# CONFIG_MMIO_NVRAM is not set
253# CONFIG_PPC_MPC106 is not set
254# CONFIG_PPC_970_NAP is not set
255# CONFIG_PPC_INDIRECT_IO is not set
256# CONFIG_GENERIC_IOMAP is not set
257# CONFIG_CPU_FREQ is not set
258# CONFIG_FSL_ULI1575 is not set
259# CONFIG_SIMPLE_GPIO is not set
260
261#
262# Kernel options
263#
264CONFIG_HIGHMEM=y
265# CONFIG_NO_HZ is not set
266# CONFIG_HIGH_RES_TIMERS is not set
267CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
268# CONFIG_HZ_100 is not set
269CONFIG_HZ_250=y
270# CONFIG_HZ_300 is not set
271# CONFIG_HZ_1000 is not set
272CONFIG_HZ=250
273# CONFIG_SCHED_HRTICK is not set
274CONFIG_PREEMPT_NONE=y
275# CONFIG_PREEMPT_VOLUNTARY is not set
276# CONFIG_PREEMPT is not set
277CONFIG_BINFMT_ELF=y
278# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
279# CONFIG_HAVE_AOUT is not set
280# CONFIG_BINFMT_MISC is not set
281# CONFIG_MATH_EMULATION is not set
282# CONFIG_IOMMU_HELPER is not set
283# CONFIG_SWIOTLB is not set
284CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
285CONFIG_ARCH_HAS_WALK_MEMORY=y
286CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
287CONFIG_SPARSE_IRQ=y
288CONFIG_MAX_ACTIVE_REGIONS=32
289CONFIG_ARCH_FLATMEM_ENABLE=y
290CONFIG_ARCH_POPULATES_NODE_MAP=y
291CONFIG_SELECT_MEMORY_MODEL=y
292CONFIG_FLATMEM_MANUAL=y
293# CONFIG_DISCONTIGMEM_MANUAL is not set
294# CONFIG_SPARSEMEM_MANUAL is not set
295CONFIG_FLATMEM=y
296CONFIG_FLAT_NODE_MEM_MAP=y
297CONFIG_PAGEFLAGS_EXTENDED=y
298CONFIG_SPLIT_PTLOCK_CPUS=4
299CONFIG_MIGRATION=y
300CONFIG_PHYS_ADDR_T_64BIT=y
301CONFIG_ZONE_DMA_FLAG=1
302CONFIG_BOUNCE=y
303CONFIG_VIRT_TO_BUS=y
304# CONFIG_KSM is not set
305CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
306CONFIG_PPC_4K_PAGES=y
307# CONFIG_PPC_16K_PAGES is not set
308# CONFIG_PPC_64K_PAGES is not set
309# CONFIG_PPC_256K_PAGES is not set
310CONFIG_FORCE_MAX_ZONEORDER=11
311CONFIG_PROC_DEVICETREE=y
312CONFIG_CMDLINE_BOOL=y
313CONFIG_CMDLINE=""
314CONFIG_EXTRA_TARGETS=""
315# CONFIG_ARCH_HAS_NMI_WATCHDOG is not set
316CONFIG_SECCOMP=y
317CONFIG_ISA_DMA_API=y
318
319#
320# Bus options
321#
322CONFIG_ZONE_DMA=y
323CONFIG_NEED_DMA_MAP_STATE=y
324CONFIG_PPC_INDIRECT_PCI=y
325CONFIG_4xx_SOC=y
326CONFIG_PPC_PCI_CHOICE=y
327CONFIG_PCI=y
328CONFIG_PCI_DOMAINS=y
329CONFIG_PCI_SYSCALL=y
330CONFIG_PCIEPORTBUS=y
331CONFIG_PCIEAER=y
332# CONFIG_PCIE_ECRC is not set
333# CONFIG_PCIEAER_INJECT is not set
334# CONFIG_PCIEASPM is not set
335CONFIG_ARCH_SUPPORTS_MSI=y
336# CONFIG_PCI_MSI is not set
337# CONFIG_PCI_DEBUG is not set
338# CONFIG_PCI_STUB is not set
339# CONFIG_PCI_IOV is not set
340# CONFIG_PCCARD is not set
341# CONFIG_HOTPLUG_PCI is not set
342# CONFIG_HAS_RAPIDIO is not set
343
344#
345# Advanced setup
346#
347# CONFIG_ADVANCED_OPTIONS is not set
348
349#
350# Default settings for advanced configuration options are used
351#
352CONFIG_LOWMEM_SIZE=0x30000000
353CONFIG_PAGE_OFFSET=0xc0000000
354CONFIG_KERNEL_START=0xc0000000
355CONFIG_PHYSICAL_START=0x00000000
356CONFIG_TASK_SIZE=0xc0000000
357CONFIG_CONSISTENT_SIZE=0x00200000
358CONFIG_NET=y
359
360#
361# Networking options
362#
363CONFIG_PACKET=y
364CONFIG_UNIX=y
365# CONFIG_NET_KEY is not set
366CONFIG_INET=y
367# CONFIG_IP_MULTICAST is not set
368# CONFIG_IP_ADVANCED_ROUTER is not set
369CONFIG_IP_FIB_HASH=y
370CONFIG_IP_PNP=y
371CONFIG_IP_PNP_DHCP=y
372CONFIG_IP_PNP_BOOTP=y
373# CONFIG_IP_PNP_RARP is not set
374# CONFIG_NET_IPIP is not set
375# CONFIG_NET_IPGRE is not set
376# CONFIG_ARPD is not set
377# CONFIG_SYN_COOKIES is not set
378# CONFIG_INET_AH is not set
379# CONFIG_INET_ESP is not set
380# CONFIG_INET_IPCOMP is not set
381# CONFIG_INET_XFRM_TUNNEL is not set
382# CONFIG_INET_TUNNEL is not set
383# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
384# CONFIG_INET_XFRM_MODE_TUNNEL is not set
385# CONFIG_INET_XFRM_MODE_BEET is not set
386# CONFIG_INET_LRO is not set
387CONFIG_INET_DIAG=y
388CONFIG_INET_TCP_DIAG=y
389# CONFIG_TCP_CONG_ADVANCED is not set
390CONFIG_TCP_CONG_CUBIC=y
391CONFIG_DEFAULT_TCP_CONG="cubic"
392# CONFIG_TCP_MD5SIG is not set
393# CONFIG_IPV6 is not set
394# CONFIG_NETWORK_SECMARK is not set
395# CONFIG_NETFILTER is not set
396# CONFIG_IP_DCCP is not set
397# CONFIG_IP_SCTP is not set
398# CONFIG_RDS is not set
399# CONFIG_TIPC is not set
400# CONFIG_ATM is not set
401# CONFIG_BRIDGE is not set
402# CONFIG_NET_DSA is not set
403# CONFIG_VLAN_8021Q is not set
404# CONFIG_DECNET is not set
405# CONFIG_LLC2 is not set
406# CONFIG_IPX is not set
407# CONFIG_ATALK is not set
408# CONFIG_X25 is not set
409# CONFIG_LAPB is not set
410# CONFIG_ECONET is not set
411# CONFIG_WAN_ROUTER is not set
412# CONFIG_PHONET is not set
413# CONFIG_IEEE802154 is not set
414# CONFIG_NET_SCHED is not set
415# CONFIG_DCB is not set
416
417#
418# Network testing
419#
420# CONFIG_NET_PKTGEN is not set
421# CONFIG_HAMRADIO is not set
422# CONFIG_CAN is not set
423# CONFIG_IRDA is not set
424# CONFIG_BT is not set
425# CONFIG_AF_RXRPC is not set
426CONFIG_WIRELESS=y
427# CONFIG_CFG80211 is not set
428# CONFIG_LIB80211 is not set
429
430#
431# CFG80211 needs to be enabled for MAC80211
432#
433# CONFIG_WIMAX is not set
434# CONFIG_RFKILL is not set
435# CONFIG_NET_9P is not set
436
437#
438# Device Drivers
439#
440
441#
442# Generic Driver Options
443#
444CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
445# CONFIG_DEVTMPFS is not set
446CONFIG_STANDALONE=y
447CONFIG_PREVENT_FIRMWARE_BUILD=y
448CONFIG_FW_LOADER=y
449CONFIG_FIRMWARE_IN_KERNEL=y
450CONFIG_EXTRA_FIRMWARE=""
451# CONFIG_DEBUG_DRIVER is not set
452# CONFIG_DEBUG_DEVRES is not set
453# CONFIG_SYS_HYPERVISOR is not set
454CONFIG_CONNECTOR=y
455CONFIG_PROC_EVENTS=y
456CONFIG_MTD=y
457# CONFIG_MTD_DEBUG is not set
458# CONFIG_MTD_TESTS is not set
459# CONFIG_MTD_CONCAT is not set
460CONFIG_MTD_PARTITIONS=y
461# CONFIG_MTD_REDBOOT_PARTS is not set
462CONFIG_MTD_CMDLINE_PARTS=y
463CONFIG_MTD_OF_PARTS=y
464# CONFIG_MTD_AR7_PARTS is not set
465
466#
467# User Modules And Translation Layers
468#
469CONFIG_MTD_CHAR=y
470CONFIG_MTD_BLKDEVS=y
471CONFIG_MTD_BLOCK=y
472# CONFIG_FTL is not set
473# CONFIG_NFTL is not set
474# CONFIG_INFTL is not set
475# CONFIG_RFD_FTL is not set
476# CONFIG_SSFDC is not set
477# CONFIG_MTD_OOPS is not set
478
479#
480# RAM/ROM/Flash chip drivers
481#
482CONFIG_MTD_CFI=y
483# CONFIG_MTD_JEDECPROBE is not set
484CONFIG_MTD_GEN_PROBE=y
485# CONFIG_MTD_CFI_ADV_OPTIONS is not set
486CONFIG_MTD_MAP_BANK_WIDTH_1=y
487CONFIG_MTD_MAP_BANK_WIDTH_2=y
488CONFIG_MTD_MAP_BANK_WIDTH_4=y
489# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
490# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
491# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
492CONFIG_MTD_CFI_I1=y
493CONFIG_MTD_CFI_I2=y
494# CONFIG_MTD_CFI_I4 is not set
495# CONFIG_MTD_CFI_I8 is not set
496# CONFIG_MTD_CFI_INTELEXT is not set
497CONFIG_MTD_CFI_AMDSTD=y
498# CONFIG_MTD_CFI_STAA is not set
499CONFIG_MTD_CFI_UTIL=y
500# CONFIG_MTD_RAM is not set
501# CONFIG_MTD_ROM is not set
502# CONFIG_MTD_ABSENT is not set
503
504#
505# Mapping drivers for chip access
506#
507# CONFIG_MTD_COMPLEX_MAPPINGS is not set
508# CONFIG_MTD_PHYSMAP is not set
509CONFIG_MTD_PHYSMAP_OF=y
510# CONFIG_MTD_INTEL_VR_NOR is not set
511# CONFIG_MTD_PLATRAM is not set
512
513#
514# Self-contained MTD device drivers
515#
516# CONFIG_MTD_PMC551 is not set
517# CONFIG_MTD_SLRAM is not set
518# CONFIG_MTD_PHRAM is not set
519# CONFIG_MTD_MTDRAM is not set
520# CONFIG_MTD_BLOCK2MTD is not set
521
522#
523# Disk-On-Chip Device Drivers
524#
525# CONFIG_MTD_DOC2000 is not set
526# CONFIG_MTD_DOC2001 is not set
527# CONFIG_MTD_DOC2001PLUS is not set
528# CONFIG_MTD_NAND is not set
529# CONFIG_MTD_ONENAND is not set
530
531#
532# LPDDR flash memory drivers
533#
534# CONFIG_MTD_LPDDR is not set
535
536#
537# UBI - Unsorted block images
538#
539# CONFIG_MTD_UBI is not set
540CONFIG_OF_FLATTREE=y
541CONFIG_OF_DYNAMIC=y
542CONFIG_OF_DEVICE=y
543CONFIG_OF_I2C=y
544# CONFIG_PARPORT is not set
545CONFIG_BLK_DEV=y
546# CONFIG_BLK_DEV_FD is not set
547# CONFIG_BLK_CPQ_DA is not set
548# CONFIG_BLK_CPQ_CISS_DA is not set
549# CONFIG_BLK_DEV_DAC960 is not set
550# CONFIG_BLK_DEV_UMEM is not set
551# CONFIG_BLK_DEV_COW_COMMON is not set
552# CONFIG_BLK_DEV_LOOP is not set
553# CONFIG_BLK_DEV_DRBD is not set
554# CONFIG_BLK_DEV_NBD is not set
555# CONFIG_BLK_DEV_SX8 is not set
556CONFIG_BLK_DEV_RAM=y
557CONFIG_BLK_DEV_RAM_COUNT=16
558CONFIG_BLK_DEV_RAM_SIZE=35000
559# CONFIG_BLK_DEV_XIP is not set
560# CONFIG_CDROM_PKTCDVD is not set
561# CONFIG_ATA_OVER_ETH is not set
562CONFIG_XILINX_SYSACE=y
563# CONFIG_BLK_DEV_HD is not set
564# CONFIG_MISC_DEVICES is not set
565CONFIG_HAVE_IDE=y
566# CONFIG_IDE is not set
567
568#
569# SCSI device support
570#
571CONFIG_SCSI_MOD=y
572# CONFIG_RAID_ATTRS is not set
573CONFIG_SCSI=y
574CONFIG_SCSI_DMA=y
575# CONFIG_SCSI_TGT is not set
576# CONFIG_SCSI_NETLINK is not set
577CONFIG_SCSI_PROC_FS=y
578
579#
580# SCSI support type (disk, tape, CD-ROM)
581#
582CONFIG_BLK_DEV_SD=y
583# CONFIG_CHR_DEV_ST is not set
584# CONFIG_CHR_DEV_OSST is not set
585# CONFIG_BLK_DEV_SR is not set
586# CONFIG_CHR_DEV_SG is not set
587# CONFIG_CHR_DEV_SCH is not set
588# CONFIG_SCSI_MULTI_LUN is not set
589CONFIG_SCSI_CONSTANTS=y
590CONFIG_SCSI_LOGGING=y
591# CONFIG_SCSI_SCAN_ASYNC is not set
592CONFIG_SCSI_WAIT_SCAN=m
593
594#
595# SCSI Transports
596#
597# CONFIG_SCSI_SPI_ATTRS is not set
598# CONFIG_SCSI_FC_ATTRS is not set
599# CONFIG_SCSI_ISCSI_ATTRS is not set
600CONFIG_SCSI_SAS_ATTRS=y
601# CONFIG_SCSI_SAS_LIBSAS is not set
602# CONFIG_SCSI_SRP_ATTRS is not set
603# CONFIG_SCSI_LOWLEVEL is not set
604# CONFIG_SCSI_DH is not set
605# CONFIG_SCSI_OSD_INITIATOR is not set
606# CONFIG_ATA is not set
607# CONFIG_MD is not set
608CONFIG_FUSION=y
609# CONFIG_FUSION_SPI is not set
610# CONFIG_FUSION_FC is not set
611CONFIG_FUSION_SAS=y
612CONFIG_FUSION_MAX_SGE=128
613CONFIG_FUSION_CTL=y
614CONFIG_FUSION_LOGGING=y
615
616#
617# IEEE 1394 (FireWire) support
618#
619
620#
621# You can enable one or both FireWire driver stacks.
622#
623
624#
625# The newer stack is recommended.
626#
627# CONFIG_FIREWIRE is not set
628# CONFIG_IEEE1394 is not set
629# CONFIG_I2O is not set
630# CONFIG_MACINTOSH_DRIVERS is not set
631CONFIG_NETDEVICES=y
632# CONFIG_DUMMY is not set
633# CONFIG_BONDING is not set
634# CONFIG_MACVLAN is not set
635# CONFIG_EQUALIZER is not set
636# CONFIG_TUN is not set
637# CONFIG_VETH is not set
638# CONFIG_ARCNET is not set
639# CONFIG_PHYLIB is not set
640CONFIG_NET_ETHERNET=y
641# CONFIG_MII is not set
642# CONFIG_HAPPYMEAL is not set
643# CONFIG_SUNGEM is not set
644# CONFIG_CASSINI is not set
645# CONFIG_NET_VENDOR_3COM is not set
646# CONFIG_ETHOC is not set
647# CONFIG_DNET is not set
648# CONFIG_NET_TULIP is not set
649# CONFIG_HP100 is not set
650CONFIG_IBM_NEW_EMAC=y
651CONFIG_IBM_NEW_EMAC_RXB=128
652CONFIG_IBM_NEW_EMAC_TXB=64
653CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
654CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
655CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
656# CONFIG_IBM_NEW_EMAC_DEBUG is not set
657# CONFIG_IBM_NEW_EMAC_ZMII is not set
658# CONFIG_IBM_NEW_EMAC_RGMII is not set
659# CONFIG_IBM_NEW_EMAC_TAH is not set
660CONFIG_IBM_NEW_EMAC_EMAC4=y
661# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
662# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
663# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
664# CONFIG_NET_PCI is not set
665# CONFIG_B44 is not set
666# CONFIG_KS8842 is not set
667# CONFIG_KS8851_MLL is not set
668# CONFIG_ATL2 is not set
669# CONFIG_XILINX_EMACLITE is not set
670# CONFIG_NETDEV_1000 is not set
671# CONFIG_NETDEV_10000 is not set
672# CONFIG_TR is not set
673# CONFIG_WLAN is not set
674
675#
676# Enable WiMAX (Networking options) to see the WiMAX drivers
677#
678# CONFIG_WAN is not set
679# CONFIG_FDDI is not set
680# CONFIG_HIPPI is not set
681# CONFIG_PPP is not set
682# CONFIG_SLIP is not set
683# CONFIG_NET_FC is not set
684# CONFIG_NETCONSOLE is not set
685# CONFIG_NETPOLL is not set
686# CONFIG_NET_POLL_CONTROLLER is not set
687# CONFIG_VMXNET3 is not set
688# CONFIG_ISDN is not set
689# CONFIG_PHONE is not set
690
691#
692# Input device support
693#
694CONFIG_INPUT=y
695# CONFIG_INPUT_FF_MEMLESS is not set
696# CONFIG_INPUT_POLLDEV is not set
697# CONFIG_INPUT_SPARSEKMAP is not set
698
699#
700# Userland interfaces
701#
702CONFIG_INPUT_MOUSEDEV=y
703CONFIG_INPUT_MOUSEDEV_PSAUX=y
704CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
705CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
706# CONFIG_INPUT_JOYDEV is not set
707# CONFIG_INPUT_EVDEV is not set
708# CONFIG_INPUT_EVBUG is not set
709
710#
711# Input Device Drivers
712#
713CONFIG_INPUT_KEYBOARD=y
714# CONFIG_KEYBOARD_ADP5588 is not set
715CONFIG_KEYBOARD_ATKBD=y
716# CONFIG_QT2160 is not set
717# CONFIG_KEYBOARD_LKKBD is not set
718# CONFIG_KEYBOARD_MAX7359 is not set
719# CONFIG_KEYBOARD_NEWTON is not set
720# CONFIG_KEYBOARD_OPENCORES is not set
721# CONFIG_KEYBOARD_STOWAWAY is not set
722# CONFIG_KEYBOARD_SUNKBD is not set
723# CONFIG_KEYBOARD_XTKBD is not set
724CONFIG_INPUT_MOUSE=y
725CONFIG_MOUSE_PS2=y
726# CONFIG_MOUSE_PS2_ALPS is not set
727# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
728# CONFIG_MOUSE_PS2_SYNAPTICS is not set
729# CONFIG_MOUSE_PS2_TRACKPOINT is not set
730# CONFIG_MOUSE_PS2_ELANTECH is not set
731# CONFIG_MOUSE_PS2_SENTELIC is not set
732# CONFIG_MOUSE_PS2_TOUCHKIT is not set
733# CONFIG_MOUSE_SERIAL is not set
734# CONFIG_MOUSE_VSXXXAA is not set
735# CONFIG_MOUSE_SYNAPTICS_I2C is not set
736# CONFIG_INPUT_JOYSTICK is not set
737# CONFIG_INPUT_TABLET is not set
738# CONFIG_INPUT_TOUCHSCREEN is not set
739# CONFIG_INPUT_MISC is not set
740
741#
742# Hardware I/O ports
743#
744CONFIG_SERIO=y
745CONFIG_SERIO_I8042=y
746CONFIG_SERIO_SERPORT=y
747# CONFIG_SERIO_PCIPS2 is not set
748CONFIG_SERIO_LIBPS2=y
749# CONFIG_SERIO_RAW is not set
750# CONFIG_SERIO_XILINX_XPS_PS2 is not set
751# CONFIG_SERIO_ALTERA_PS2 is not set
752# CONFIG_GAMEPORT is not set
753
754#
755# Character devices
756#
757CONFIG_VT=y
758CONFIG_CONSOLE_TRANSLATIONS=y
759CONFIG_VT_CONSOLE=y
760CONFIG_HW_CONSOLE=y
761# CONFIG_VT_HW_CONSOLE_BINDING is not set
762CONFIG_DEVKMEM=y
763# CONFIG_SERIAL_NONSTANDARD is not set
764# CONFIG_NOZOMI is not set
765
766#
767# Serial drivers
768#
769CONFIG_SERIAL_8250=y
770CONFIG_SERIAL_8250_CONSOLE=y
771# CONFIG_SERIAL_8250_PCI is not set
772CONFIG_SERIAL_8250_NR_UARTS=4
773CONFIG_SERIAL_8250_RUNTIME_UARTS=4
774CONFIG_SERIAL_8250_EXTENDED=y
775# CONFIG_SERIAL_8250_MANY_PORTS is not set
776CONFIG_SERIAL_8250_SHARE_IRQ=y
777# CONFIG_SERIAL_8250_DETECT_IRQ is not set
778# CONFIG_SERIAL_8250_RSA is not set
779
780#
781# Non-8250 serial port support
782#
783# CONFIG_SERIAL_UARTLITE is not set
784CONFIG_SERIAL_CORE=y
785CONFIG_SERIAL_CORE_CONSOLE=y
786# CONFIG_SERIAL_JSM is not set
787CONFIG_SERIAL_OF_PLATFORM=y
788# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
789# CONFIG_SERIAL_TIMBERDALE is not set
790# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
791CONFIG_UNIX98_PTYS=y
792# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
793CONFIG_LEGACY_PTYS=y
794CONFIG_LEGACY_PTY_COUNT=256
795# CONFIG_HVC_UDBG is not set
796# CONFIG_IPMI_HANDLER is not set
797# CONFIG_HW_RANDOM is not set
798# CONFIG_NVRAM is not set
799# CONFIG_R3964 is not set
800# CONFIG_APPLICOM is not set
801# CONFIG_RAW_DRIVER is not set
802# CONFIG_BOOTCOUNT is not set
803# CONFIG_DISPLAY_PDSP1880 is not set
804# CONFIG_MUCMC52_IO is not set
805# CONFIG_UC101_IO is not set
806# CONFIG_SRAM is not set
807# CONFIG_TCG_TPM is not set
808CONFIG_DEVPORT=y
809CONFIG_I2C=y
810CONFIG_I2C_BOARDINFO=y
811CONFIG_I2C_COMPAT=y
812CONFIG_I2C_CHARDEV=y
813CONFIG_I2C_HELPER_AUTO=y
814
815#
816# I2C Hardware Bus support
817#
818
819#
820# PC SMBus host controller drivers
821#
822# CONFIG_I2C_ALI1535 is not set
823# CONFIG_I2C_ALI1563 is not set
824# CONFIG_I2C_ALI15X3 is not set
825# CONFIG_I2C_AMD756 is not set
826# CONFIG_I2C_AMD8111 is not set
827# CONFIG_I2C_I801 is not set
828# CONFIG_I2C_ISCH is not set
829# CONFIG_I2C_PIIX4 is not set
830# CONFIG_I2C_NFORCE2 is not set
831# CONFIG_I2C_SIS5595 is not set
832# CONFIG_I2C_SIS630 is not set
833# CONFIG_I2C_SIS96X is not set
834# CONFIG_I2C_VIA is not set
835# CONFIG_I2C_VIAPRO is not set
836
837#
838# I2C system bus drivers (mostly embedded / system-on-chip)
839#
840CONFIG_I2C_IBM_IIC=y
841# CONFIG_I2C_MPC is not set
842# CONFIG_I2C_OCORES is not set
843# CONFIG_I2C_SIMTEC is not set
844# CONFIG_I2C_XILINX is not set
845
846#
847# External I2C/SMBus adapter drivers
848#
849# CONFIG_I2C_PARPORT_LIGHT is not set
850# CONFIG_I2C_TAOS_EVM is not set
851
852#
853# Other I2C/SMBus bus drivers
854#
855# CONFIG_I2C_PCA_PLATFORM is not set
856# CONFIG_I2C_STUB is not set
857# CONFIG_I2C_DEBUG_CORE is not set
858# CONFIG_I2C_DEBUG_ALGO is not set
859# CONFIG_I2C_DEBUG_BUS is not set
860# CONFIG_SPI is not set
861
862#
863# PPS support
864#
865# CONFIG_PPS is not set
866CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
867# CONFIG_GPIOLIB is not set
868# CONFIG_W1 is not set
869# CONFIG_POWER_SUPPLY is not set
870# CONFIG_HWMON is not set
871# CONFIG_THERMAL is not set
872# CONFIG_WATCHDOG is not set
873CONFIG_SSB_POSSIBLE=y
874
875#
876# Sonics Silicon Backplane
877#
878# CONFIG_SSB is not set
879
880#
881# Multifunction device drivers
882#
883# CONFIG_MFD_CORE is not set
884# CONFIG_MFD_88PM860X is not set
885CONFIG_MFD_SM501=y
886# CONFIG_HTC_PASIC3 is not set
887# CONFIG_TWL4030_CORE is not set
888# CONFIG_MFD_TMIO is not set
889# CONFIG_PMIC_DA903X is not set
890# CONFIG_PMIC_ADP5520 is not set
891# CONFIG_MFD_MAX8925 is not set
892# CONFIG_MFD_WM8400 is not set
893# CONFIG_MFD_WM831X is not set
894# CONFIG_MFD_WM8350_I2C is not set
895# CONFIG_MFD_WM8994 is not set
896# CONFIG_MFD_PCF50633 is not set
897# CONFIG_AB3100_CORE is not set
898# CONFIG_LPC_SCH is not set
899# CONFIG_REGULATOR is not set
900# CONFIG_MEDIA_SUPPORT is not set
901
902#
903# Graphics support
904#
905# CONFIG_AGP is not set
906CONFIG_VGA_ARB=y
907CONFIG_VGA_ARB_MAX_GPUS=16
908# CONFIG_DRM is not set
909# CONFIG_VGASTATE is not set
910CONFIG_VIDEO_OUTPUT_CONTROL=m
911CONFIG_FB=y
912# CONFIG_FIRMWARE_EDID is not set
913# CONFIG_FB_DDC is not set
914# CONFIG_FB_BOOT_VESA_SUPPORT is not set
915CONFIG_FB_CFB_FILLRECT=y
916CONFIG_FB_CFB_COPYAREA=y
917CONFIG_FB_CFB_IMAGEBLIT=y
918# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
919# CONFIG_FB_SYS_FILLRECT is not set
920# CONFIG_FB_SYS_COPYAREA is not set
921# CONFIG_FB_SYS_IMAGEBLIT is not set
922# CONFIG_FB_FOREIGN_ENDIAN is not set
923# CONFIG_FB_SYS_FOPS is not set
924# CONFIG_FB_SVGALIB is not set
925# CONFIG_FB_MACMODES is not set
926# CONFIG_FB_BACKLIGHT is not set
927# CONFIG_FB_MODE_HELPERS is not set
928# CONFIG_FB_TILEBLITTING is not set
929
930#
931# Frame buffer hardware drivers
932#
933# CONFIG_FB_CIRRUS is not set
934# CONFIG_FB_PM2 is not set
935# CONFIG_FB_CYBER2000 is not set
936# CONFIG_FB_OF is not set
937# CONFIG_FB_CT65550 is not set
938# CONFIG_FB_ASILIANT is not set
939# CONFIG_FB_IMSTT is not set
940# CONFIG_FB_VGA16 is not set
941# CONFIG_FB_UVESA is not set
942# CONFIG_FB_S1D13XXX is not set
943# CONFIG_FB_NVIDIA is not set
944# CONFIG_FB_RIVA is not set
945# CONFIG_FB_MATROX is not set
946# CONFIG_FB_RADEON is not set
947# CONFIG_FB_ATY128 is not set
948# CONFIG_FB_ATY is not set
949# CONFIG_FB_S3 is not set
950# CONFIG_FB_SAVAGE is not set
951# CONFIG_FB_SIS is not set
952# CONFIG_FB_VIA is not set
953# CONFIG_FB_NEOMAGIC is not set
954# CONFIG_FB_KYRO is not set
955# CONFIG_FB_3DFX is not set
956# CONFIG_FB_VOODOO1 is not set
957# CONFIG_FB_VT8623 is not set
958# CONFIG_FB_TRIDENT is not set
959# CONFIG_FB_ARK is not set
960# CONFIG_FB_PM3 is not set
961# CONFIG_FB_CARMINE is not set
962CONFIG_FB_SM501=y
963# CONFIG_FB_IBM_GXT4500 is not set
964# CONFIG_FB_VIRTUAL is not set
965# CONFIG_FB_METRONOME is not set
966# CONFIG_FB_MB862XX is not set
967# CONFIG_FB_BROADSHEET is not set
968# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
969
970#
971# Display device support
972#
973# CONFIG_DISPLAY_SUPPORT is not set
974
975#
976# Console display driver support
977#
978CONFIG_DUMMY_CONSOLE=y
979CONFIG_FRAMEBUFFER_CONSOLE=y
980# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
981# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
982# CONFIG_FONTS is not set
983CONFIG_FONT_8x8=y
984CONFIG_FONT_8x16=y
985CONFIG_LOGO=y
986# CONFIG_LOGO_LINUX_MONO is not set
987# CONFIG_LOGO_LINUX_VGA16 is not set
988CONFIG_LOGO_LINUX_CLUT224=y
989# CONFIG_SOUND is not set
990CONFIG_HID_SUPPORT=y
991CONFIG_HID=y
992# CONFIG_HIDRAW is not set
993# CONFIG_HID_PID is not set
994
995#
996# Special HID drivers
997#
998# CONFIG_USB_SUPPORT is not set
999# CONFIG_UWB is not set
1000# CONFIG_MMC is not set
1001# CONFIG_MEMSTICK is not set
1002# CONFIG_NEW_LEDS is not set
1003# CONFIG_ACCESSIBILITY is not set
1004# CONFIG_INFINIBAND is not set
1005# CONFIG_EDAC is not set
1006CONFIG_RTC_LIB=y
1007CONFIG_RTC_CLASS=y
1008CONFIG_RTC_HCTOSYS=y
1009CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1010# CONFIG_RTC_DEBUG is not set
1011
1012#
1013# RTC interfaces
1014#
1015CONFIG_RTC_INTF_SYSFS=y
1016CONFIG_RTC_INTF_PROC=y
1017CONFIG_RTC_INTF_DEV=y
1018# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1019# CONFIG_RTC_DRV_TEST is not set
1020
1021#
1022# I2C RTC drivers
1023#
1024CONFIG_RTC_DRV_DS1307=y
1025# CONFIG_RTC_DRV_DS1374 is not set
1026# CONFIG_RTC_DRV_DS1672 is not set
1027# CONFIG_RTC_DRV_MAX6900 is not set
1028# CONFIG_RTC_DRV_RS5C372 is not set
1029# CONFIG_RTC_DRV_ISL1208 is not set
1030# CONFIG_RTC_DRV_X1205 is not set
1031# CONFIG_RTC_DRV_PCF8563 is not set
1032# CONFIG_RTC_DRV_PCF8583 is not set
1033# CONFIG_RTC_DRV_M41T80 is not set
1034# CONFIG_RTC_DRV_BQ32K is not set
1035# CONFIG_RTC_DRV_S35390A is not set
1036# CONFIG_RTC_DRV_FM3130 is not set
1037# CONFIG_RTC_DRV_RX8581 is not set
1038# CONFIG_RTC_DRV_RX8025 is not set
1039
1040#
1041# SPI RTC drivers
1042#
1043
1044#
1045# Platform RTC drivers
1046#
1047# CONFIG_RTC_DRV_CMOS is not set
1048# CONFIG_RTC_DRV_DS1286 is not set
1049# CONFIG_RTC_DRV_DS1511 is not set
1050# CONFIG_RTC_DRV_DS1553 is not set
1051# CONFIG_RTC_DRV_DS1742 is not set
1052# CONFIG_RTC_DRV_STK17TA8 is not set
1053# CONFIG_RTC_DRV_M48T86 is not set
1054# CONFIG_RTC_DRV_M48T35 is not set
1055# CONFIG_RTC_DRV_M48T59 is not set
1056# CONFIG_RTC_DRV_MSM6242 is not set
1057# CONFIG_RTC_DRV_BQ4802 is not set
1058# CONFIG_RTC_DRV_RP5C01 is not set
1059# CONFIG_RTC_DRV_V3020 is not set
1060
1061#
1062# on-CPU RTC drivers
1063#
1064# CONFIG_RTC_DRV_GENERIC is not set
1065# CONFIG_DMADEVICES is not set
1066# CONFIG_AUXDISPLAY is not set
1067# CONFIG_UIO is not set
1068
1069#
1070# TI VLYNQ
1071#
1072# CONFIG_STAGING is not set
1073
1074#
1075# File systems
1076#
1077CONFIG_EXT2_FS=y
1078# CONFIG_EXT2_FS_XATTR is not set
1079# CONFIG_EXT2_FS_XIP is not set
1080CONFIG_EXT3_FS=y
1081# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
1082CONFIG_EXT3_FS_XATTR=y
1083# CONFIG_EXT3_FS_POSIX_ACL is not set
1084# CONFIG_EXT3_FS_SECURITY is not set
1085# CONFIG_EXT4_FS is not set
1086CONFIG_JBD=y
1087CONFIG_FS_MBCACHE=y
1088# CONFIG_REISERFS_FS is not set
1089# CONFIG_JFS_FS is not set
1090# CONFIG_FS_POSIX_ACL is not set
1091# CONFIG_XFS_FS is not set
1092# CONFIG_GFS2_FS is not set
1093# CONFIG_OCFS2_FS is not set
1094# CONFIG_BTRFS_FS is not set
1095# CONFIG_NILFS2_FS is not set
1096CONFIG_FILE_LOCKING=y
1097CONFIG_FSNOTIFY=y
1098CONFIG_DNOTIFY=y
1099CONFIG_INOTIFY=y
1100CONFIG_INOTIFY_USER=y
1101# CONFIG_QUOTA is not set
1102# CONFIG_AUTOFS_FS is not set
1103# CONFIG_AUTOFS4_FS is not set
1104# CONFIG_FUSE_FS is not set
1105
1106#
1107# Caches
1108#
1109# CONFIG_FSCACHE is not set
1110
1111#
1112# CD-ROM/DVD Filesystems
1113#
1114# CONFIG_ISO9660_FS is not set
1115# CONFIG_UDF_FS is not set
1116
1117#
1118# DOS/FAT/NT Filesystems
1119#
1120CONFIG_FAT_FS=y
1121# CONFIG_MSDOS_FS is not set
1122CONFIG_VFAT_FS=y
1123CONFIG_FAT_DEFAULT_CODEPAGE=437
1124CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1125# CONFIG_NTFS_FS is not set
1126
1127#
1128# Pseudo filesystems
1129#
1130CONFIG_PROC_FS=y
1131CONFIG_PROC_KCORE=y
1132CONFIG_PROC_SYSCTL=y
1133CONFIG_PROC_PAGE_MONITOR=y
1134CONFIG_SYSFS=y
1135CONFIG_TMPFS=y
1136# CONFIG_TMPFS_POSIX_ACL is not set
1137# CONFIG_HUGETLB_PAGE is not set
1138# CONFIG_CONFIGFS_FS is not set
1139CONFIG_MISC_FILESYSTEMS=y
1140# CONFIG_ADFS_FS is not set
1141# CONFIG_AFFS_FS is not set
1142# CONFIG_HFS_FS is not set
1143# CONFIG_HFSPLUS_FS is not set
1144# CONFIG_BEFS_FS is not set
1145# CONFIG_BFS_FS is not set
1146# CONFIG_EFS_FS is not set
1147# CONFIG_JFFS2_FS is not set
1148# CONFIG_YAFFS_FS is not set
1149# CONFIG_LOGFS is not set
1150CONFIG_CRAMFS=y
1151# CONFIG_SQUASHFS is not set
1152# CONFIG_VXFS_FS is not set
1153# CONFIG_MINIX_FS is not set
1154# CONFIG_OMFS_FS is not set
1155# CONFIG_HPFS_FS is not set
1156# CONFIG_QNX4FS_FS is not set
1157# CONFIG_ROMFS_FS is not set
1158# CONFIG_SYSV_FS is not set
1159# CONFIG_UFS_FS is not set
1160CONFIG_NETWORK_FILESYSTEMS=y
1161CONFIG_NFS_FS=y
1162CONFIG_NFS_V3=y
1163# CONFIG_NFS_V3_ACL is not set
1164# CONFIG_NFS_V4 is not set
1165CONFIG_ROOT_NFS=y
1166# CONFIG_NFSD is not set
1167CONFIG_LOCKD=y
1168CONFIG_LOCKD_V4=y
1169CONFIG_NFS_COMMON=y
1170CONFIG_SUNRPC=y
1171# CONFIG_RPCSEC_GSS_KRB5 is not set
1172# CONFIG_RPCSEC_GSS_SPKM3 is not set
1173# CONFIG_SMB_FS is not set
1174# CONFIG_CEPH_FS is not set
1175# CONFIG_CIFS is not set
1176# CONFIG_NCP_FS is not set
1177# CONFIG_CODA_FS is not set
1178# CONFIG_AFS_FS is not set
1179
1180#
1181# Partition Types
1182#
1183# CONFIG_PARTITION_ADVANCED is not set
1184CONFIG_MSDOS_PARTITION=y
1185CONFIG_NLS=y
1186CONFIG_NLS_DEFAULT="iso8859-1"
1187CONFIG_NLS_CODEPAGE_437=y
1188# CONFIG_NLS_CODEPAGE_737 is not set
1189# CONFIG_NLS_CODEPAGE_775 is not set
1190CONFIG_NLS_CODEPAGE_850=y
1191# CONFIG_NLS_CODEPAGE_852 is not set
1192# CONFIG_NLS_CODEPAGE_855 is not set
1193# CONFIG_NLS_CODEPAGE_857 is not set
1194# CONFIG_NLS_CODEPAGE_860 is not set
1195# CONFIG_NLS_CODEPAGE_861 is not set
1196# CONFIG_NLS_CODEPAGE_862 is not set
1197# CONFIG_NLS_CODEPAGE_863 is not set
1198# CONFIG_NLS_CODEPAGE_864 is not set
1199# CONFIG_NLS_CODEPAGE_865 is not set
1200# CONFIG_NLS_CODEPAGE_866 is not set
1201# CONFIG_NLS_CODEPAGE_869 is not set
1202# CONFIG_NLS_CODEPAGE_936 is not set
1203# CONFIG_NLS_CODEPAGE_950 is not set
1204# CONFIG_NLS_CODEPAGE_932 is not set
1205# CONFIG_NLS_CODEPAGE_949 is not set
1206# CONFIG_NLS_CODEPAGE_874 is not set
1207# CONFIG_NLS_ISO8859_8 is not set
1208# CONFIG_NLS_CODEPAGE_1250 is not set
1209# CONFIG_NLS_CODEPAGE_1251 is not set
1210# CONFIG_NLS_ASCII is not set
1211CONFIG_NLS_ISO8859_1=y
1212# CONFIG_NLS_ISO8859_2 is not set
1213# CONFIG_NLS_ISO8859_3 is not set
1214# CONFIG_NLS_ISO8859_4 is not set
1215# CONFIG_NLS_ISO8859_5 is not set
1216# CONFIG_NLS_ISO8859_6 is not set
1217# CONFIG_NLS_ISO8859_7 is not set
1218# CONFIG_NLS_ISO8859_9 is not set
1219# CONFIG_NLS_ISO8859_13 is not set
1220# CONFIG_NLS_ISO8859_14 is not set
1221CONFIG_NLS_ISO8859_15=y
1222# CONFIG_NLS_KOI8_R is not set
1223# CONFIG_NLS_KOI8_U is not set
1224# CONFIG_NLS_UTF8 is not set
1225# CONFIG_DLM is not set
1226# CONFIG_BINARY_PRINTF is not set
1227
1228#
1229# Library routines
1230#
1231CONFIG_BITREVERSE=y
1232CONFIG_GENERIC_FIND_LAST_BIT=y
1233# CONFIG_CRC_CCITT is not set
1234# CONFIG_CRC16 is not set
1235# CONFIG_CRC_T10DIF is not set
1236# CONFIG_CRC_ITU_T is not set
1237CONFIG_CRC32=y
1238# CONFIG_CRC7 is not set
1239# CONFIG_LIBCRC32C is not set
1240CONFIG_ZLIB_INFLATE=y
1241CONFIG_DECOMPRESS_GZIP=y
1242CONFIG_HAS_IOMEM=y
1243CONFIG_HAS_IOPORT=y
1244CONFIG_HAS_DMA=y
1245CONFIG_HAVE_LMB=y
1246CONFIG_NLATTR=y
1247CONFIG_GENERIC_ATOMIC64=y
1248
1249#
1250# Kernel hacking
1251#
1252# CONFIG_PRINTK_TIME is not set
1253CONFIG_ENABLE_WARN_DEPRECATED=y
1254CONFIG_ENABLE_MUST_CHECK=y
1255CONFIG_FRAME_WARN=1024
1256CONFIG_MAGIC_SYSRQ=y
1257# CONFIG_STRIP_ASM_SYMS is not set
1258# CONFIG_UNUSED_SYMBOLS is not set
1259# CONFIG_DEBUG_FS is not set
1260# CONFIG_HEADERS_CHECK is not set
1261CONFIG_DEBUG_KERNEL=y
1262# CONFIG_DEBUG_SHIRQ is not set
1263CONFIG_DETECT_SOFTLOCKUP=y
1264# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
1265CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
1266CONFIG_DETECT_HUNG_TASK=y
1267# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
1268CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
1269CONFIG_SCHED_DEBUG=y
1270# CONFIG_SCHEDSTATS is not set
1271# CONFIG_TIMER_STATS is not set
1272# CONFIG_DEBUG_OBJECTS is not set
1273# CONFIG_SLUB_DEBUG_ON is not set
1274# CONFIG_SLUB_STATS is not set
1275# CONFIG_DEBUG_KMEMLEAK is not set
1276# CONFIG_DEBUG_RT_MUTEXES is not set
1277# CONFIG_RT_MUTEX_TESTER is not set
1278# CONFIG_DEBUG_SPINLOCK is not set
1279# CONFIG_DEBUG_MUTEXES is not set
1280# CONFIG_DEBUG_LOCK_ALLOC is not set
1281# CONFIG_PROVE_LOCKING is not set
1282# CONFIG_LOCK_STAT is not set
1283# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1284# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1285# CONFIG_DEBUG_KOBJECT is not set
1286# CONFIG_DEBUG_HIGHMEM is not set
1287# CONFIG_DEBUG_BUGVERBOSE is not set
1288# CONFIG_DEBUG_INFO is not set
1289# CONFIG_DEBUG_VM is not set
1290# CONFIG_DEBUG_WRITECOUNT is not set
1291# CONFIG_DEBUG_MEMORY_INIT is not set
1292# CONFIG_DEBUG_LIST is not set
1293# CONFIG_DEBUG_SG is not set
1294# CONFIG_DEBUG_NOTIFIERS is not set
1295# CONFIG_DEBUG_CREDENTIALS is not set
1296# CONFIG_RCU_TORTURE_TEST is not set
1297# CONFIG_RCU_CPU_STALL_DETECTOR is not set
1298# CONFIG_BACKTRACE_SELF_TEST is not set
1299# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
1300# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
1301# CONFIG_FAULT_INJECTION is not set
1302# CONFIG_LATENCYTOP is not set
1303CONFIG_SYSCTL_SYSCALL_CHECK=y
1304# CONFIG_DEBUG_PAGEALLOC is not set
1305CONFIG_HAVE_FUNCTION_TRACER=y
1306CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
1307CONFIG_HAVE_DYNAMIC_FTRACE=y
1308CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
1309CONFIG_TRACING_SUPPORT=y
1310CONFIG_FTRACE=y
1311# CONFIG_FUNCTION_TRACER is not set
1312# CONFIG_IRQSOFF_TRACER is not set
1313# CONFIG_SCHED_TRACER is not set
1314# CONFIG_ENABLE_DEFAULT_TRACERS is not set
1315# CONFIG_BOOT_TRACER is not set
1316CONFIG_BRANCH_PROFILE_NONE=y
1317# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
1318# CONFIG_PROFILE_ALL_BRANCHES is not set
1319# CONFIG_STACK_TRACER is not set
1320# CONFIG_KMEMTRACE is not set
1321# CONFIG_WORKQUEUE_TRACER is not set
1322# CONFIG_BLK_DEV_IO_TRACE is not set
1323# CONFIG_DMA_API_DEBUG is not set
1324# CONFIG_SAMPLES is not set
1325CONFIG_HAVE_ARCH_KGDB=y
1326# CONFIG_KGDB is not set
1327# CONFIG_PPC_DISABLE_WERROR is not set
1328CONFIG_PPC_WERROR=y
1329CONFIG_PRINT_STACK_DEPTH=64
1330# CONFIG_DEBUG_STACKOVERFLOW is not set
1331# CONFIG_DEBUG_STACK_USAGE is not set
1332# CONFIG_CODE_PATCHING_SELFTEST is not set
1333# CONFIG_FTR_FIXUP_SELFTEST is not set
1334# CONFIG_MSI_BITMAP_SELFTEST is not set
1335# CONFIG_XMON is not set
1336# CONFIG_IRQSTACKS is not set
1337# CONFIG_BDI_SWITCH is not set
1338# CONFIG_PPC_EARLY_DEBUG is not set
1339
1340#
1341# Security options
1342#
1343# CONFIG_KEYS is not set
1344# CONFIG_SECURITY is not set
1345# CONFIG_SECURITYFS is not set
1346# CONFIG_DEFAULT_SECURITY_SELINUX is not set
1347# CONFIG_DEFAULT_SECURITY_SMACK is not set
1348# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
1349CONFIG_DEFAULT_SECURITY_DAC=y
1350CONFIG_DEFAULT_SECURITY=""
1351CONFIG_CRYPTO=y
1352
1353#
1354# Crypto core or helper
1355#
1356CONFIG_CRYPTO_ALGAPI=y
1357CONFIG_CRYPTO_ALGAPI2=y
1358CONFIG_CRYPTO_AEAD2=y
1359CONFIG_CRYPTO_BLKCIPHER=y
1360CONFIG_CRYPTO_BLKCIPHER2=y
1361CONFIG_CRYPTO_HASH=y
1362CONFIG_CRYPTO_HASH2=y
1363CONFIG_CRYPTO_RNG2=y
1364CONFIG_CRYPTO_PCOMP=y
1365CONFIG_CRYPTO_MANAGER=y
1366CONFIG_CRYPTO_MANAGER2=y
1367# CONFIG_CRYPTO_GF128MUL is not set
1368# CONFIG_CRYPTO_NULL is not set
1369CONFIG_CRYPTO_WORKQUEUE=y
1370# CONFIG_CRYPTO_CRYPTD is not set
1371# CONFIG_CRYPTO_AUTHENC is not set
1372# CONFIG_CRYPTO_TEST is not set
1373
1374#
1375# Authenticated Encryption with Associated Data
1376#
1377# CONFIG_CRYPTO_CCM is not set
1378# CONFIG_CRYPTO_GCM is not set
1379# CONFIG_CRYPTO_SEQIV is not set
1380
1381#
1382# Block modes
1383#
1384CONFIG_CRYPTO_CBC=y
1385# CONFIG_CRYPTO_CTR is not set
1386# CONFIG_CRYPTO_CTS is not set
1387CONFIG_CRYPTO_ECB=y
1388# CONFIG_CRYPTO_LRW is not set
1389CONFIG_CRYPTO_PCBC=y
1390# CONFIG_CRYPTO_XTS is not set
1391
1392#
1393# Hash modes
1394#
1395# CONFIG_CRYPTO_HMAC is not set
1396# CONFIG_CRYPTO_XCBC is not set
1397# CONFIG_CRYPTO_VMAC is not set
1398
1399#
1400# Digest
1401#
1402# CONFIG_CRYPTO_CRC32C is not set
1403# CONFIG_CRYPTO_GHASH is not set
1404# CONFIG_CRYPTO_MD4 is not set
1405CONFIG_CRYPTO_MD5=y
1406# CONFIG_CRYPTO_MICHAEL_MIC is not set
1407# CONFIG_CRYPTO_RMD128 is not set
1408# CONFIG_CRYPTO_RMD160 is not set
1409# CONFIG_CRYPTO_RMD256 is not set
1410# CONFIG_CRYPTO_RMD320 is not set
1411# CONFIG_CRYPTO_SHA1 is not set
1412# CONFIG_CRYPTO_SHA256 is not set
1413# CONFIG_CRYPTO_SHA512 is not set
1414# CONFIG_CRYPTO_TGR192 is not set
1415# CONFIG_CRYPTO_WP512 is not set
1416
1417#
1418# Ciphers
1419#
1420# CONFIG_CRYPTO_AES is not set
1421# CONFIG_CRYPTO_ANUBIS is not set
1422# CONFIG_CRYPTO_ARC4 is not set
1423# CONFIG_CRYPTO_BLOWFISH is not set
1424# CONFIG_CRYPTO_CAMELLIA is not set
1425# CONFIG_CRYPTO_CAST5 is not set
1426# CONFIG_CRYPTO_CAST6 is not set
1427CONFIG_CRYPTO_DES=y
1428# CONFIG_CRYPTO_FCRYPT is not set
1429# CONFIG_CRYPTO_KHAZAD is not set
1430# CONFIG_CRYPTO_SALSA20 is not set
1431# CONFIG_CRYPTO_SEED is not set
1432# CONFIG_CRYPTO_SERPENT is not set
1433# CONFIG_CRYPTO_TEA is not set
1434# CONFIG_CRYPTO_TWOFISH is not set
1435
1436#
1437# Compression
1438#
1439# CONFIG_CRYPTO_DEFLATE is not set
1440# CONFIG_CRYPTO_ZLIB is not set
1441# CONFIG_CRYPTO_LZO is not set
1442
1443#
1444# Random Number Generation
1445#
1446# CONFIG_CRYPTO_ANSI_CPRNG is not set
1447CONFIG_CRYPTO_HW=y
1448# CONFIG_CRYPTO_DEV_HIFN_795X is not set
1449# CONFIG_CRYPTO_DEV_PPC4XX is not set
1450# CONFIG_PPC_CLOCK is not set
1451# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index 725634fc18c6..4b509411ad8a 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -42,7 +42,7 @@ extern struct ppc64_caches ppc64_caches;
42#endif /* __powerpc64__ && ! __ASSEMBLY__ */ 42#endif /* __powerpc64__ && ! __ASSEMBLY__ */
43 43
44#if !defined(__ASSEMBLY__) 44#if !defined(__ASSEMBLY__)
45#define __read_mostly __attribute__((__section__(".data.read_mostly"))) 45#define __read_mostly __attribute__((__section__(".data..read_mostly")))
46#endif 46#endif
47 47
48#endif /* __KERNEL__ */ 48#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index e3cba4e1eb34..b0b21134f61a 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -70,6 +70,7 @@ struct pt_regs;
70extern int machine_check_generic(struct pt_regs *regs); 70extern int machine_check_generic(struct pt_regs *regs);
71extern int machine_check_4xx(struct pt_regs *regs); 71extern int machine_check_4xx(struct pt_regs *regs);
72extern int machine_check_440A(struct pt_regs *regs); 72extern int machine_check_440A(struct pt_regs *regs);
73extern int machine_check_e500mc(struct pt_regs *regs);
73extern int machine_check_e500(struct pt_regs *regs); 74extern int machine_check_e500(struct pt_regs *regs);
74extern int machine_check_e200(struct pt_regs *regs); 75extern int machine_check_e200(struct pt_regs *regs);
75extern int machine_check_47x(struct pt_regs *regs); 76extern int machine_check_47x(struct pt_regs *regs);
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index a6ca6da1430b..2a9cd74a841e 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -2,6 +2,18 @@
2#define _ASM_POWERPC_KEXEC_H 2#define _ASM_POWERPC_KEXEC_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#ifdef CONFIG_FSL_BOOKE
6
7/*
8 * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory
9 * and therefore we can only deal with memory within this range
10 */
11#define KEXEC_SOURCE_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL)
12#define KEXEC_DESTINATION_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL)
13#define KEXEC_CONTROL_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL)
14
15#else
16
5/* 17/*
6 * Maximum page that is mapped directly into kernel memory. 18 * Maximum page that is mapped directly into kernel memory.
7 * XXX: Since we copy virt we can use any page we allocate 19 * XXX: Since we copy virt we can use any page we allocate
@@ -21,6 +33,7 @@
21/* TASK_SIZE, probably left over from use_mm ?? */ 33/* TASK_SIZE, probably left over from use_mm ?? */
22#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE 34#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
23#endif 35#endif
36#endif
24 37
25#define KEXEC_CONTROL_PAGE_SIZE 4096 38#define KEXEC_CONTROL_PAGE_SIZE 4096
26 39
diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h
index 19a661b4cb98..675e159b5ef4 100644
--- a/arch/powerpc/include/asm/macio.h
+++ b/arch/powerpc/include/asm/macio.h
@@ -123,10 +123,6 @@ static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev)
123 */ 123 */
124struct macio_driver 124struct macio_driver
125{ 125{
126 char *name;
127 struct of_device_id *match_table;
128 struct module *owner;
129
130 int (*probe)(struct macio_dev* dev, const struct of_device_id *match); 126 int (*probe)(struct macio_dev* dev, const struct of_device_id *match);
131 int (*remove)(struct macio_dev* dev); 127 int (*remove)(struct macio_dev* dev);
132 128
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index bfc4e027e2ad..358ff14ea25e 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -162,14 +162,6 @@ do { \
162 162
163#endif /* !CONFIG_HUGETLB_PAGE */ 163#endif /* !CONFIG_HUGETLB_PAGE */
164 164
165#ifdef MODULE
166#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
167#else
168#define __page_aligned \
169 __attribute__((__aligned__(PAGE_SIZE), \
170 __section__(".data.page_aligned")))
171#endif
172
173#define VM_DATA_DEFAULT_FLAGS \ 165#define VM_DATA_DEFAULT_FLAGS \
174 (test_thread_flag(TIF_32BIT) ? \ 166 (test_thread_flag(TIF_32BIT) ? \
175 VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64) 167 VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 5304a37ba425..2360317179a9 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -4,6 +4,12 @@
4 * are not true Book E PowerPCs, they borrowed a number of features 4 * are not true Book E PowerPCs, they borrowed a number of features
5 * before Book E was finalized, and are included here as well. Unfortunatly, 5 * before Book E was finalized, and are included here as well. Unfortunatly,
6 * they sometimes used different locations than true Book E CPUs did. 6 * they sometimes used different locations than true Book E CPUs did.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * Copyright 2009-2010 Freescale Semiconductor, Inc.
7 */ 13 */
8#ifdef __KERNEL__ 14#ifdef __KERNEL__
9#ifndef __ASM_POWERPC_REG_BOOKE_H__ 15#ifndef __ASM_POWERPC_REG_BOOKE_H__
@@ -88,6 +94,7 @@
88#define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */ 94#define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */
89#define SPRN_IVOR36 0x214 /* Interrupt Vector Offset Register 36 */ 95#define SPRN_IVOR36 0x214 /* Interrupt Vector Offset Register 36 */
90#define SPRN_IVOR37 0x215 /* Interrupt Vector Offset Register 37 */ 96#define SPRN_IVOR37 0x215 /* Interrupt Vector Offset Register 37 */
97#define SPRN_MCARU 0x239 /* Machine Check Address Register Upper */
91#define SPRN_MCSRR0 0x23A /* Machine Check Save and Restore Register 0 */ 98#define SPRN_MCSRR0 0x23A /* Machine Check Save and Restore Register 0 */
92#define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */ 99#define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */
93#define SPRN_MCSR 0x23C /* Machine Check Status Register */ 100#define SPRN_MCSR 0x23C /* Machine Check Status Register */
@@ -196,8 +203,11 @@
196#define PPC47x_MCSR_IPR 0x00400000 /* Imprecise Machine Check Exception */ 203#define PPC47x_MCSR_IPR 0x00400000 /* Imprecise Machine Check Exception */
197 204
198#ifdef CONFIG_E500 205#ifdef CONFIG_E500
206/* All e500 */
199#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ 207#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */
200#define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */ 208#define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */
209
210/* e500v1/v2 */
201#define MCSR_DCP_PERR 0x20000000UL /* D-Cache Push Parity Error */ 211#define MCSR_DCP_PERR 0x20000000UL /* D-Cache Push Parity Error */
202#define MCSR_DCPERR 0x10000000UL /* D-Cache Parity Error */ 212#define MCSR_DCPERR 0x10000000UL /* D-Cache Parity Error */
203#define MCSR_BUS_IAERR 0x00000080UL /* Instruction Address Error */ 213#define MCSR_BUS_IAERR 0x00000080UL /* Instruction Address Error */
@@ -209,12 +219,20 @@
209#define MCSR_BUS_IPERR 0x00000002UL /* Instruction parity Error */ 219#define MCSR_BUS_IPERR 0x00000002UL /* Instruction parity Error */
210#define MCSR_BUS_RPERR 0x00000001UL /* Read parity Error */ 220#define MCSR_BUS_RPERR 0x00000001UL /* Read parity Error */
211 221
212/* e500 parts may set unused bits in MCSR; mask these off */ 222/* e500mc */
213#define MCSR_MASK (MCSR_MCP | MCSR_ICPERR | MCSR_DCP_PERR | \ 223#define MCSR_DCPERR_MC 0x20000000UL /* D-Cache Parity Error */
214 MCSR_DCPERR | MCSR_BUS_IAERR | MCSR_BUS_RAERR | \ 224#define MCSR_L2MMU_MHIT 0x04000000UL /* Hit on multiple TLB entries */
215 MCSR_BUS_WAERR | MCSR_BUS_IBERR | MCSR_BUS_RBERR | \ 225#define MCSR_NMI 0x00100000UL /* Non-Maskable Interrupt */
216 MCSR_BUS_WBERR | MCSR_BUS_IPERR | MCSR_BUS_RPERR) 226#define MCSR_MAV 0x00080000UL /* MCAR address valid */
227#define MCSR_MEA 0x00040000UL /* MCAR is effective address */
228#define MCSR_IF 0x00010000UL /* Instruction Fetch */
229#define MCSR_LD 0x00008000UL /* Load */
230#define MCSR_ST 0x00004000UL /* Store */
231#define MCSR_LDG 0x00002000UL /* Guarded Load */
232#define MCSR_TLBSYNC 0x00000002UL /* Multiple tlbsyncs detected */
233#define MCSR_BSL2_ERR 0x00000001UL /* Backside L2 cache error */
217#endif 234#endif
235
218#ifdef CONFIG_E200 236#ifdef CONFIG_E200
219#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ 237#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */
220#define MCSR_CP_PERR 0x20000000UL /* Cache Push Parity Error */ 238#define MCSR_CP_PERR 0x20000000UL /* Cache Push Parity Error */
@@ -225,11 +243,6 @@
225#define MCSR_BUS_DRERR 0x00000008UL /* Read Bus Error on data load */ 243#define MCSR_BUS_DRERR 0x00000008UL /* Read Bus Error on data load */
226#define MCSR_BUS_WRERR 0x00000004UL /* Write Bus Error on buffered 244#define MCSR_BUS_WRERR 0x00000004UL /* Write Bus Error on buffered
227 store or cache line push */ 245 store or cache line push */
228
229/* e200 parts may set unused bits in MCSR; mask these off */
230#define MCSR_MASK (MCSR_MCP | MCSR_CP_PERR | MCSR_CPERR | \
231 MCSR_EXCP_ERR | MCSR_BUS_IRERR | MCSR_BUS_DRERR | \
232 MCSR_BUS_WRERR)
233#endif 246#endif
234 247
235/* Bit definitions for the DBSR. */ 248/* Bit definitions for the DBSR. */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 877326320e74..58d0572de6f9 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -57,8 +57,12 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
57obj-$(CONFIG_E500) += idle_e500.o 57obj-$(CONFIG_E500) += idle_e500.o
58obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o 58obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
59obj-$(CONFIG_TAU) += tau_6xx.o 59obj-$(CONFIG_TAU) += tau_6xx.o
60obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \ 60obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o
61 swsusp_$(CONFIG_WORD_SIZE).o 61ifeq ($(CONFIG_FSL_BOOKE),y)
62obj-$(CONFIG_HIBERNATION) += swsusp_booke.o
63else
64obj-$(CONFIG_HIBERNATION) += swsusp_$(CONFIG_WORD_SIZE).o
65endif
62obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o 66obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o
63obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o 67obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o
64obj-$(CONFIG_44x) += cpu_setup_44x.o 68obj-$(CONFIG_44x) += cpu_setup_44x.o
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 9556be903e96..87aa0f3c6047 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1840,7 +1840,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1840 .oprofile_cpu_type = "ppc/e500mc", 1840 .oprofile_cpu_type = "ppc/e500mc",
1841 .oprofile_type = PPC_OPROFILE_FSL_EMB, 1841 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1842 .cpu_setup = __setup_cpu_e500mc, 1842 .cpu_setup = __setup_cpu_e500mc,
1843 .machine_check = machine_check_e500, 1843 .machine_check = machine_check_e500mc,
1844 .platform = "ppce500mc", 1844 .platform = "ppce500mc",
1845 }, 1845 },
1846 { /* default match */ 1846 { /* default match */
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 8c066d6a8e4b..b46f2e09bd81 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -163,6 +163,7 @@ static void crash_kexec_prepare_cpus(int cpu)
163} 163}
164 164
165/* wait for all the CPUs to hit real mode but timeout if they don't come in */ 165/* wait for all the CPUs to hit real mode but timeout if they don't come in */
166#ifdef CONFIG_PPC_STD_MMU_64
166static void crash_kexec_wait_realmode(int cpu) 167static void crash_kexec_wait_realmode(int cpu)
167{ 168{
168 unsigned int msecs; 169 unsigned int msecs;
@@ -187,6 +188,7 @@ static void crash_kexec_wait_realmode(int cpu)
187 } 188 }
188 mb(); 189 mb();
189} 190}
191#endif
190 192
191/* 193/*
192 * This function will be called by secondary cpus or by kexec cpu 194 * This function will be called by secondary cpus or by kexec cpu
@@ -445,7 +447,9 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
445 crash_kexec_prepare_cpus(crashing_cpu); 447 crash_kexec_prepare_cpus(crashing_cpu);
446 cpu_set(crashing_cpu, cpus_in_crash); 448 cpu_set(crashing_cpu, cpus_in_crash);
447 crash_kexec_stop_spus(); 449 crash_kexec_stop_spus();
450#ifdef CONFIG_PPC_STD_MMU_64
448 crash_kexec_wait_realmode(crashing_cpu); 451 crash_kexec_wait_realmode(crashing_cpu);
452#endif
449 if (ppc_md.kexec_cpu_down) 453 if (ppc_md.kexec_cpu_down)
450 ppc_md.kexec_cpu_down(1, 0); 454 ppc_md.kexec_cpu_down(1, 0);
451} 455}
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
new file mode 100644
index 000000000000..beb4d78a2304
--- /dev/null
+++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
@@ -0,0 +1,237 @@
1
2/* 1. Find the index of the entry we're executing in */
3 bl invstr /* Find our address */
4invstr: mflr r6 /* Make it accessible */
5 mfmsr r7
6 rlwinm r4,r7,27,31,31 /* extract MSR[IS] */
7 mfspr r7, SPRN_PID0
8 slwi r7,r7,16
9 or r7,r7,r4
10 mtspr SPRN_MAS6,r7
11 tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */
12 mfspr r7,SPRN_MAS1
13 andis. r7,r7,MAS1_VALID@h
14 bne match_TLB
15
16 mfspr r7,SPRN_MMUCFG
17 rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */
18 cmpwi r7,3
19 bne match_TLB /* skip if NPIDS != 3 */
20
21 mfspr r7,SPRN_PID1
22 slwi r7,r7,16
23 or r7,r7,r4
24 mtspr SPRN_MAS6,r7
25 tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */
26 mfspr r7,SPRN_MAS1
27 andis. r7,r7,MAS1_VALID@h
28 bne match_TLB
29 mfspr r7, SPRN_PID2
30 slwi r7,r7,16
31 or r7,r7,r4
32 mtspr SPRN_MAS6,r7
33 tlbsx 0,r6 /* Fall through, we had to match */
34
35match_TLB:
36 mfspr r7,SPRN_MAS0
37 rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */
38
39 mfspr r7,SPRN_MAS1 /* Insure IPROT set */
40 oris r7,r7,MAS1_IPROT@h
41 mtspr SPRN_MAS1,r7
42 tlbwe
43
44/* 2. Invalidate all entries except the entry we're executing in */
45 mfspr r9,SPRN_TLB1CFG
46 andi. r9,r9,0xfff
47 li r6,0 /* Set Entry counter to 0 */
481: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
49 rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */
50 mtspr SPRN_MAS0,r7
51 tlbre
52 mfspr r7,SPRN_MAS1
53 rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */
54 cmpw r3,r6
55 beq skpinv /* Dont update the current execution TLB */
56 mtspr SPRN_MAS1,r7
57 tlbwe
58 isync
59skpinv: addi r6,r6,1 /* Increment */
60 cmpw r6,r9 /* Are we done? */
61 bne 1b /* If not, repeat */
62
63 /* Invalidate TLB0 */
64 li r6,0x04
65 tlbivax 0,r6
66 TLBSYNC
67 /* Invalidate TLB1 */
68 li r6,0x0c
69 tlbivax 0,r6
70 TLBSYNC
71
72/* 3. Setup a temp mapping and jump to it */
73 andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */
74 addi r5, r5, 0x1
75 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
76 rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
77 mtspr SPRN_MAS0,r7
78 tlbre
79
80 /* grab and fixup the RPN */
81 mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */
82 rlwinm r6,r6,25,27,31
83 li r8,-1
84 addi r6,r6,10
85 slw r6,r8,r6 /* convert to mask */
86
87 bl 1f /* Find our address */
881: mflr r7
89
90 mfspr r8,SPRN_MAS3
91#ifdef CONFIG_PHYS_64BIT
92 mfspr r23,SPRN_MAS7
93#endif
94 and r8,r6,r8
95 subfic r9,r6,-4096
96 and r9,r9,r7
97
98 or r25,r8,r9
99 ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)
100
101 /* Just modify the entry ID and EPN for the temp mapping */
102 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
103 rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
104 mtspr SPRN_MAS0,r7
105 xori r6,r4,1 /* Setup TMP mapping in the other Address space */
106 slwi r6,r6,12
107 oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h
108 ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
109 mtspr SPRN_MAS1,r6
110 mfspr r6,SPRN_MAS2
111 li r7,0 /* temp EPN = 0 */
112 rlwimi r7,r6,0,20,31
113 mtspr SPRN_MAS2,r7
114 mtspr SPRN_MAS3,r8
115 tlbwe
116
117 xori r6,r4,1
118 slwi r6,r6,5 /* setup new context with other address space */
119 bl 1f /* Find our address */
1201: mflr r9
121 rlwimi r7,r9,0,20,31
122 addi r7,r7,(2f - 1b)
123 mtspr SPRN_SRR0,r7
124 mtspr SPRN_SRR1,r6
125 rfi
1262:
127/* 4. Clear out PIDs & Search info */
128 li r6,0
129 mtspr SPRN_MAS6,r6
130 mtspr SPRN_PID0,r6
131
132 mfspr r7,SPRN_MMUCFG
133 rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */
134 cmpwi r7,3
135 bne 2f /* skip if NPIDS != 3 */
136
137 mtspr SPRN_PID1,r6
138 mtspr SPRN_PID2,r6
139
140/* 5. Invalidate mapping we started in */
1412:
142 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
143 rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
144 mtspr SPRN_MAS0,r7
145 tlbre
146 mfspr r6,SPRN_MAS1
147 rlwinm r6,r6,0,2,0 /* clear IPROT */
148 mtspr SPRN_MAS1,r6
149 tlbwe
150 /* Invalidate TLB1 */
151 li r9,0x0c
152 tlbivax 0,r9
153 TLBSYNC
154
155/* The mapping only needs to be cache-coherent on SMP */
156#ifdef CONFIG_SMP
157#define M_IF_SMP MAS2_M
158#else
159#define M_IF_SMP 0
160#endif
161
162#if defined(ENTRY_MAPPING_BOOT_SETUP)
163
164/* 6. Setup KERNELBASE mapping in TLB1[0] */
165 lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
166 mtspr SPRN_MAS0,r6
167 lis r6,(MAS1_VALID|MAS1_IPROT)@h
168 ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
169 mtspr SPRN_MAS1,r6
170 lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
171 ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
172 mtspr SPRN_MAS2,r6
173 mtspr SPRN_MAS3,r8
174 tlbwe
175
176/* 7. Jump to KERNELBASE mapping */
177 lis r6,(KERNELBASE & ~0xfff)@h
178 ori r6,r6,(KERNELBASE & ~0xfff)@l
179
180#elif defined(ENTRY_MAPPING_KEXEC_SETUP)
181/*
182 * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp
183 * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This
184 * will cover the first 2GiB of memory.
185 */
186
187 lis r10, (MAS1_VALID|MAS1_IPROT)@h
188 ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l
189 li r11, 0
190 li r0, 8
191 mtctr r0
192
193next_tlb_setup:
194 addi r0, r11, 3
195 rlwinm r0, r0, 16, 4, 15 // Compute esel
196 rlwinm r9, r11, 28, 0, 3 // Compute [ER]PN
197 oris r0, r0, (MAS0_TLBSEL(1))@h
198 mtspr SPRN_MAS0,r0
199 mtspr SPRN_MAS1,r10
200 mtspr SPRN_MAS2,r9
201 ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR)
202 mtspr SPRN_MAS3,r9
203 tlbwe
204 addi r11, r11, 1
205 bdnz+ next_tlb_setup
206
207/* 7. Jump to our 1:1 mapping */
208 li r6, 0
209
210#else
211 #error You need to specify the mapping or not use this at all.
212#endif
213
214 lis r7,MSR_KERNEL@h
215 ori r7,r7,MSR_KERNEL@l
216 bl 1f /* Find our address */
2171: mflr r9
218 rlwimi r6,r9,0,20,31
219 addi r6,r6,(2f - 1b)
220 add r6, r6, r25
221 mtspr SPRN_SRR0,r6
222 mtspr SPRN_SRR1,r7
223 rfi /* start execution out of TLB1[0] entry */
224
225/* 8. Clear out the temp mapping */
2262: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
227 rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
228 mtspr SPRN_MAS0,r7
229 tlbre
230 mfspr r8,SPRN_MAS1
231 rlwinm r8,r8,0,2,0 /* clear IPROT */
232 mtspr SPRN_MAS1,r8
233 tlbwe
234 /* Invalidate TLB1 */
235 li r9,0x0c
236 tlbivax 0,r9
237 TLBSYNC
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index edd4a57fd29e..4faeba247854 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -94,204 +94,10 @@ _ENTRY(_start);
94 */ 94 */
95 95
96_ENTRY(__early_start) 96_ENTRY(__early_start)
97/* 1. Find the index of the entry we're executing in */
98 bl invstr /* Find our address */
99invstr: mflr r6 /* Make it accessible */
100 mfmsr r7
101 rlwinm r4,r7,27,31,31 /* extract MSR[IS] */
102 mfspr r7, SPRN_PID0
103 slwi r7,r7,16
104 or r7,r7,r4
105 mtspr SPRN_MAS6,r7
106 tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */
107 mfspr r7,SPRN_MAS1
108 andis. r7,r7,MAS1_VALID@h
109 bne match_TLB
110
111 mfspr r7,SPRN_MMUCFG
112 rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */
113 cmpwi r7,3
114 bne match_TLB /* skip if NPIDS != 3 */
115
116 mfspr r7,SPRN_PID1
117 slwi r7,r7,16
118 or r7,r7,r4
119 mtspr SPRN_MAS6,r7
120 tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */
121 mfspr r7,SPRN_MAS1
122 andis. r7,r7,MAS1_VALID@h
123 bne match_TLB
124 mfspr r7, SPRN_PID2
125 slwi r7,r7,16
126 or r7,r7,r4
127 mtspr SPRN_MAS6,r7
128 tlbsx 0,r6 /* Fall through, we had to match */
129
130match_TLB:
131 mfspr r7,SPRN_MAS0
132 rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */
133
134 mfspr r7,SPRN_MAS1 /* Insure IPROT set */
135 oris r7,r7,MAS1_IPROT@h
136 mtspr SPRN_MAS1,r7
137 tlbwe
138
139/* 2. Invalidate all entries except the entry we're executing in */
140 mfspr r9,SPRN_TLB1CFG
141 andi. r9,r9,0xfff
142 li r6,0 /* Set Entry counter to 0 */
1431: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
144 rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */
145 mtspr SPRN_MAS0,r7
146 tlbre
147 mfspr r7,SPRN_MAS1
148 rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */
149 cmpw r3,r6
150 beq skpinv /* Dont update the current execution TLB */
151 mtspr SPRN_MAS1,r7
152 tlbwe
153 isync
154skpinv: addi r6,r6,1 /* Increment */
155 cmpw r6,r9 /* Are we done? */
156 bne 1b /* If not, repeat */
157
158 /* Invalidate TLB0 */
159 li r6,0x04
160 tlbivax 0,r6
161 TLBSYNC
162 /* Invalidate TLB1 */
163 li r6,0x0c
164 tlbivax 0,r6
165 TLBSYNC
166
167/* 3. Setup a temp mapping and jump to it */
168 andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */
169 addi r5, r5, 0x1
170 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
171 rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
172 mtspr SPRN_MAS0,r7
173 tlbre
174
175 /* grab and fixup the RPN */
176 mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */
177 rlwinm r6,r6,25,27,31
178 li r8,-1
179 addi r6,r6,10
180 slw r6,r8,r6 /* convert to mask */
181
182 bl 1f /* Find our address */
1831: mflr r7
184
185 mfspr r8,SPRN_MAS3
186#ifdef CONFIG_PHYS_64BIT
187 mfspr r23,SPRN_MAS7
188#endif
189 and r8,r6,r8
190 subfic r9,r6,-4096
191 and r9,r9,r7
192
193 or r25,r8,r9
194 ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)
195
196 /* Just modify the entry ID and EPN for the temp mapping */
197 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
198 rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
199 mtspr SPRN_MAS0,r7
200 xori r6,r4,1 /* Setup TMP mapping in the other Address space */
201 slwi r6,r6,12
202 oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h
203 ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
204 mtspr SPRN_MAS1,r6
205 mfspr r6,SPRN_MAS2
206 li r7,0 /* temp EPN = 0 */
207 rlwimi r7,r6,0,20,31
208 mtspr SPRN_MAS2,r7
209 mtspr SPRN_MAS3,r8
210 tlbwe
211
212 xori r6,r4,1
213 slwi r6,r6,5 /* setup new context with other address space */
214 bl 1f /* Find our address */
2151: mflr r9
216 rlwimi r7,r9,0,20,31
217 addi r7,r7,(2f - 1b)
218 mtspr SPRN_SRR0,r7
219 mtspr SPRN_SRR1,r6
220 rfi
2212:
222/* 4. Clear out PIDs & Search info */
223 li r6,0
224 mtspr SPRN_MAS6,r6
225 mtspr SPRN_PID0,r6
226
227 mfspr r7,SPRN_MMUCFG
228 rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */
229 cmpwi r7,3
230 bne 2f /* skip if NPIDS != 3 */
231 97
232 mtspr SPRN_PID1,r6 98#define ENTRY_MAPPING_BOOT_SETUP
233 mtspr SPRN_PID2,r6 99#include "fsl_booke_entry_mapping.S"
234 100#undef ENTRY_MAPPING_BOOT_SETUP
235/* 5. Invalidate mapping we started in */
2362:
237 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
238 rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
239 mtspr SPRN_MAS0,r7
240 tlbre
241 mfspr r6,SPRN_MAS1
242 rlwinm r6,r6,0,2,0 /* clear IPROT */
243 mtspr SPRN_MAS1,r6
244 tlbwe
245 /* Invalidate TLB1 */
246 li r9,0x0c
247 tlbivax 0,r9
248 TLBSYNC
249
250/* The mapping only needs to be cache-coherent on SMP */
251#ifdef CONFIG_SMP
252#define M_IF_SMP MAS2_M
253#else
254#define M_IF_SMP 0
255#endif
256
257/* 6. Setup KERNELBASE mapping in TLB1[0] */
258 lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
259 mtspr SPRN_MAS0,r6
260 lis r6,(MAS1_VALID|MAS1_IPROT)@h
261 ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
262 mtspr SPRN_MAS1,r6
263 lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
264 ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
265 mtspr SPRN_MAS2,r6
266 mtspr SPRN_MAS3,r8
267 tlbwe
268
269/* 7. Jump to KERNELBASE mapping */
270 lis r6,(KERNELBASE & ~0xfff)@h
271 ori r6,r6,(KERNELBASE & ~0xfff)@l
272 lis r7,MSR_KERNEL@h
273 ori r7,r7,MSR_KERNEL@l
274 bl 1f /* Find our address */
2751: mflr r9
276 rlwimi r6,r9,0,20,31
277 addi r6,r6,(2f - 1b)
278 mtspr SPRN_SRR0,r6
279 mtspr SPRN_SRR1,r7
280 rfi /* start execution out of TLB1[0] entry */
281
282/* 8. Clear out the temp mapping */
2832: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
284 rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
285 mtspr SPRN_MAS0,r7
286 tlbre
287 mfspr r8,SPRN_MAS1
288 rlwinm r8,r8,0,2,0 /* clear IPROT */
289 mtspr SPRN_MAS1,r8
290 tlbwe
291 /* Invalidate TLB1 */
292 li r9,0x0c
293 tlbivax 0,r9
294 TLBSYNC
295 101
296 /* Establish the interrupt vector offsets */ 102 /* Establish the interrupt vector offsets */
297 SET_IVOR(0, CriticalInput); 103 SET_IVOR(0, CriticalInput);
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index c533525ca56a..bc47352deb1f 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -378,17 +378,6 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
378 * single-stepped a copy of the instruction. The address of this 378 * single-stepped a copy of the instruction. The address of this
379 * copy is p->ainsn.insn. 379 * copy is p->ainsn.insn.
380 */ 380 */
381static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
382{
383 int ret;
384 unsigned int insn = *p->ainsn.insn;
385
386 regs->nip = (unsigned long)p->addr;
387 ret = emulate_step(regs, insn);
388 if (ret == 0)
389 regs->nip = (unsigned long)p->addr + 4;
390}
391
392static int __kprobes post_kprobe_handler(struct pt_regs *regs) 381static int __kprobes post_kprobe_handler(struct pt_regs *regs)
393{ 382{
394 struct kprobe *cur = kprobe_running(); 383 struct kprobe *cur = kprobe_running();
@@ -406,7 +395,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
406 cur->post_handler(cur, regs, 0); 395 cur->post_handler(cur, regs, 0);
407 } 396 }
408 397
409 resume_execution(cur, regs); 398 /* Adjust nip to after the single-stepped instruction */
399 regs->nip = (unsigned long)cur->addr + 4;
410 regs->msr |= kcb->kprobe_saved_msr; 400 regs->msr |= kcb->kprobe_saved_msr;
411 401
412 /*Restore back the original saved kprobes variables and continue. */ 402 /*Restore back the original saved kprobes variables and continue. */
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 8043d1b73cf0..dc66d52dcff5 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -711,6 +711,22 @@ relocate_new_kernel:
711 /* r4 = reboot_code_buffer */ 711 /* r4 = reboot_code_buffer */
712 /* r5 = start_address */ 712 /* r5 = start_address */
713 713
714#ifdef CONFIG_FSL_BOOKE
715
716 mr r29, r3
717 mr r30, r4
718 mr r31, r5
719
720#define ENTRY_MAPPING_KEXEC_SETUP
721#include "fsl_booke_entry_mapping.S"
722#undef ENTRY_MAPPING_KEXEC_SETUP
723
724 mr r3, r29
725 mr r4, r30
726 mr r5, r31
727
728 li r0, 0
729#else
714 li r0, 0 730 li r0, 0
715 731
716 /* 732 /*
@@ -727,6 +743,7 @@ relocate_new_kernel:
727 rfi 743 rfi
728 744
7291: 7451:
746#endif
730 /* from this point address translation is turned off */ 747 /* from this point address translation is turned off */
731 /* and interrupts are disabled */ 748 /* and interrupts are disabled */
732 749
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index bc9f39d2598b..3b4dcc82a4c1 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -101,7 +101,7 @@ EXPORT_SYMBOL(pci_dram_offset);
101EXPORT_SYMBOL(start_thread); 101EXPORT_SYMBOL(start_thread);
102EXPORT_SYMBOL(kernel_thread); 102EXPORT_SYMBOL(kernel_thread);
103 103
104#ifndef CONFIG_BOOKE 104#ifdef CONFIG_PPC_FPU
105EXPORT_SYMBOL_GPL(cvt_df); 105EXPORT_SYMBOL_GPL(cvt_df);
106EXPORT_SYMBOL_GPL(cvt_fd); 106EXPORT_SYMBOL_GPL(cvt_fd);
107#endif 107#endif
diff --git a/arch/powerpc/kernel/swsusp_booke.S b/arch/powerpc/kernel/swsusp_booke.S
new file mode 100644
index 000000000000..11a39307dd71
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp_booke.S
@@ -0,0 +1,193 @@
1/*
2 * Based on swsusp_32.S, modified for FSL BookE by
3 * Anton Vorontsov <avorontsov@ru.mvista.com>
4 * Copyright (c) 2009-2010 MontaVista Software, LLC.
5 */
6
7#include <linux/threads.h>
8#include <asm/processor.h>
9#include <asm/page.h>
10#include <asm/cputable.h>
11#include <asm/thread_info.h>
12#include <asm/ppc_asm.h>
13#include <asm/asm-offsets.h>
14#include <asm/mmu.h>
15
16/*
17 * Structure for storing CPU registers on the save area.
18 */
19#define SL_SP 0
20#define SL_PC 4
21#define SL_MSR 8
22#define SL_TCR 0xc
23#define SL_SPRG0 0x10
24#define SL_SPRG1 0x14
25#define SL_SPRG2 0x18
26#define SL_SPRG3 0x1c
27#define SL_SPRG4 0x20
28#define SL_SPRG5 0x24
29#define SL_SPRG6 0x28
30#define SL_SPRG7 0x2c
31#define SL_TBU 0x30
32#define SL_TBL 0x34
33#define SL_R2 0x38
34#define SL_CR 0x3c
35#define SL_LR 0x40
36#define SL_R12 0x44 /* r12 to r31 */
37#define SL_SIZE (SL_R12 + 80)
38
39 .section .data
40 .align 5
41
42_GLOBAL(swsusp_save_area)
43 .space SL_SIZE
44
45
46 .section .text
47 .align 5
48
49_GLOBAL(swsusp_arch_suspend)
50 lis r11,swsusp_save_area@h
51 ori r11,r11,swsusp_save_area@l
52
53 mflr r0
54 stw r0,SL_LR(r11)
55 mfcr r0
56 stw r0,SL_CR(r11)
57 stw r1,SL_SP(r11)
58 stw r2,SL_R2(r11)
59 stmw r12,SL_R12(r11)
60
61 /* Save MSR & TCR */
62 mfmsr r4
63 stw r4,SL_MSR(r11)
64 mfspr r4,SPRN_TCR
65 stw r4,SL_TCR(r11)
66
67 /* Get a stable timebase and save it */
681: mfspr r4,SPRN_TBRU
69 stw r4,SL_TBU(r11)
70 mfspr r5,SPRN_TBRL
71 stw r5,SL_TBL(r11)
72 mfspr r3,SPRN_TBRU
73 cmpw r3,r4
74 bne 1b
75
76 /* Save SPRGs */
77 mfsprg r4,0
78 stw r4,SL_SPRG0(r11)
79 mfsprg r4,1
80 stw r4,SL_SPRG1(r11)
81 mfsprg r4,2
82 stw r4,SL_SPRG2(r11)
83 mfsprg r4,3
84 stw r4,SL_SPRG3(r11)
85 mfsprg r4,4
86 stw r4,SL_SPRG4(r11)
87 mfsprg r4,5
88 stw r4,SL_SPRG5(r11)
89 mfsprg r4,6
90 stw r4,SL_SPRG6(r11)
91 mfsprg r4,7
92 stw r4,SL_SPRG7(r11)
93
94 /* Call the low level suspend stuff (we should probably have made
95 * a stackframe...
96 */
97 bl swsusp_save
98
99 /* Restore LR from the save area */
100 lis r11,swsusp_save_area@h
101 ori r11,r11,swsusp_save_area@l
102 lwz r0,SL_LR(r11)
103 mtlr r0
104
105 blr
106
107_GLOBAL(swsusp_arch_resume)
108 sync
109
110 /* Load ptr the list of pages to copy in r3 */
111 lis r11,(restore_pblist)@h
112 ori r11,r11,restore_pblist@l
113 lwz r3,0(r11)
114
115 /* Copy the pages. This is a very basic implementation, to
116 * be replaced by something more cache efficient */
1171:
118 li r0,256
119 mtctr r0
120 lwz r5,pbe_address(r3) /* source */
121 lwz r6,pbe_orig_address(r3) /* destination */
1222:
123 lwz r8,0(r5)
124 lwz r9,4(r5)
125 lwz r10,8(r5)
126 lwz r11,12(r5)
127 addi r5,r5,16
128 stw r8,0(r6)
129 stw r9,4(r6)
130 stw r10,8(r6)
131 stw r11,12(r6)
132 addi r6,r6,16
133 bdnz 2b
134 lwz r3,pbe_next(r3)
135 cmpwi 0,r3,0
136 bne 1b
137
138 bl flush_dcache_L1
139 bl flush_instruction_cache
140
141 lis r11,swsusp_save_area@h
142 ori r11,r11,swsusp_save_area@l
143
144 lwz r4,SL_SPRG0(r11)
145 mtsprg 0,r4
146 lwz r4,SL_SPRG1(r11)
147 mtsprg 1,r4
148 lwz r4,SL_SPRG2(r11)
149 mtsprg 2,r4
150 lwz r4,SL_SPRG3(r11)
151 mtsprg 3,r4
152 lwz r4,SL_SPRG4(r11)
153 mtsprg 4,r4
154 lwz r4,SL_SPRG5(r11)
155 mtsprg 5,r4
156 lwz r4,SL_SPRG6(r11)
157 mtsprg 6,r4
158 lwz r4,SL_SPRG7(r11)
159 mtsprg 7,r4
160
161 /* restore the MSR */
162 lwz r3,SL_MSR(r11)
163 mtmsr r3
164
165 /* Restore TB */
166 li r3,0
167 mtspr SPRN_TBWL,r3
168 lwz r3,SL_TBU(r11)
169 lwz r4,SL_TBL(r11)
170 mtspr SPRN_TBWU,r3
171 mtspr SPRN_TBWL,r4
172
173 /* Restore TCR and clear any pending bits in TSR. */
174 lwz r4,SL_TCR(r11)
175 mtspr SPRN_TCR,r4
176 lis r4, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
177 mtspr SPRN_TSR,r4
178
179 /* Kick decrementer */
180 li r0,1
181 mtdec r0
182
183 /* Restore the callee-saved registers and return */
184 lwz r0,SL_CR(r11)
185 mtcr r0
186 lwz r2,SL_R2(r11)
187 lmw r12,SL_R12(r11)
188 lwz r1,SL_SP(r11)
189 lwz r0,SL_LR(r11)
190 mtlr r0
191
192 li r3,0
193 blr
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 3031fc712ad0..25fc33984c2b 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 2 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
3 * Copyright 2007-2010 Freescale Semiconductor, Inc.
3 * 4 *
4 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
@@ -305,7 +306,7 @@ static inline int check_io_access(struct pt_regs *regs)
305#ifndef CONFIG_FSL_BOOKE 306#ifndef CONFIG_FSL_BOOKE
306#define get_mc_reason(regs) ((regs)->dsisr) 307#define get_mc_reason(regs) ((regs)->dsisr)
307#else 308#else
308#define get_mc_reason(regs) (mfspr(SPRN_MCSR) & MCSR_MASK) 309#define get_mc_reason(regs) (mfspr(SPRN_MCSR))
309#endif 310#endif
310#define REASON_FP ESR_FP 311#define REASON_FP ESR_FP
311#define REASON_ILLEGAL (ESR_PIL | ESR_PUO) 312#define REASON_ILLEGAL (ESR_PIL | ESR_PUO)
@@ -421,6 +422,91 @@ int machine_check_47x(struct pt_regs *regs)
421 return 0; 422 return 0;
422} 423}
423#elif defined(CONFIG_E500) 424#elif defined(CONFIG_E500)
425int machine_check_e500mc(struct pt_regs *regs)
426{
427 unsigned long mcsr = mfspr(SPRN_MCSR);
428 unsigned long reason = mcsr;
429 int recoverable = 1;
430
431 printk("Machine check in kernel mode.\n");
432 printk("Caused by (from MCSR=%lx): ", reason);
433
434 if (reason & MCSR_MCP)
435 printk("Machine Check Signal\n");
436
437 if (reason & MCSR_ICPERR) {
438 printk("Instruction Cache Parity Error\n");
439
440 /*
441 * This is recoverable by invalidating the i-cache.
442 */
443 mtspr(SPRN_L1CSR1, mfspr(SPRN_L1CSR1) | L1CSR1_ICFI);
444 while (mfspr(SPRN_L1CSR1) & L1CSR1_ICFI)
445 ;
446
447 /*
448 * This will generally be accompanied by an instruction
449 * fetch error report -- only treat MCSR_IF as fatal
450 * if it wasn't due to an L1 parity error.
451 */
452 reason &= ~MCSR_IF;
453 }
454
455 if (reason & MCSR_DCPERR_MC) {
456 printk("Data Cache Parity Error\n");
457 recoverable = 0;
458 }
459
460 if (reason & MCSR_L2MMU_MHIT) {
461 printk("Hit on multiple TLB entries\n");
462 recoverable = 0;
463 }
464
465 if (reason & MCSR_NMI)
466 printk("Non-maskable interrupt\n");
467
468 if (reason & MCSR_IF) {
469 printk("Instruction Fetch Error Report\n");
470 recoverable = 0;
471 }
472
473 if (reason & MCSR_LD) {
474 printk("Load Error Report\n");
475 recoverable = 0;
476 }
477
478 if (reason & MCSR_ST) {
479 printk("Store Error Report\n");
480 recoverable = 0;
481 }
482
483 if (reason & MCSR_LDG) {
484 printk("Guarded Load Error Report\n");
485 recoverable = 0;
486 }
487
488 if (reason & MCSR_TLBSYNC)
489 printk("Simultaneous tlbsync operations\n");
490
491 if (reason & MCSR_BSL2_ERR) {
492 printk("Level 2 Cache Error\n");
493 recoverable = 0;
494 }
495
496 if (reason & MCSR_MAV) {
497 u64 addr;
498
499 addr = mfspr(SPRN_MCAR);
500 addr |= (u64)mfspr(SPRN_MCARU) << 32;
501
502 printk("Machine Check %s Address: %#llx\n",
503 reason & MCSR_MEA ? "Effective" : "Physical", addr);
504 }
505
506 mtspr(SPRN_MCSR, mcsr);
507 return mfspr(SPRN_MCSR) == 0 && recoverable;
508}
509
424int machine_check_e500(struct pt_regs *regs) 510int machine_check_e500(struct pt_regs *regs)
425{ 511{
426 unsigned long reason = get_mc_reason(regs); 512 unsigned long reason = get_mc_reason(regs);
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index dcd01c82e701..8a0deefac08d 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -223,19 +223,17 @@ SECTIONS
223#endif 223#endif
224 224
225 /* The initial task and kernel stack */ 225 /* The initial task and kernel stack */
226 .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { 226 INIT_TASK_DATA_SECTION(THREAD_SIZE)
227 INIT_TASK_DATA(THREAD_SIZE)
228 }
229 227
230 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { 228 .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
231 PAGE_ALIGNED_DATA(PAGE_SIZE) 229 PAGE_ALIGNED_DATA(PAGE_SIZE)
232 } 230 }
233 231
234 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { 232 .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) {
235 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) 233 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
236 } 234 }
237 235
238 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { 236 .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) {
239 READ_MOSTLY_DATA(L1_CACHE_BYTES) 237 READ_MOSTLY_DATA(L1_CACHE_BYTES)
240 } 238 }
241 239
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index eeba0a70e466..69d668c072ae 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -171,6 +171,17 @@ config ISS4xx
171 help 171 help
172 This option enables support for the IBM ISS simulation environment 172 This option enables support for the IBM ISS simulation environment
173 173
174config ICON
175 bool "Icon"
176 depends on 44x
177 default n
178 select PPC44x_SIMPLE
179 select 440SPe
180 select PCI
181 select PPC4xx_PCI_EXPRESS
182 help
183 This option enables support for the AMCC PPC440SPe evaluation board.
184
174#config LUAN 185#config LUAN
175# bool "Luan" 186# bool "Luan"
176# depends on 44x 187# depends on 44x
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c
index e8c23ccaa1fc..5f7a29d7f590 100644
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -61,7 +61,8 @@ static char *board[] __initdata = {
61 "amcc,redwood", 61 "amcc,redwood",
62 "amcc,sequoia", 62 "amcc,sequoia",
63 "amcc,taishan", 63 "amcc,taishan",
64 "amcc,yosemite" 64 "amcc,yosemite",
65 "mosaixtech,icon"
65}; 66};
66 67
67static int __init ppc44x_probe(void) 68static int __init ppc44x_probe(void)
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index f0684c8ac960..8fe87fc61485 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006-2007. All rights reserved. 2 * Copyright (C) Freescale Semicondutor, Inc. 2006-2010. All rights reserved.
3 * 3 *
4 * Author: Andy Fleming <afleming@freescale.com> 4 * Author: Andy Fleming <afleming@freescale.com>
5 * 5 *
@@ -154,6 +154,10 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
154 * Setup the architecture 154 * Setup the architecture
155 * 155 *
156 */ 156 */
157#ifdef CONFIG_SMP
158extern void __init mpc85xx_smp_init(void);
159#endif
160
157static void __init mpc85xx_mds_setup_arch(void) 161static void __init mpc85xx_mds_setup_arch(void)
158{ 162{
159 struct device_node *np; 163 struct device_node *np;
@@ -194,6 +198,10 @@ static void __init mpc85xx_mds_setup_arch(void)
194 } 198 }
195#endif 199#endif
196 200
201#ifdef CONFIG_SMP
202 mpc85xx_smp_init();
203#endif
204
197#ifdef CONFIG_QUICC_ENGINE 205#ifdef CONFIG_QUICC_ENGINE
198 np = of_find_compatible_node(NULL, NULL, "fsl,qe"); 206 np = of_find_compatible_node(NULL, NULL, "fsl,qe");
199 if (!np) { 207 if (!np) {
@@ -271,9 +279,49 @@ static void __init mpc85xx_mds_setup_arch(void)
271 BCSR_UCC_RGMII, BCSR_UCC_RTBI); 279 BCSR_UCC_RGMII, BCSR_UCC_RTBI);
272 } 280 }
273 281
282 } else if (machine_is(p1021_mds)) {
283#define BCSR11_ENET_MICRST (0x1 << 5)
284 /* Reset Micrel PHY */
285 clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
286 setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
274 } 287 }
288
275 iounmap(bcsr_regs); 289 iounmap(bcsr_regs);
276 } 290 }
291
292 if (machine_is(p1021_mds)) {
293#define MPC85xx_PMUXCR_OFFSET 0x60
294#define MPC85xx_PMUXCR_QE0 0x00008000
295#define MPC85xx_PMUXCR_QE3 0x00001000
296#define MPC85xx_PMUXCR_QE9 0x00000040
297#define MPC85xx_PMUXCR_QE12 0x00000008
298 static __be32 __iomem *pmuxcr;
299
300 np = of_find_node_by_name(NULL, "global-utilities");
301
302 if (np) {
303 pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET;
304
305 if (!pmuxcr)
306 printk(KERN_EMERG "Error: Alternate function"
307 " signal multiplex control register not"
308 " mapped!\n");
309 else
310 /* P1021 has pins muxed for QE and other functions. To
311 * enable QE UEC mode, we need to set bit QE0 for UCC1
312 * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
313 * and QE12 for QE MII management singals in PMUXCR
314 * register.
315 */
316 setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 |
317 MPC85xx_PMUXCR_QE3 |
318 MPC85xx_PMUXCR_QE9 |
319 MPC85xx_PMUXCR_QE12);
320
321 of_node_put(np);
322 }
323
324 }
277#endif /* CONFIG_QUICC_ENGINE */ 325#endif /* CONFIG_QUICC_ENGINE */
278 326
279#ifdef CONFIG_SWIOTLB 327#ifdef CONFIG_SWIOTLB
@@ -330,6 +378,16 @@ static struct of_device_id mpc85xx_ids[] = {
330 {}, 378 {},
331}; 379};
332 380
381static struct of_device_id p1021_ids[] = {
382 { .type = "soc", },
383 { .compatible = "soc", },
384 { .compatible = "simple-bus", },
385 { .type = "qe", },
386 { .compatible = "fsl,qe", },
387 { .compatible = "gianfar", },
388 {},
389};
390
333static int __init mpc85xx_publish_devices(void) 391static int __init mpc85xx_publish_devices(void)
334{ 392{
335 if (machine_is(mpc8568_mds)) 393 if (machine_is(mpc8568_mds))
@@ -342,11 +400,22 @@ static int __init mpc85xx_publish_devices(void)
342 400
343 return 0; 401 return 0;
344} 402}
403
404static int __init p1021_publish_devices(void)
405{
406 /* Publish the QE devices */
407 of_platform_bus_probe(NULL, p1021_ids, NULL);
408
409 return 0;
410}
411
345machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); 412machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
346machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); 413machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
414machine_device_initcall(p1021_mds, p1021_publish_devices);
347 415
348machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); 416machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
349machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); 417machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
418machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
350 419
351static void __init mpc85xx_mds_pic_init(void) 420static void __init mpc85xx_mds_pic_init(void)
352{ 421{
@@ -366,7 +435,7 @@ static void __init mpc85xx_mds_pic_init(void)
366 435
367 mpic = mpic_alloc(np, r.start, 436 mpic = mpic_alloc(np, r.start,
368 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | 437 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
369 MPIC_BROKEN_FRR_NIRQS, 438 MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
370 0, 256, " OpenPIC "); 439 0, 256, " OpenPIC ");
371 BUG_ON(mpic == NULL); 440 BUG_ON(mpic == NULL);
372 of_node_put(np); 441 of_node_put(np);
@@ -380,7 +449,11 @@ static void __init mpc85xx_mds_pic_init(void)
380 if (!np) 449 if (!np)
381 return; 450 return;
382 } 451 }
383 qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); 452 if (machine_is(p1021_mds))
453 qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
454 qe_ic_cascade_high_mpic);
455 else
456 qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
384 of_node_put(np); 457 of_node_put(np);
385#endif /* CONFIG_QUICC_ENGINE */ 458#endif /* CONFIG_QUICC_ENGINE */
386} 459}
@@ -426,3 +499,26 @@ define_machine(mpc8569_mds) {
426 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 499 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
427#endif 500#endif
428}; 501};
502
503static int __init p1021_mds_probe(void)
504{
505 unsigned long root = of_get_flat_dt_root();
506
507 return of_flat_dt_is_compatible(root, "fsl,P1021MDS");
508
509}
510
511define_machine(p1021_mds) {
512 .name = "P1021 MDS",
513 .probe = p1021_mds_probe,
514 .setup_arch = mpc85xx_mds_setup_arch,
515 .init_IRQ = mpc85xx_mds_pic_init,
516 .get_irq = mpic_get_irq,
517 .restart = fsl_rstcr_restart,
518 .calibrate_decr = generic_calibrate_decr,
519 .progress = udbg_progress,
520#ifdef CONFIG_PCI
521 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
522#endif
523};
524
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 22667a09d40e..4326b737d913 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -1066,7 +1066,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
1066 fbase = _ALIGN_UP(fbase, 1 << IO_SEGMENT_SHIFT); 1066 fbase = _ALIGN_UP(fbase, 1 << IO_SEGMENT_SHIFT);
1067 fsize = lmb_phys_mem_size(); 1067 fsize = lmb_phys_mem_size();
1068 1068
1069 if ((fbase + fsize) <= 0x800000000) 1069 if ((fbase + fsize) <= 0x800000000ul)
1070 hbase = 0; /* use the device tree window */ 1070 hbase = 0; /* use the device tree window */
1071 else { 1071 else {
1072 /* If we're over 32 GB we need to cheat. We can't map all of 1072 /* If we're over 32 GB we need to cheat. We can't map all of
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index a7be144f5874..962c2d8dd8d9 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. All rights reserved. 2 * Copyright (C) 2007-2010 Freescale Semiconductor, Inc.
3 * 3 *
4 * Author: Tony Li <tony.li@freescale.com> 4 * Author: Tony Li <tony.li@freescale.com>
5 * Jason Jin <Jason.jin@freescale.com> 5 * Jason Jin <Jason.jin@freescale.com>
@@ -22,14 +22,20 @@
22#include <asm/prom.h> 22#include <asm/prom.h>
23#include <asm/hw_irq.h> 23#include <asm/hw_irq.h>
24#include <asm/ppc-pci.h> 24#include <asm/ppc-pci.h>
25#include <asm/mpic.h>
25#include "fsl_msi.h" 26#include "fsl_msi.h"
26 27
28LIST_HEAD(msi_head);
29
27struct fsl_msi_feature { 30struct fsl_msi_feature {
28 u32 fsl_pic_ip; 31 u32 fsl_pic_ip;
29 u32 msiir_offset; 32 u32 msiir_offset;
30}; 33};
31 34
32static struct fsl_msi *fsl_msi; 35struct fsl_msi_cascade_data {
36 struct fsl_msi *msi_data;
37 int index;
38};
33 39
34static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg) 40static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg)
35{ 41{
@@ -54,10 +60,12 @@ static struct irq_chip fsl_msi_chip = {
54static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, 60static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
55 irq_hw_number_t hw) 61 irq_hw_number_t hw)
56{ 62{
63 struct fsl_msi *msi_data = h->host_data;
57 struct irq_chip *chip = &fsl_msi_chip; 64 struct irq_chip *chip = &fsl_msi_chip;
58 65
59 irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING; 66 irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING;
60 67
68 set_irq_chip_data(virq, msi_data);
61 set_irq_chip_and_handler(virq, chip, handle_edge_irq); 69 set_irq_chip_and_handler(virq, chip, handle_edge_irq);
62 70
63 return 0; 71 return 0;
@@ -96,11 +104,12 @@ static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type)
96static void fsl_teardown_msi_irqs(struct pci_dev *pdev) 104static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
97{ 105{
98 struct msi_desc *entry; 106 struct msi_desc *entry;
99 struct fsl_msi *msi_data = fsl_msi; 107 struct fsl_msi *msi_data;
100 108
101 list_for_each_entry(entry, &pdev->msi_list, list) { 109 list_for_each_entry(entry, &pdev->msi_list, list) {
102 if (entry->irq == NO_IRQ) 110 if (entry->irq == NO_IRQ)
103 continue; 111 continue;
112 msi_data = get_irq_data(entry->irq);
104 set_irq_msi(entry->irq, NULL); 113 set_irq_msi(entry->irq, NULL);
105 msi_bitmap_free_hwirqs(&msi_data->bitmap, 114 msi_bitmap_free_hwirqs(&msi_data->bitmap,
106 virq_to_hw(entry->irq), 1); 115 virq_to_hw(entry->irq), 1);
@@ -111,9 +120,10 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
111} 120}
112 121
113static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, 122static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
114 struct msi_msg *msg) 123 struct msi_msg *msg,
124 struct fsl_msi *fsl_msi_data)
115{ 125{
116 struct fsl_msi *msi_data = fsl_msi; 126 struct fsl_msi *msi_data = fsl_msi_data;
117 struct pci_controller *hose = pci_bus_to_host(pdev->bus); 127 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
118 u32 base = 0; 128 u32 base = 0;
119 129
@@ -130,14 +140,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
130 140
131static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) 141static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
132{ 142{
133 int rc, hwirq; 143 int rc, hwirq = -ENOMEM;
134 unsigned int virq; 144 unsigned int virq;
135 struct msi_desc *entry; 145 struct msi_desc *entry;
136 struct msi_msg msg; 146 struct msi_msg msg;
137 struct fsl_msi *msi_data = fsl_msi; 147 struct fsl_msi *msi_data;
138 148
139 list_for_each_entry(entry, &pdev->msi_list, list) { 149 list_for_each_entry(entry, &pdev->msi_list, list) {
140 hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); 150 list_for_each_entry(msi_data, &msi_head, list) {
151 hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
152 if (hwirq >= 0)
153 break;
154 }
155
141 if (hwirq < 0) { 156 if (hwirq < 0) {
142 rc = hwirq; 157 rc = hwirq;
143 pr_debug("%s: fail allocating msi interrupt\n", 158 pr_debug("%s: fail allocating msi interrupt\n",
@@ -154,25 +169,31 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
154 rc = -ENOSPC; 169 rc = -ENOSPC;
155 goto out_free; 170 goto out_free;
156 } 171 }
172 set_irq_data(virq, msi_data);
157 set_irq_msi(virq, entry); 173 set_irq_msi(virq, entry);
158 174
159 fsl_compose_msi_msg(pdev, hwirq, &msg); 175 fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data);
160 write_msi_msg(virq, &msg); 176 write_msi_msg(virq, &msg);
161 } 177 }
162 return 0; 178 return 0;
163 179
164out_free: 180out_free:
181 /* free by the caller of this function */
165 return rc; 182 return rc;
166} 183}
167 184
168static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) 185static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
169{ 186{
170 unsigned int cascade_irq; 187 unsigned int cascade_irq;
171 struct fsl_msi *msi_data = fsl_msi; 188 struct fsl_msi *msi_data;
172 int msir_index = -1; 189 int msir_index = -1;
173 u32 msir_value = 0; 190 u32 msir_value = 0;
174 u32 intr_index; 191 u32 intr_index;
175 u32 have_shift = 0; 192 u32 have_shift = 0;
193 struct fsl_msi_cascade_data *cascade_data;
194
195 cascade_data = (struct fsl_msi_cascade_data *)get_irq_data(irq);
196 msi_data = cascade_data->msi_data;
176 197
177 raw_spin_lock(&desc->lock); 198 raw_spin_lock(&desc->lock);
178 if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { 199 if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
@@ -187,13 +208,13 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
187 if (unlikely(desc->status & IRQ_INPROGRESS)) 208 if (unlikely(desc->status & IRQ_INPROGRESS))
188 goto unlock; 209 goto unlock;
189 210
190 msir_index = (int)desc->handler_data; 211 msir_index = cascade_data->index;
191 212
192 if (msir_index >= NR_MSI_REG) 213 if (msir_index >= NR_MSI_REG)
193 cascade_irq = NO_IRQ; 214 cascade_irq = NO_IRQ;
194 215
195 desc->status |= IRQ_INPROGRESS; 216 desc->status |= IRQ_INPROGRESS;
196 switch (fsl_msi->feature & FSL_PIC_IP_MASK) { 217 switch (msi_data->feature & FSL_PIC_IP_MASK) {
197 case FSL_PIC_IP_MPIC: 218 case FSL_PIC_IP_MPIC:
198 msir_value = fsl_msi_read(msi_data->msi_regs, 219 msir_value = fsl_msi_read(msi_data->msi_regs,
199 msir_index * 0x10); 220 msir_index * 0x10);
@@ -229,6 +250,30 @@ unlock:
229 raw_spin_unlock(&desc->lock); 250 raw_spin_unlock(&desc->lock);
230} 251}
231 252
253static int fsl_of_msi_remove(struct of_device *ofdev)
254{
255 struct fsl_msi *msi = ofdev->dev.platform_data;
256 int virq, i;
257 struct fsl_msi_cascade_data *cascade_data;
258
259 if (msi->list.prev != NULL)
260 list_del(&msi->list);
261 for (i = 0; i < NR_MSI_REG; i++) {
262 virq = msi->msi_virqs[i];
263 if (virq != NO_IRQ) {
264 cascade_data = get_irq_data(virq);
265 kfree(cascade_data);
266 irq_dispose_mapping(virq);
267 }
268 }
269 if (msi->bitmap.bitmap)
270 msi_bitmap_free(&msi->bitmap);
271 iounmap(msi->msi_regs);
272 kfree(msi);
273
274 return 0;
275}
276
232static int __devinit fsl_of_msi_probe(struct of_device *dev, 277static int __devinit fsl_of_msi_probe(struct of_device *dev,
233 const struct of_device_id *match) 278 const struct of_device_id *match)
234{ 279{
@@ -239,15 +284,18 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
239 int virt_msir; 284 int virt_msir;
240 const u32 *p; 285 const u32 *p;
241 struct fsl_msi_feature *features = match->data; 286 struct fsl_msi_feature *features = match->data;
287 struct fsl_msi_cascade_data *cascade_data = NULL;
288 int len;
289 u32 offset;
242 290
243 printk(KERN_DEBUG "Setting up Freescale MSI support\n"); 291 printk(KERN_DEBUG "Setting up Freescale MSI support\n");
244 292
245 msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); 293 msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL);
246 if (!msi) { 294 if (!msi) {
247 dev_err(&dev->dev, "No memory for MSI structure\n"); 295 dev_err(&dev->dev, "No memory for MSI structure\n");
248 err = -ENOMEM; 296 return -ENOMEM;
249 goto error_out;
250 } 297 }
298 dev->dev.platform_data = msi;
251 299
252 msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, 300 msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR,
253 NR_MSI_IRQS, &fsl_msi_host_ops, 0); 301 NR_MSI_IRQS, &fsl_msi_host_ops, 0);
@@ -298,27 +346,47 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
298 err = -EINVAL; 346 err = -EINVAL;
299 goto error_out; 347 goto error_out;
300 } 348 }
349 offset = 0;
350 p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
351 if (p)
352 offset = *p / IRQS_PER_MSI_REG;
301 353
302 count /= sizeof(u32); 354 count /= sizeof(u32);
303 for (i = 0; i < count / 2; i++) { 355 for (i = 0; i < min(count / 2, NR_MSI_REG); i++) {
304 if (i > NR_MSI_REG)
305 break;
306 virt_msir = irq_of_parse_and_map(dev->dev.of_node, i); 356 virt_msir = irq_of_parse_and_map(dev->dev.of_node, i);
307 if (virt_msir != NO_IRQ) { 357 if (virt_msir != NO_IRQ) {
308 set_irq_data(virt_msir, (void *)i); 358 cascade_data = kzalloc(
359 sizeof(struct fsl_msi_cascade_data),
360 GFP_KERNEL);
361 if (!cascade_data) {
362 dev_err(&dev->dev,
363 "No memory for MSI cascade data\n");
364 err = -ENOMEM;
365 goto error_out;
366 }
367 msi->msi_virqs[i] = virt_msir;
368 cascade_data->index = i + offset;
369 cascade_data->msi_data = msi;
370 set_irq_data(virt_msir, (void *)cascade_data);
309 set_irq_chained_handler(virt_msir, fsl_msi_cascade); 371 set_irq_chained_handler(virt_msir, fsl_msi_cascade);
310 } 372 }
311 } 373 }
312 374
313 fsl_msi = msi; 375 list_add_tail(&msi->list, &msi_head);
314 376
315 WARN_ON(ppc_md.setup_msi_irqs); 377 /* The multiple setting ppc_md.setup_msi_irqs will not harm things */
316 ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; 378 if (!ppc_md.setup_msi_irqs) {
317 ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; 379 ppc_md.setup_msi_irqs = fsl_setup_msi_irqs;
318 ppc_md.msi_check_device = fsl_msi_check_device; 380 ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs;
381 ppc_md.msi_check_device = fsl_msi_check_device;
382 } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) {
383 dev_err(&dev->dev, "Different MSI driver already installed!\n");
384 err = -ENODEV;
385 goto error_out;
386 }
319 return 0; 387 return 0;
320error_out: 388error_out:
321 kfree(msi); 389 fsl_of_msi_remove(dev);
322 return err; 390 return err;
323} 391}
324 392
@@ -351,6 +419,7 @@ static struct of_platform_driver fsl_of_msi_driver = {
351 .of_match_table = fsl_of_msi_ids, 419 .of_match_table = fsl_of_msi_ids,
352 }, 420 },
353 .probe = fsl_of_msi_probe, 421 .probe = fsl_of_msi_probe,
422 .remove = fsl_of_msi_remove,
354}; 423};
355 424
356static __init int fsl_of_msi_init(void) 425static __init int fsl_of_msi_init(void)
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index 331c7e7025b7..624580c252d7 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -32,8 +32,11 @@ struct fsl_msi {
32 u32 msi_addr_hi; 32 u32 msi_addr_hi;
33 void __iomem *msi_regs; 33 void __iomem *msi_regs;
34 u32 feature; 34 u32 feature;
35 int msi_virqs[NR_MSI_REG];
35 36
36 struct msi_bitmap bitmap; 37 struct msi_bitmap bitmap;
38
39 struct list_head list; /* support multiple MSI banks */
37}; 40};
38 41
39#endif /* _POWERPC_SYSDEV_FSL_MSI_H */ 42#endif /* _POWERPC_SYSDEV_FSL_MSI_H */
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index cd37e49e7034..30e1626b2e85 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1426,7 +1426,7 @@ int fsl_rio_setup(struct of_device *dev)
1426 port->iores.flags = IORESOURCE_MEM; 1426 port->iores.flags = IORESOURCE_MEM;
1427 port->iores.name = "rio_io_win"; 1427 port->iores.name = "rio_io_win";
1428 1428
1429 priv->pwirq = irq_of_parse_and_map(dev->node, 0); 1429 priv->pwirq = irq_of_parse_and_map(dev->dev.of_node, 0);
1430 priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2); 1430 priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2);
1431 priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3); 1431 priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3);
1432 priv->rxirq = irq_of_parse_and_map(dev->dev.of_node, 4); 1432 priv->rxirq = irq_of_parse_and_map(dev->dev.of_node, 4);
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 106d767bf65b..156aa7d36258 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -974,6 +974,123 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata =
974 .setup_utl = ppc460ex_pciex_init_utl, 974 .setup_utl = ppc460ex_pciex_init_utl,
975}; 975};
976 976
977static int __init ppc460sx_pciex_core_init(struct device_node *np)
978{
979 /* HSS drive amplitude */
980 mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211);
981 mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211);
982 mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211);
983 mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211);
984 mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211);
985 mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211);
986 mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211);
987 mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211);
988
989 mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211);
990 mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211);
991 mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211);
992 mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211);
993
994 mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211);
995 mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211);
996 mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211);
997 mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211);
998
999 /* HSS TX pre-emphasis */
1000 mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987);
1001 mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987);
1002 mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987);
1003 mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987);
1004 mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987);
1005 mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987);
1006 mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987);
1007 mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987);
1008
1009 mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987);
1010 mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987);
1011 mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987);
1012 mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987);
1013
1014 mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987);
1015 mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987);
1016 mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987);
1017 mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987);
1018
1019 /* HSS TX calibration control */
1020 mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222);
1021 mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000);
1022 mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000);
1023
1024 /* HSS TX slew control */
1025 mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF);
1026 mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000);
1027 mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000);
1028
1029 udelay(100);
1030
1031 /* De-assert PLLRESET */
1032 dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0);
1033
1034 /* Reset DL, UTL, GPL before configuration */
1035 mtdcri(SDR0, PESDR0_460SX_RCSSET,
1036 PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
1037 mtdcri(SDR0, PESDR1_460SX_RCSSET,
1038 PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
1039 mtdcri(SDR0, PESDR2_460SX_RCSSET,
1040 PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
1041
1042 udelay(100);
1043
1044 /*
1045 * If bifurcation is not enabled, u-boot would have disabled the
1046 * third PCIe port
1047 */
1048 if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) ==
1049 0x00000001)) {
1050 printk(KERN_INFO "PCI: PCIE bifurcation setup successfully.\n");
1051 printk(KERN_INFO "PCI: Total 3 PCIE ports are present\n");
1052 return 3;
1053 }
1054
1055 printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n");
1056 return 2;
1057}
1058
1059static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1060{
1061
1062 if (port->endpoint)
1063 dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
1064 0x01000000, 0);
1065 else
1066 dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
1067 0, 0x01000000);
1068
1069 /*Gen-1*/
1070 mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000);
1071
1072 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
1073 (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL),
1074 PESDRx_RCSSET_RSTPYN);
1075
1076 port->has_ibpre = 1;
1077
1078 return 0;
1079}
1080
1081static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
1082{
1083 /* Max 128 Bytes */
1084 out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000);
1085 return 0;
1086}
1087
1088static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
1089 .core_init = ppc460sx_pciex_core_init,
1090 .port_init_hw = ppc460sx_pciex_init_port_hw,
1091 .setup_utl = ppc460sx_pciex_init_utl,
1092};
1093
977#endif /* CONFIG_44x */ 1094#endif /* CONFIG_44x */
978 1095
979#ifdef CONFIG_40x 1096#ifdef CONFIG_40x
@@ -1089,6 +1206,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
1089 } 1206 }
1090 if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) 1207 if (of_device_is_compatible(np, "ibm,plb-pciex-460ex"))
1091 ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; 1208 ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops;
1209 if (of_device_is_compatible(np, "ibm,plb-pciex-460sx"))
1210 ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops;
1092#endif /* CONFIG_44x */ 1211#endif /* CONFIG_44x */
1093#ifdef CONFIG_40x 1212#ifdef CONFIG_40x
1094 if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) 1213 if (of_device_is_compatible(np, "ibm,plb-pciex-405ex"))
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h
index d04e40b306fb..56d9e5deccbf 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.h
+++ b/arch/powerpc/sysdev/ppc4xx_pci.h
@@ -324,6 +324,64 @@
324#define PESDR0_460EX_IHS2 0x036D 324#define PESDR0_460EX_IHS2 0x036D
325 325
326/* 326/*
327 * 460SX addtional DCRs
328 */
329#define PESDRn_460SX_RCEI 0x02
330
331#define PESDR0_460SX_HSSL0DAMP 0x320
332#define PESDR0_460SX_HSSL1DAMP 0x321
333#define PESDR0_460SX_HSSL2DAMP 0x322
334#define PESDR0_460SX_HSSL3DAMP 0x323
335#define PESDR0_460SX_HSSL4DAMP 0x324
336#define PESDR0_460SX_HSSL5DAMP 0x325
337#define PESDR0_460SX_HSSL6DAMP 0x326
338#define PESDR0_460SX_HSSL7DAMP 0x327
339
340#define PESDR1_460SX_HSSL0DAMP 0x354
341#define PESDR1_460SX_HSSL1DAMP 0x355
342#define PESDR1_460SX_HSSL2DAMP 0x356
343#define PESDR1_460SX_HSSL3DAMP 0x357
344
345#define PESDR2_460SX_HSSL0DAMP 0x384
346#define PESDR2_460SX_HSSL1DAMP 0x385
347#define PESDR2_460SX_HSSL2DAMP 0x386
348#define PESDR2_460SX_HSSL3DAMP 0x387
349
350#define PESDR0_460SX_HSSL0COEFA 0x328
351#define PESDR0_460SX_HSSL1COEFA 0x329
352#define PESDR0_460SX_HSSL2COEFA 0x32A
353#define PESDR0_460SX_HSSL3COEFA 0x32B
354#define PESDR0_460SX_HSSL4COEFA 0x32C
355#define PESDR0_460SX_HSSL5COEFA 0x32D
356#define PESDR0_460SX_HSSL6COEFA 0x32E
357#define PESDR0_460SX_HSSL7COEFA 0x32F
358
359#define PESDR1_460SX_HSSL0COEFA 0x358
360#define PESDR1_460SX_HSSL1COEFA 0x359
361#define PESDR1_460SX_HSSL2COEFA 0x35A
362#define PESDR1_460SX_HSSL3COEFA 0x35B
363
364#define PESDR2_460SX_HSSL0COEFA 0x388
365#define PESDR2_460SX_HSSL1COEFA 0x389
366#define PESDR2_460SX_HSSL2COEFA 0x38A
367#define PESDR2_460SX_HSSL3COEFA 0x38B
368
369#define PESDR0_460SX_HSSL1CALDRV 0x339
370#define PESDR1_460SX_HSSL1CALDRV 0x361
371#define PESDR2_460SX_HSSL1CALDRV 0x391
372
373#define PESDR0_460SX_HSSSLEW 0x338
374#define PESDR1_460SX_HSSSLEW 0x360
375#define PESDR2_460SX_HSSSLEW 0x390
376
377#define PESDR0_460SX_HSSCTLSET 0x31E
378#define PESDR1_460SX_HSSCTLSET 0x352
379#define PESDR2_460SX_HSSCTLSET 0x382
380
381#define PESDR0_460SX_RCSSET 0x304
382#define PESDR1_460SX_RCSSET 0x344
383#define PESDR2_460SX_RCSSET 0x374
384/*
327 * Of the above, some are common offsets from the base 385 * Of the above, some are common offsets from the base
328 */ 386 */
329#define PESDRn_UTLSET1 0x00 387#define PESDRn_UTLSET1 0x00
diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h
index 9b866816863c..24aafa68b643 100644
--- a/arch/s390/include/asm/cache.h
+++ b/arch/s390/include/asm/cache.h
@@ -14,6 +14,6 @@
14#define L1_CACHE_BYTES 256 14#define L1_CACHE_BYTES 256
15#define L1_CACHE_SHIFT 8 15#define L1_CACHE_SHIFT 8
16 16
17#define __read_mostly __attribute__((__section__(".data.read_mostly"))) 17#define __read_mostly __attribute__((__section__(".data..read_mostly")))
18 18
19#endif 19#endif
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index c56d3f56d020..1f066e46e83e 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -264,7 +264,7 @@ restore_registers:
264 lghi %r2,0 264 lghi %r2,0
265 br %r14 265 br %r14
266 266
267 .section .data.nosave,"aw",@progbits 267 .section .data..nosave,"aw",@progbits
268 .align 8 268 .align 8
269.Ldisabled_wait_31: 269.Ldisabled_wait_31:
270 .long 0x000a0000,0x00000000 270 .long 0x000a0000,0x00000000
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index c5ee4ce60b57..573fca1fbd9b 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -9,7 +9,7 @@ config SUPERH
9 def_bool y 9 def_bool y
10 select EMBEDDED 10 select EMBEDDED
11 select HAVE_CLK 11 select HAVE_CLK
12 select HAVE_IDE 12 select HAVE_IDE if HAS_IOPORT
13 select HAVE_LMB 13 select HAVE_LMB
14 select HAVE_OPROFILE 14 select HAVE_OPROFILE
15 select HAVE_GENERIC_DMA_COHERENT 15 select HAVE_GENERIC_DMA_COHERENT
@@ -174,6 +174,9 @@ config ARCH_HAS_DEFAULT_IDLE
174config ARCH_HAS_CPU_IDLE_WAIT 174config ARCH_HAS_CPU_IDLE_WAIT
175 def_bool y 175 def_bool y
176 176
177config NO_IOPORT
178 bool
179
177config IO_TRAPPED 180config IO_TRAPPED
178 bool 181 bool
179 182
@@ -776,6 +779,17 @@ config ENTRY_OFFSET
776 default "0x00010000" if PAGE_SIZE_64KB 779 default "0x00010000" if PAGE_SIZE_64KB
777 default "0x00000000" 780 default "0x00000000"
778 781
782config ROMIMAGE_MMCIF
783 bool "Include MMCIF loader in romImage (EXPERIMENTAL)"
784 depends on CPU_SUBTYPE_SH7724 && EXPERIMENTAL
785 help
786 Say Y here to include experimental MMCIF loading code in
787 romImage. With this enabled it is possible to write the romImage
788 kernel image to an MMC card and boot the kernel straight from
789 the reset vector. At reset the processor Mask ROM will load the
790 first part of the romImage which in turn loads the rest the kernel
791 image to RAM using the MMCIF hardware block.
792
779choice 793choice
780 prompt "Kernel command line" 794 prompt "Kernel command line"
781 optional 795 optional
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 938e87d51482..07b35ca2f644 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -154,6 +154,7 @@ config SH_SDK7786
154 bool "SDK7786" 154 bool "SDK7786"
155 depends on CPU_SUBTYPE_SH7786 155 depends on CPU_SUBTYPE_SH7786
156 select SYS_SUPPORTS_PCI 156 select SYS_SUPPORTS_PCI
157 select NO_IOPORT if !PCI
157 help 158 help
158 Select SDK7786 if configuring for a Renesas Technology Europe 159 Select SDK7786 if configuring for a Renesas Technology Europe
159 SH7786-65nm board. 160 SH7786-65nm board.
@@ -190,6 +191,7 @@ config SH_URQUELL
190 depends on CPU_SUBTYPE_SH7786 191 depends on CPU_SUBTYPE_SH7786
191 select ARCH_REQUIRE_GPIOLIB 192 select ARCH_REQUIRE_GPIOLIB
192 select SYS_SUPPORTS_PCI 193 select SYS_SUPPORTS_PCI
194 select NO_IOPORT if !PCI
193 195
194config SH_MIGOR 196config SH_MIGOR
195 bool "Migo-R" 197 bool "Migo-R"
@@ -286,6 +288,7 @@ config SH_LBOX_RE2
286config SH_X3PROTO 288config SH_X3PROTO
287 bool "SH-X3 Prototype board" 289 bool "SH-X3 Prototype board"
288 depends on CPU_SUBTYPE_SHX3 290 depends on CPU_SUBTYPE_SHX3
291 select NO_IOPORT if !PCI
289 292
290config SH_MAGIC_PANEL_R2 293config SH_MAGIC_PANEL_R2
291 bool "Magic Panel R2" 294 bool "Magic Panel R2"
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 57e37e284208..3a170bd3f3d0 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -328,7 +328,7 @@ static struct soc_camera_platform_info camera_info = {
328 .set_capture = camera_set_capture, 328 .set_capture = camera_set_capture,
329}; 329};
330 330
331struct soc_camera_link camera_link = { 331static struct soc_camera_link camera_link = {
332 .bus_id = 0, 332 .bus_id = 0,
333 .add_device = ap325rxa_camera_add, 333 .add_device = ap325rxa_camera_add,
334 .del_device = ap325rxa_camera_del, 334 .del_device = ap325rxa_camera_del,
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 49714258732e..be1d114d3a43 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -12,6 +12,8 @@
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/mfd/sh_mobile_sdhi.h> 14#include <linux/mfd/sh_mobile_sdhi.h>
15#include <linux/mmc/host.h>
16#include <linux/mmc/sh_mmcif.h>
15#include <linux/mtd/physmap.h> 17#include <linux/mtd/physmap.h>
16#include <linux/gpio.h> 18#include <linux/gpio.h>
17#include <linux/interrupt.h> 19#include <linux/interrupt.h>
@@ -26,7 +28,6 @@
26#include <linux/mmc/host.h> 28#include <linux/mmc/host.h>
27#include <linux/input.h> 29#include <linux/input.h>
28#include <linux/input/sh_keysc.h> 30#include <linux/input/sh_keysc.h>
29#include <linux/mfd/sh_mobile_sdhi.h>
30#include <video/sh_mobile_lcdc.h> 31#include <video/sh_mobile_lcdc.h>
31#include <sound/sh_fsi.h> 32#include <sound/sh_fsi.h>
32#include <media/sh_mobile_ceu.h> 33#include <media/sh_mobile_ceu.h>
@@ -139,7 +140,7 @@ static struct resource sh_eth_resources[] = {
139 }, 140 },
140}; 141};
141 142
142struct sh_eth_plat_data sh_eth_plat = { 143static struct sh_eth_plat_data sh_eth_plat = {
143 .phy = 0x1f, /* SMSC LAN8700 */ 144 .phy = 0x1f, /* SMSC LAN8700 */
144 .edmac_endian = EDMAC_LITTLE_ENDIAN, 145 .edmac_endian = EDMAC_LITTLE_ENDIAN,
145 .ether_link_active_low = 1 146 .ether_link_active_low = 1
@@ -159,7 +160,7 @@ static struct platform_device sh_eth_device = {
159}; 160};
160 161
161/* USB0 host */ 162/* USB0 host */
162void usb0_port_power(int port, int power) 163static void usb0_port_power(int port, int power)
163{ 164{
164 gpio_set_value(GPIO_PTB4, power); 165 gpio_set_value(GPIO_PTB4, power);
165} 166}
@@ -195,7 +196,7 @@ static struct platform_device usb0_host_device = {
195}; 196};
196 197
197/* USB1 host/function */ 198/* USB1 host/function */
198void usb1_port_power(int port, int power) 199static void usb1_port_power(int port, int power)
199{ 200{
200 gpio_set_value(GPIO_PTB5, power); 201 gpio_set_value(GPIO_PTB5, power);
201} 202}
@@ -421,7 +422,7 @@ static int ts_init(void)
421 return 0; 422 return 0;
422} 423}
423 424
424struct tsc2007_platform_data tsc2007_info = { 425static struct tsc2007_platform_data tsc2007_info = {
425 .model = 2007, 426 .model = 2007,
426 .x_plate_ohms = 180, 427 .x_plate_ohms = 180,
427 .get_pendown_state = ts_get_pendown_state, 428 .get_pendown_state = ts_get_pendown_state,
@@ -436,7 +437,7 @@ static struct i2c_board_info ts_i2c_clients = {
436}; 437};
437 438
438#ifdef CONFIG_MFD_SH_MOBILE_SDHI 439#ifdef CONFIG_MFD_SH_MOBILE_SDHI
439/* SHDI0 */ 440/* SDHI0 */
440static void sdhi0_set_pwr(struct platform_device *pdev, int state) 441static void sdhi0_set_pwr(struct platform_device *pdev, int state)
441{ 442{
442 gpio_set_value(GPIO_PTB6, state); 443 gpio_set_value(GPIO_PTB6, state);
@@ -474,7 +475,8 @@ static struct platform_device sdhi0_device = {
474 }, 475 },
475}; 476};
476 477
477/* SHDI1 */ 478#if !defined(CONFIG_MMC_SH_MMCIF)
479/* SDHI1 */
478static void sdhi1_set_pwr(struct platform_device *pdev, int state) 480static void sdhi1_set_pwr(struct platform_device *pdev, int state)
479{ 481{
480 gpio_set_value(GPIO_PTB7, state); 482 gpio_set_value(GPIO_PTB7, state);
@@ -511,6 +513,7 @@ static struct platform_device sdhi1_device = {
511 .hwblk_id = HWBLK_SDHI1, 513 .hwblk_id = HWBLK_SDHI1,
512 }, 514 },
513}; 515};
516#endif /* CONFIG_MMC_SH_MMCIF */
514 517
515#else 518#else
516 519
@@ -720,7 +723,7 @@ static struct clk fsimckb_clk = {
720 .rate = 0, /* unknown */ 723 .rate = 0, /* unknown */
721}; 724};
722 725
723struct sh_fsi_platform_info fsi_info = { 726static struct sh_fsi_platform_info fsi_info = {
724 .portb_flags = SH_FSI_BRS_INV | 727 .portb_flags = SH_FSI_BRS_INV |
725 SH_FSI_OUT_SLAVE_MODE | 728 SH_FSI_OUT_SLAVE_MODE |
726 SH_FSI_IN_SLAVE_MODE | 729 SH_FSI_IN_SLAVE_MODE |
@@ -777,7 +780,7 @@ static struct platform_device irda_device = {
777#include <media/ak881x.h> 780#include <media/ak881x.h>
778#include <media/sh_vou.h> 781#include <media/sh_vou.h>
779 782
780struct ak881x_pdata ak881x_pdata = { 783static struct ak881x_pdata ak881x_pdata = {
781 .flags = AK881X_IF_MODE_SLAVE, 784 .flags = AK881X_IF_MODE_SLAVE,
782}; 785};
783 786
@@ -786,7 +789,7 @@ static struct i2c_board_info ak8813 = {
786 .platform_data = &ak881x_pdata, 789 .platform_data = &ak881x_pdata,
787}; 790};
788 791
789struct sh_vou_pdata sh_vou_pdata = { 792static struct sh_vou_pdata sh_vou_pdata = {
790 .bus_fmt = SH_VOU_BUS_8BIT, 793 .bus_fmt = SH_VOU_BUS_8BIT,
791 .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, 794 .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW,
792 .board_info = &ak8813, 795 .board_info = &ak8813,
@@ -819,6 +822,58 @@ static struct platform_device vou_device = {
819 }, 822 },
820}; 823};
821 824
825#if defined(CONFIG_MMC_SH_MMCIF)
826/* SH_MMCIF */
827static void mmcif_set_pwr(struct platform_device *pdev, int state)
828{
829 gpio_set_value(GPIO_PTB7, state);
830}
831
832static void mmcif_down_pwr(struct platform_device *pdev)
833{
834 gpio_set_value(GPIO_PTB7, 0);
835}
836
837static struct resource sh_mmcif_resources[] = {
838 [0] = {
839 .name = "SH_MMCIF",
840 .start = 0xA4CA0000,
841 .end = 0xA4CA00FF,
842 .flags = IORESOURCE_MEM,
843 },
844 [1] = {
845 /* MMC2I */
846 .start = 29,
847 .flags = IORESOURCE_IRQ,
848 },
849 [2] = {
850 /* MMC3I */
851 .start = 30,
852 .flags = IORESOURCE_IRQ,
853 },
854};
855
856static struct sh_mmcif_plat_data sh_mmcif_plat = {
857 .set_pwr = mmcif_set_pwr,
858 .down_pwr = mmcif_down_pwr,
859 .sup_pclk = 0, /* SH7724: Max Pclk/2 */
860 .caps = MMC_CAP_4_BIT_DATA |
861 MMC_CAP_8_BIT_DATA |
862 MMC_CAP_NEEDS_POLL,
863 .ocr = MMC_VDD_32_33 | MMC_VDD_33_34,
864};
865
866static struct platform_device sh_mmcif_device = {
867 .name = "sh_mmcif",
868 .id = 0,
869 .dev = {
870 .platform_data = &sh_mmcif_plat,
871 },
872 .num_resources = ARRAY_SIZE(sh_mmcif_resources),
873 .resource = sh_mmcif_resources,
874};
875#endif
876
822static struct platform_device *ecovec_devices[] __initdata = { 877static struct platform_device *ecovec_devices[] __initdata = {
823 &heartbeat_device, 878 &heartbeat_device,
824 &nor_flash_device, 879 &nor_flash_device,
@@ -831,7 +886,9 @@ static struct platform_device *ecovec_devices[] __initdata = {
831 &keysc_device, 886 &keysc_device,
832#ifdef CONFIG_MFD_SH_MOBILE_SDHI 887#ifdef CONFIG_MFD_SH_MOBILE_SDHI
833 &sdhi0_device, 888 &sdhi0_device,
889#if !defined(CONFIG_MMC_SH_MMCIF)
834 &sdhi1_device, 890 &sdhi1_device,
891#endif
835#else 892#else
836 &msiof0_device, 893 &msiof0_device,
837#endif 894#endif
@@ -841,6 +898,9 @@ static struct platform_device *ecovec_devices[] __initdata = {
841 &fsi_device, 898 &fsi_device,
842 &irda_device, 899 &irda_device,
843 &vou_device, 900 &vou_device,
901#if defined(CONFIG_MMC_SH_MMCIF)
902 &sh_mmcif_device,
903#endif
844}; 904};
845 905
846#ifdef CONFIG_I2C 906#ifdef CONFIG_I2C
@@ -1134,6 +1194,7 @@ static int __init arch_setup(void)
1134 gpio_request(GPIO_PTB6, NULL); 1194 gpio_request(GPIO_PTB6, NULL);
1135 gpio_direction_output(GPIO_PTB6, 0); 1195 gpio_direction_output(GPIO_PTB6, 0);
1136 1196
1197#if !defined(CONFIG_MMC_SH_MMCIF)
1137 /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */ 1198 /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */
1138 gpio_request(GPIO_FN_SDHI1CD, NULL); 1199 gpio_request(GPIO_FN_SDHI1CD, NULL);
1139 gpio_request(GPIO_FN_SDHI1WP, NULL); 1200 gpio_request(GPIO_FN_SDHI1WP, NULL);
@@ -1148,6 +1209,7 @@ static int __init arch_setup(void)
1148 1209
1149 /* I/O buffer drive ability is high for SDHI1 */ 1210 /* I/O buffer drive ability is high for SDHI1 */
1150 __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); 1211 __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
1212#endif /* CONFIG_MMC_SH_MMCIF */
1151#else 1213#else
1152 /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ 1214 /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */
1153 gpio_request(GPIO_FN_MSIOF0_TXD, NULL); 1215 gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
@@ -1223,6 +1285,25 @@ static int __init arch_setup(void)
1223 gpio_request(GPIO_PTU5, NULL); 1285 gpio_request(GPIO_PTU5, NULL);
1224 gpio_direction_output(GPIO_PTU5, 0); 1286 gpio_direction_output(GPIO_PTU5, 0);
1225 1287
1288#if defined(CONFIG_MMC_SH_MMCIF)
1289 /* enable MMCIF (needs DS2.6,7 set to OFF,ON) */
1290 gpio_request(GPIO_FN_MMC_D7, NULL);
1291 gpio_request(GPIO_FN_MMC_D6, NULL);
1292 gpio_request(GPIO_FN_MMC_D5, NULL);
1293 gpio_request(GPIO_FN_MMC_D4, NULL);
1294 gpio_request(GPIO_FN_MMC_D3, NULL);
1295 gpio_request(GPIO_FN_MMC_D2, NULL);
1296 gpio_request(GPIO_FN_MMC_D1, NULL);
1297 gpio_request(GPIO_FN_MMC_D0, NULL);
1298 gpio_request(GPIO_FN_MMC_CLK, NULL);
1299 gpio_request(GPIO_FN_MMC_CMD, NULL);
1300 gpio_request(GPIO_PTB7, NULL);
1301 gpio_direction_output(GPIO_PTB7, 0);
1302
1303 /* I/O buffer drive ability is high for MMCIF */
1304 __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
1305#endif
1306
1226 /* enable I2C device */ 1307 /* enable I2C device */
1227 i2c_register_board_info(0, i2c0_devices, 1308 i2c_register_board_info(0, i2c0_devices,
1228 ARRAY_SIZE(i2c0_devices)); 1309 ARRAY_SIZE(i2c0_devices));
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 87185de20446..662debe4ead2 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -181,7 +181,7 @@ static int migor_nand_flash_ready(struct mtd_info *mtd)
181 return gpio_get_value(GPIO_PTA1); /* NAND_RBn */ 181 return gpio_get_value(GPIO_PTA1); /* NAND_RBn */
182} 182}
183 183
184struct platform_nand_data migor_nand_flash_data = { 184static struct platform_nand_data migor_nand_flash_data = {
185 .chip = { 185 .chip = {
186 .nr_chips = 1, 186 .nr_chips = 1,
187 .partitions = migor_nand_flash_partitions, 187 .partitions = migor_nand_flash_partitions,
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index f9b82546c2df..552ebd9ba82b 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -283,7 +283,7 @@ static struct clk fsimcka_clk = {
283}; 283};
284 284
285/* change J20, J21, J22 pin to 1-2 connection to use slave mode */ 285/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
286struct sh_fsi_platform_info fsi_info = { 286static struct sh_fsi_platform_info fsi_info = {
287 .porta_flags = SH_FSI_BRS_INV | 287 .porta_flags = SH_FSI_BRS_INV |
288 SH_FSI_OUT_SLAVE_MODE | 288 SH_FSI_OUT_SLAVE_MODE |
289 SH_FSI_IN_SLAVE_MODE | 289 SH_FSI_IN_SLAVE_MODE |
@@ -371,7 +371,7 @@ static struct resource sh_eth_resources[] = {
371 }, 371 },
372}; 372};
373 373
374struct sh_eth_plat_data sh_eth_plat = { 374static struct sh_eth_plat_data sh_eth_plat = {
375 .phy = 0x1f, /* SMSC LAN8187 */ 375 .phy = 0x1f, /* SMSC LAN8187 */
376 .edmac_endian = EDMAC_LITTLE_ENDIAN, 376 .edmac_endian = EDMAC_LITTLE_ENDIAN,
377}; 377};
@@ -535,7 +535,7 @@ static struct platform_device irda_device = {
535#include <media/ak881x.h> 535#include <media/ak881x.h>
536#include <media/sh_vou.h> 536#include <media/sh_vou.h>
537 537
538struct ak881x_pdata ak881x_pdata = { 538static struct ak881x_pdata ak881x_pdata = {
539 .flags = AK881X_IF_MODE_SLAVE, 539 .flags = AK881X_IF_MODE_SLAVE,
540}; 540};
541 541
@@ -545,7 +545,7 @@ static struct i2c_board_info ak8813 = {
545 .platform_data = &ak881x_pdata, 545 .platform_data = &ak881x_pdata,
546}; 546};
547 547
548struct sh_vou_pdata sh_vou_pdata = { 548static struct sh_vou_pdata sh_vou_pdata = {
549 .bus_fmt = SH_VOU_BUS_8BIT, 549 .bus_fmt = SH_VOU_BUS_8BIT,
550 .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, 550 .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW,
551 .board_info = &ak8813, 551 .board_info = &ak8813,
diff --git a/arch/sh/boot/compressed/vmlinux.scr b/arch/sh/boot/compressed/vmlinux.scr
index f02382ae5c48..862d74808236 100644
--- a/arch/sh/boot/compressed/vmlinux.scr
+++ b/arch/sh/boot/compressed/vmlinux.scr
@@ -1,6 +1,6 @@
1SECTIONS 1SECTIONS
2{ 2{
3 .rodata.compressed : { 3 .rodata..compressed : {
4 input_len = .; 4 input_len = .;
5 LONG(input_data_end - input_data) input_data = .; 5 LONG(input_data_end - input_data) input_data = .;
6 *(.data) 6 *(.data)
diff --git a/arch/sh/boot/romimage/Makefile b/arch/sh/boot/romimage/Makefile
index f473a24a2d92..2216ee57f251 100644
--- a/arch/sh/boot/romimage/Makefile
+++ b/arch/sh/boot/romimage/Makefile
@@ -1,16 +1,21 @@
1# 1#
2# linux/arch/sh/boot/romimage/Makefile 2# linux/arch/sh/boot/romimage/Makefile
3# 3#
4# create an image suitable for burning to flash from zImage 4# create an romImage file suitable for burning to flash/mmc from zImage
5# 5#
6 6
7targets := vmlinux head.o zeropage.bin piggy.o 7targets := vmlinux head.o zeropage.bin piggy.o
8load-y := 0
8 9
9OBJECTS = $(obj)/head.o 10mmcif-load-$(CONFIG_CPU_SUBTYPE_SH7724) := 0xe5200000 # ILRAM
10LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart \ 11mmcif-obj-$(CONFIG_CPU_SUBTYPE_SH7724) := $(obj)/mmcif-sh7724.o
12load-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-load-y)
13obj-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-obj-y)
14
15LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(load-y) -e romstart \
11 -T $(obj)/../../kernel/vmlinux.lds 16 -T $(obj)/../../kernel/vmlinux.lds
12 17
13$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE 18$(obj)/vmlinux: $(obj)/head.o $(obj-y) $(obj)/piggy.o FORCE
14 $(call if_changed,ld) 19 $(call if_changed,ld)
15 @: 20 @:
16 21
diff --git a/arch/sh/boot/romimage/head.S b/arch/sh/boot/romimage/head.S
index 93e779a405ec..4671d1b82150 100644
--- a/arch/sh/boot/romimage/head.S
+++ b/arch/sh/boot/romimage/head.S
@@ -12,8 +12,40 @@ romstart:
12 /* include board specific setup code */ 12 /* include board specific setup code */
13#include <mach/romimage.h> 13#include <mach/romimage.h>
14 14
15#ifdef CONFIG_ROMIMAGE_MMCIF
16 /* load the romImage to above the empty zero page */
17 mov.l empty_zero_page_dst, r4
18 mov.l empty_zero_page_dst_adj, r5
19 add r5, r4
20 mov.l bytes_to_load, r5
21 mov.l loader_function, r7
22 jsr @r7
23 mov r4, r15
24
25 mov.l empty_zero_page_dst, r4
26 mov.l empty_zero_page_dst_adj, r5
27 add r5, r4
28 mov.l loaded_code_offs, r5
29 add r5, r4
30 jmp @r4
31 nop
32
33 .balign 4
34empty_zero_page_dst_adj:
35 .long PAGE_SIZE
36bytes_to_load:
37 .long end_data - romstart
38loader_function:
39 .long mmcif_loader
40loaded_code_offs:
41 .long loaded_code - romstart
42loaded_code:
43#endif /* CONFIG_ROMIMAGE_MMCIF */
44
15 /* copy the empty_zero_page contents to where vmlinux expects it */ 45 /* copy the empty_zero_page contents to where vmlinux expects it */
16 mova empty_zero_page_src, r0 46 mova extra_data_pos, r0
47 mov.l extra_data_size, r1
48 add r1, r0
17 mov.l empty_zero_page_dst, r1 49 mov.l empty_zero_page_dst, r1
18 mov #(PAGE_SHIFT - 4), r4 50 mov #(PAGE_SHIFT - 4), r4
19 mov #1, r3 51 mov #1, r3
@@ -37,7 +69,9 @@ romstart:
37 mov #PAGE_SHIFT, r4 69 mov #PAGE_SHIFT, r4
38 mov #1, r1 70 mov #1, r1
39 shld r4, r1 71 shld r4, r1
40 mova empty_zero_page_src, r0 72 mova extra_data_pos, r0
73 add r1, r0
74 mov.l extra_data_size, r1
41 add r1, r0 75 add r1, r0
42 jmp @r0 76 jmp @r0
43 nop 77 nop
@@ -45,4 +79,6 @@ romstart:
45 .align 2 79 .align 2
46empty_zero_page_dst: 80empty_zero_page_dst:
47 .long _text 81 .long _text
48empty_zero_page_src: 82extra_data_pos:
83extra_data_size:
84 .long zero_page_pos - extra_data_pos
diff --git a/arch/sh/boot/romimage/mmcif-sh7724.c b/arch/sh/boot/romimage/mmcif-sh7724.c
new file mode 100644
index 000000000000..14863d7292cb
--- /dev/null
+++ b/arch/sh/boot/romimage/mmcif-sh7724.c
@@ -0,0 +1,72 @@
1/*
2 * sh7724 MMCIF loader
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/mmc/sh_mmcif.h>
12#include <mach/romimage.h>
13
14#define MMCIF_BASE (void __iomem *)0xa4ca0000
15
16#define MSTPCR2 0xa4150038
17#define PTWCR 0xa4050146
18#define PTXCR 0xa4050148
19#define PSELA 0xa405014e
20#define PSELE 0xa4050156
21#define HIZCRC 0xa405015c
22#define DRVCRA 0xa405018a
23
24enum { MMCIF_PROGRESS_ENTER, MMCIF_PROGRESS_INIT,
25 MMCIF_PROGRESS_LOAD, MMCIF_PROGRESS_DONE };
26
27/* SH7724 specific MMCIF loader
28 *
29 * loads the romImage from an MMC card starting from block 512
30 * use the following line to write the romImage to an MMC card
31 * # dd if=arch/sh/boot/romImage of=/dev/sdx bs=512 seek=512
32 */
33asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes)
34{
35 mmcif_update_progress(MMCIF_PROGRESS_ENTER);
36
37 /* enable clock to the MMCIF hardware block */
38 __raw_writel(__raw_readl(MSTPCR2) & ~0x20000000, MSTPCR2);
39
40 /* setup pins D7-D0 */
41 __raw_writew(0x0000, PTWCR);
42
43 /* setup pins MMC_CLK, MMC_CMD */
44 __raw_writew(__raw_readw(PTXCR) & ~0x000f, PTXCR);
45
46 /* select D3-D0 pin function */
47 __raw_writew(__raw_readw(PSELA) & ~0x2000, PSELA);
48
49 /* select D7-D4 pin function */
50 __raw_writew(__raw_readw(PSELE) & ~0x3000, PSELE);
51
52 /* disable Hi-Z for the MMC pins */
53 __raw_writew(__raw_readw(HIZCRC) & ~0x0620, HIZCRC);
54
55 /* high drive capability for MMC pins */
56 __raw_writew(__raw_readw(DRVCRA) | 0x3000, DRVCRA);
57
58 mmcif_update_progress(MMCIF_PROGRESS_INIT);
59
60 /* setup MMCIF hardware */
61 sh_mmcif_boot_init(MMCIF_BASE);
62
63 mmcif_update_progress(MMCIF_PROGRESS_LOAD);
64
65 /* load kernel via MMCIF interface */
66 sh_mmcif_boot_slurp(MMCIF_BASE, buf, no_bytes);
67
68 /* disable clock to the MMCIF hardware block */
69 __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2);
70
71 mmcif_update_progress(MMCIF_PROGRESS_DONE);
72}
diff --git a/arch/sh/boot/romimage/vmlinux.scr b/arch/sh/boot/romimage/vmlinux.scr
index 287c08f8b4bb..590394e2f5f2 100644
--- a/arch/sh/boot/romimage/vmlinux.scr
+++ b/arch/sh/boot/romimage/vmlinux.scr
@@ -1,6 +1,8 @@
1SECTIONS 1SECTIONS
2{ 2{
3 .text : { 3 .text : {
4 zero_page_pos = .;
4 *(.data) 5 *(.data)
6 end_data = .;
5 } 7 }
6} 8}
diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h
index e461d67f03c3..ef9e555aafba 100644
--- a/arch/sh/include/asm/cache.h
+++ b/arch/sh/include/asm/cache.h
@@ -14,7 +14,7 @@
14 14
15#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 15#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
16 16
17#define __read_mostly __attribute__((__section__(".data.read_mostly"))) 17#define __read_mostly __attribute__((__section__(".data..read_mostly")))
18 18
19#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
20struct cache_info { 20struct cache_info {
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index f689554e17c1..b237d525d592 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -39,6 +39,8 @@
39#include <asm/io_generic.h> 39#include <asm/io_generic.h>
40#include <asm/io_trapped.h> 40#include <asm/io_trapped.h>
41 41
42#ifdef CONFIG_HAS_IOPORT
43
42#define inb(p) sh_mv.mv_inb((p)) 44#define inb(p) sh_mv.mv_inb((p))
43#define inw(p) sh_mv.mv_inw((p)) 45#define inw(p) sh_mv.mv_inw((p))
44#define inl(p) sh_mv.mv_inl((p)) 46#define inl(p) sh_mv.mv_inl((p))
@@ -60,6 +62,8 @@
60#define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c)) 62#define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c))
61#define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c)) 63#define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c))
62 64
65#endif
66
63#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v)) 67#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v))
64#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v)) 68#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v))
65#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v)) 69#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v))
@@ -240,6 +244,8 @@ __BUILD_MEMORY_STRING(q, u64)
240 244
241#define IO_SPACE_LIMIT 0xffffffff 245#define IO_SPACE_LIMIT 0xffffffff
242 246
247#ifdef CONFIG_HAS_IOPORT
248
243/* 249/*
244 * This function provides a method for the generic case where a 250 * This function provides a method for the generic case where a
245 * board-specific ioport_map simply needs to return the port + some 251 * board-specific ioport_map simply needs to return the port + some
@@ -255,6 +261,8 @@ static inline void __set_io_port_base(unsigned long pbase)
255 261
256#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n)) 262#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n))
257 263
264#endif
265
258/* We really want to try and get these to memcpy etc */ 266/* We really want to try and get these to memcpy etc */
259void memcpy_fromio(void *, const volatile void __iomem *, unsigned long); 267void memcpy_fromio(void *, const volatile void __iomem *, unsigned long);
260void memcpy_toio(volatile void __iomem *, const void *, unsigned long); 268void memcpy_toio(volatile void __iomem *, const void *, unsigned long);
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index bc0218cb72e1..a0b0cf79cf8a 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -19,6 +19,10 @@ struct sh_machine_vector {
19 const char *mv_name; 19 const char *mv_name;
20 int mv_nr_irqs; 20 int mv_nr_irqs;
21 21
22 int (*mv_irq_demux)(int irq);
23 void (*mv_init_irq)(void);
24
25#ifdef CONFIG_HAS_IOPORT
22 u8 (*mv_inb)(unsigned long); 26 u8 (*mv_inb)(unsigned long);
23 u16 (*mv_inw)(unsigned long); 27 u16 (*mv_inw)(unsigned long);
24 u32 (*mv_inl)(unsigned long); 28 u32 (*mv_inl)(unsigned long);
@@ -40,12 +44,9 @@ struct sh_machine_vector {
40 void (*mv_outsw)(unsigned long, const void *src, unsigned long count); 44 void (*mv_outsw)(unsigned long, const void *src, unsigned long count);
41 void (*mv_outsl)(unsigned long, const void *src, unsigned long count); 45 void (*mv_outsl)(unsigned long, const void *src, unsigned long count);
42 46
43 int (*mv_irq_demux)(int irq);
44
45 void (*mv_init_irq)(void);
46
47 void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size); 47 void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
48 void (*mv_ioport_unmap)(void __iomem *); 48 void (*mv_ioport_unmap)(void __iomem *);
49#endif
49 50
50 int (*mv_clk_init)(void); 51 int (*mv_clk_init)(void);
51 int (*mv_mode_pins)(void); 52 int (*mv_mode_pins)(void);
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h
index fbbf550cc529..4c27b68789b3 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7724.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h
@@ -9,6 +9,7 @@
9 * MD3: BSC - Area0 Bus Width (16/32-bit) [CS0BCR.9,10] 9 * MD3: BSC - Area0 Bus Width (16/32-bit) [CS0BCR.9,10]
10 * MD5: BSC - Endian Mode (L: Big, H: Little) [CMNCR.3] 10 * MD5: BSC - Endian Mode (L: Big, H: Little) [CMNCR.3]
11 * MD8: Test Mode 11 * MD8: Test Mode
12 * BOOT: FBR - Boot Mode (L: MMCIF, H: Area0)
12 */ 13 */
13 14
14/* Pin Function Controller: 15/* Pin Function Controller:
diff --git a/arch/sh/include/mach-common/mach/romimage.h b/arch/sh/include/mach-common/mach/romimage.h
index 267e24112d82..08fb42269ecd 100644
--- a/arch/sh/include/mach-common/mach/romimage.h
+++ b/arch/sh/include/mach-common/mach/romimage.h
@@ -1 +1,11 @@
1#ifdef __ASSEMBLY__
2
1/* do nothing here by default */ 3/* do nothing here by default */
4
5#else /* __ASSEMBLY__ */
6
7extern inline void mmcif_update_progress(int nr)
8{
9}
10
11#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/mach-ecovec24/mach/romimage.h b/arch/sh/include/mach-ecovec24/mach/romimage.h
index 1c8787ecb1c1..1dcf5e6c8d83 100644
--- a/arch/sh/include/mach-ecovec24/mach/romimage.h
+++ b/arch/sh/include/mach-ecovec24/mach/romimage.h
@@ -1,3 +1,5 @@
1#ifdef __ASSEMBLY__
2
1/* EcoVec board specific boot code: 3/* EcoVec board specific boot code:
2 * converts the "partner-jet-script.txt" script into assembly 4 * converts the "partner-jet-script.txt" script into assembly
3 * the assembly code is the first code to be executed in the romImage 5 * the assembly code is the first code to be executed in the romImage
@@ -18,3 +20,28 @@
18 .align 2 20 .align 2
191 : .long 0xa8000000 211 : .long 0xa8000000
202 : 222 :
23
24#else /* __ASSEMBLY__ */
25
26/* Ecovec board specific information:
27 *
28 * Set the following to enable MMCIF boot from the MMC card in CN12:
29 *
30 * DS1.5 = OFF (SH BOOT pin set to L)
31 * DS2.6 = OFF (Select MMCIF on CN12 instead of SDHI1)
32 * DS2.7 = ON (Select MMCIF on CN12 instead of SDHI1)
33 *
34 */
35#define HIZCRA 0xa4050158
36#define PGDR 0xa405012c
37
38extern inline void mmcif_update_progress(int nr)
39{
40 /* disable Hi-Z for LED pins */
41 __raw_writew(__raw_readw(HIZCRA) & ~(1 << 1), HIZCRA);
42
43 /* update progress on LED4, LED5, LED6 and LED7 */
44 __raw_writeb(1 << (nr - 1), PGDR);
45}
46
47#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/mach-kfr2r09/mach/romimage.h b/arch/sh/include/mach-kfr2r09/mach/romimage.h
index a110823f2bde..976256a323f2 100644
--- a/arch/sh/include/mach-kfr2r09/mach/romimage.h
+++ b/arch/sh/include/mach-kfr2r09/mach/romimage.h
@@ -1,3 +1,5 @@
1#ifdef __ASSEMBLY__
2
1/* kfr2r09 board specific boot code: 3/* kfr2r09 board specific boot code:
2 * converts the "partner-jet-script.txt" script into assembly 4 * converts the "partner-jet-script.txt" script into assembly
3 * the assembly code is the first code to be executed in the romImage 5 * the assembly code is the first code to be executed in the romImage
@@ -18,3 +20,11 @@
18 .align 2 20 .align 2
191: .long 0xa8000000 211: .long 0xa8000000
202: 222:
23
24#else /* __ASSEMBLY__ */
25
26extern inline void mmcif_update_progress(int nr)
27{
28}
29
30#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 650b92f00ee5..e25f3c69525d 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -12,7 +12,7 @@ endif
12CFLAGS_REMOVE_return_address.o = -pg 12CFLAGS_REMOVE_return_address.o = -pg
13 13
14obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \ 14obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \
15 idle.o io.o io_generic.o irq.o \ 15 idle.o io.o irq.o \
16 irq_$(BITS).o machvec.o nmi_debug.o process.o \ 16 irq_$(BITS).o machvec.o nmi_debug.o process.o \
17 process_$(BITS).o ptrace_$(BITS).o \ 17 process_$(BITS).o ptrace_$(BITS).o \
18 reboot.o return_address.o \ 18 reboot.o return_address.o \
@@ -39,6 +39,7 @@ obj-$(CONFIG_DUMP_CODE) += disassemble.o
39obj-$(CONFIG_HIBERNATION) += swsusp.o 39obj-$(CONFIG_HIBERNATION) += swsusp.o
40obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o 40obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
41obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o 41obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
42obj-$(CONFIG_HAS_IOPORT) += io_generic.o
42 43
43obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o 44obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
44obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o 45obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index 886d7d83ace3..49c09c7d5b77 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -49,6 +49,8 @@ static DEFINE_SPINLOCK(dwarf_fde_lock);
49 49
50static struct dwarf_cie *cached_cie; 50static struct dwarf_cie *cached_cie;
51 51
52static unsigned int dwarf_unwinder_ready;
53
52/** 54/**
53 * dwarf_frame_alloc_reg - allocate memory for a DWARF register 55 * dwarf_frame_alloc_reg - allocate memory for a DWARF register
54 * @frame: the DWARF frame whose list of registers we insert on 56 * @frame: the DWARF frame whose list of registers we insert on
@@ -582,6 +584,13 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
582 unsigned long addr; 584 unsigned long addr;
583 585
584 /* 586 /*
587 * If we've been called in to before initialization has
588 * completed, bail out immediately.
589 */
590 if (!dwarf_unwinder_ready)
591 return NULL;
592
593 /*
585 * If we're starting at the top of the stack we need get the 594 * If we're starting at the top of the stack we need get the
586 * contents of a physical register to get the CFA in order to 595 * contents of a physical register to get the CFA in order to
587 * begin the virtual unwinding of the stack. 596 * begin the virtual unwinding of the stack.
@@ -1167,7 +1176,7 @@ void module_dwarf_cleanup(struct module *mod)
1167 */ 1176 */
1168static int __init dwarf_unwinder_init(void) 1177static int __init dwarf_unwinder_init(void)
1169{ 1178{
1170 int err; 1179 int err = -ENOMEM;
1171 1180
1172 dwarf_frame_cachep = kmem_cache_create("dwarf_frames", 1181 dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
1173 sizeof(struct dwarf_frame), 0, 1182 sizeof(struct dwarf_frame), 0,
@@ -1181,11 +1190,15 @@ static int __init dwarf_unwinder_init(void)
1181 mempool_alloc_slab, 1190 mempool_alloc_slab,
1182 mempool_free_slab, 1191 mempool_free_slab,
1183 dwarf_frame_cachep); 1192 dwarf_frame_cachep);
1193 if (!dwarf_frame_pool)
1194 goto out;
1184 1195
1185 dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ, 1196 dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ,
1186 mempool_alloc_slab, 1197 mempool_alloc_slab,
1187 mempool_free_slab, 1198 mempool_free_slab,
1188 dwarf_reg_cachep); 1199 dwarf_reg_cachep);
1200 if (!dwarf_reg_pool)
1201 goto out;
1189 1202
1190 err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL); 1203 err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL);
1191 if (err) 1204 if (err)
@@ -1195,11 +1208,13 @@ static int __init dwarf_unwinder_init(void)
1195 if (err) 1208 if (err)
1196 goto out; 1209 goto out;
1197 1210
1211 dwarf_unwinder_ready = 1;
1212
1198 return 0; 1213 return 0;
1199 1214
1200out: 1215out:
1201 printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err); 1216 printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err);
1202 dwarf_unwinder_cleanup(); 1217 dwarf_unwinder_cleanup();
1203 return -EINVAL; 1218 return err;
1204} 1219}
1205early_initcall(dwarf_unwinder_init); 1220early_initcall(dwarf_unwinder_init);
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index 4770c241c679..5c51b794ba2a 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -112,25 +112,3 @@ void memset_io(volatile void __iomem *dst, int c, unsigned long count)
112 } 112 }
113} 113}
114EXPORT_SYMBOL(memset_io); 114EXPORT_SYMBOL(memset_io);
115
116#ifndef CONFIG_GENERIC_IOMAP
117
118void __iomem *ioport_map(unsigned long port, unsigned int nr)
119{
120 void __iomem *ret;
121
122 ret = __ioport_map_trapped(port, nr);
123 if (ret)
124 return ret;
125
126 return __ioport_map(port, nr);
127}
128EXPORT_SYMBOL(ioport_map);
129
130void ioport_unmap(void __iomem *addr)
131{
132 sh_mv.mv_ioport_unmap(addr);
133}
134EXPORT_SYMBOL(ioport_unmap);
135
136#endif /* CONFIG_GENERIC_IOMAP */
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index e1e1dbd19557..447d78f666f9 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -158,3 +158,23 @@ void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
158void generic_ioport_unmap(void __iomem *addr) 158void generic_ioport_unmap(void __iomem *addr)
159{ 159{
160} 160}
161
162#ifndef CONFIG_GENERIC_IOMAP
163void __iomem *ioport_map(unsigned long port, unsigned int nr)
164{
165 void __iomem *ret;
166
167 ret = __ioport_map_trapped(port, nr);
168 if (ret)
169 return ret;
170
171 return __ioport_map(port, nr);
172}
173EXPORT_SYMBOL(ioport_map);
174
175void ioport_unmap(void __iomem *addr)
176{
177 sh_mv.mv_ioport_unmap(addr);
178}
179EXPORT_SYMBOL(ioport_unmap);
180#endif /* CONFIG_GENERIC_IOMAP */
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 4a8bb4eeb8ad..2947d2bd1291 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -91,10 +91,14 @@ int register_trapped_io(struct trapped_io *tiop)
91 tiop->magic = IO_TRAPPED_MAGIC; 91 tiop->magic = IO_TRAPPED_MAGIC;
92 INIT_LIST_HEAD(&tiop->list); 92 INIT_LIST_HEAD(&tiop->list);
93 spin_lock_irq(&trapped_lock); 93 spin_lock_irq(&trapped_lock);
94#ifdef CONFIG_HAS_IOPORT
94 if (flags & IORESOURCE_IO) 95 if (flags & IORESOURCE_IO)
95 list_add(&tiop->list, &trapped_io); 96 list_add(&tiop->list, &trapped_io);
97#endif
98#ifdef CONFIG_HAS_IOMEM
96 if (flags & IORESOURCE_MEM) 99 if (flags & IORESOURCE_MEM)
97 list_add(&tiop->list, &trapped_mem); 100 list_add(&tiop->list, &trapped_mem);
101#endif
98 spin_unlock_irq(&trapped_lock); 102 spin_unlock_irq(&trapped_lock);
99 103
100 return 0; 104 return 0;
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 85cfaf916fdc..9f9bb63616ad 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -118,6 +118,14 @@ void __init sh_mv_setup(void)
118 sh_mv.mv_##elem = generic_##elem; \ 118 sh_mv.mv_##elem = generic_##elem; \
119} while (0) 119} while (0)
120 120
121#ifdef CONFIG_HAS_IOPORT
122
123#ifdef P2SEG
124 __set_io_port_base(P2SEG);
125#else
126 __set_io_port_base(0);
127#endif
128
121 mv_set(inb); mv_set(inw); mv_set(inl); 129 mv_set(inb); mv_set(inw); mv_set(inl);
122 mv_set(outb); mv_set(outw); mv_set(outl); 130 mv_set(outb); mv_set(outw); mv_set(outl);
123 131
@@ -129,16 +137,13 @@ void __init sh_mv_setup(void)
129 137
130 mv_set(ioport_map); 138 mv_set(ioport_map);
131 mv_set(ioport_unmap); 139 mv_set(ioport_unmap);
140
141#endif
142
132 mv_set(irq_demux); 143 mv_set(irq_demux);
133 mv_set(mode_pins); 144 mv_set(mode_pins);
134 mv_set(mem_init); 145 mv_set(mem_init);
135 146
136 if (!sh_mv.mv_nr_irqs) 147 if (!sh_mv.mv_nr_irqs)
137 sh_mv.mv_nr_irqs = NR_IRQS; 148 sh_mv.mv_nr_irqs = NR_IRQS;
138
139#ifdef P2SEG
140 __set_io_port_base(P2SEG);
141#else
142 __set_io_port_base(0);
143#endif
144} 149}
diff --git a/arch/sh/kernel/return_address.c b/arch/sh/kernel/return_address.c
index cbf1dd5372b2..5124aeb28c3f 100644
--- a/arch/sh/kernel/return_address.c
+++ b/arch/sh/kernel/return_address.c
@@ -24,6 +24,8 @@ void *return_address(unsigned int depth)
24 struct dwarf_frame *tmp; 24 struct dwarf_frame *tmp;
25 25
26 tmp = dwarf_unwind_stack(ra, frame); 26 tmp = dwarf_unwind_stack(ra, frame);
27 if (!tmp)
28 return NULL;
27 29
28 if (frame) 30 if (frame)
29 dwarf_free_frame(frame); 31 dwarf_free_frame(frame);
diff --git a/arch/sparc/boot/btfixupprep.c b/arch/sparc/boot/btfixupprep.c
index bbf91b9c3d39..e7f2940bd270 100644
--- a/arch/sparc/boot/btfixupprep.c
+++ b/arch/sparc/boot/btfixupprep.c
@@ -325,7 +325,7 @@ main1:
325 (*rr)->next = NULL; 325 (*rr)->next = NULL;
326 } 326 }
327 printf("! Generated by btfixupprep. Do not edit.\n\n"); 327 printf("! Generated by btfixupprep. Do not edit.\n\n");
328 printf("\t.section\t\".data.init\",#alloc,#write\n\t.align\t4\n\n"); 328 printf("\t.section\t\".data..init\",#alloc,#write\n\t.align\t4\n\n");
329 printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n"); 329 printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n");
330 for (i = 0; i < last; i++) { 330 for (i = 0; i < last; i++) {
331 f = array + i; 331 f = array + i;
diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h
index 78b07009f60a..0588b8c7faa2 100644
--- a/arch/sparc/include/asm/cache.h
+++ b/arch/sparc/include/asm/cache.h
@@ -21,7 +21,7 @@
21 21
22#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) 22#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT)
23 23
24#define __read_mostly __attribute__((__section__(".data.read_mostly"))) 24#define __read_mostly __attribute__((__section__(".data..read_mostly")))
25 25
26#ifdef CONFIG_SPARC32 26#ifdef CONFIG_SPARC32
27#include <asm/asi.h> 27#include <asm/asi.h>
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 7fcad58e216d..69268014dd8e 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -94,7 +94,7 @@ SECTIONS
94 .data : { 94 .data : {
95 INIT_TASK_DATA(KERNEL_STACK_SIZE) 95 INIT_TASK_DATA(KERNEL_STACK_SIZE)
96 . = ALIGN(KERNEL_STACK_SIZE); 96 . = ALIGN(KERNEL_STACK_SIZE);
97 *(.data.init_irqstack) 97 *(.data..init_irqstack)
98 DATA_DATA 98 DATA_DATA
99 *(.data.* .gnu.linkonce.d.*) 99 *(.data.* .gnu.linkonce.d.*)
100 SORT(CONSTRUCTORS) 100 SORT(CONSTRUCTORS)
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index 8aa77b61a5ff..ddc9698b66ed 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -34,5 +34,5 @@ union thread_union init_thread_union __init_task_data =
34 { INIT_THREAD_INFO(init_task) }; 34 { INIT_THREAD_INFO(init_task) };
35 35
36union thread_union cpu0_irqstack 36union thread_union cpu0_irqstack
37 __attribute__((__section__(".data.init_irqstack"))) = 37 __attribute__((__section__(".data..init_irqstack"))) =
38 { INIT_THREAD_INFO(init_task) }; 38 { INIT_THREAD_INFO(init_task) };
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index e22c96993db3..696634214dc6 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -81,7 +81,7 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
81 81
82 current->thread.fault_catcher = NULL; 82 current->thread.fault_catcher = NULL;
83 83
84 kunmap_atomic(page, KM_UML_USERCOPY); 84 kunmap_atomic((void *)addr, KM_UML_USERCOPY);
85 85
86 return n; 86 return n;
87} 87}
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index e7a6cca667aa..ec6378550671 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -50,7 +50,7 @@ SECTIONS
50 { 50 {
51 INIT_TASK_DATA(KERNEL_STACK_SIZE) 51 INIT_TASK_DATA(KERNEL_STACK_SIZE)
52 . = ALIGN(KERNEL_STACK_SIZE); 52 . = ALIGN(KERNEL_STACK_SIZE);
53 *(.data.init_irqstack) 53 *(.data..init_irqstack)
54 DATA_DATA 54 DATA_DATA
55 *(.gnu.linkonce.d*) 55 *(.gnu.linkonce.d*)
56 CONSTRUCTORS 56 CONSTRUCTORS
diff --git a/arch/x86/.gitignore b/arch/x86/.gitignore
new file mode 100644
index 000000000000..028079065af6
--- /dev/null
+++ b/arch/x86/.gitignore
@@ -0,0 +1,3 @@
1boot/compressed/vmlinux
2tools/test_get_len
3
diff --git a/arch/x86/boot/compressed/mkpiggy.c b/arch/x86/boot/compressed/mkpiggy.c
index bcbd36c41432..5c228129d175 100644
--- a/arch/x86/boot/compressed/mkpiggy.c
+++ b/arch/x86/boot/compressed/mkpiggy.c
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
77 offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */ 77 offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */
78 offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ 78 offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
79 79
80 printf(".section \".rodata.compressed\",\"a\",@progbits\n"); 80 printf(".section \".rodata..compressed\",\"a\",@progbits\n");
81 printf(".globl z_input_len\n"); 81 printf(".globl z_input_len\n");
82 printf("z_input_len = %lu\n", ilen); 82 printf("z_input_len = %lu\n", ilen);
83 printf(".globl z_output_len\n"); 83 printf(".globl z_output_len\n");
diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S
index a6f1a59a5b0c..5ddabceee124 100644
--- a/arch/x86/boot/compressed/vmlinux.lds.S
+++ b/arch/x86/boot/compressed/vmlinux.lds.S
@@ -26,8 +26,8 @@ SECTIONS
26 HEAD_TEXT 26 HEAD_TEXT
27 _ehead = . ; 27 _ehead = . ;
28 } 28 }
29 .rodata.compressed : { 29 .rodata..compressed : {
30 *(.rodata.compressed) 30 *(.rodata..compressed)
31 } 31 }
32 .text : { 32 .text : {
33 _text = .; /* Text */ 33 _text = .; /* Text */
diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h
index 2f9047cfaaca..48f99f15452e 100644
--- a/arch/x86/include/asm/cache.h
+++ b/arch/x86/include/asm/cache.h
@@ -7,7 +7,7 @@
7#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) 7#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
8#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 8#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
9 9
10#define __read_mostly __attribute__((__section__(".data.read_mostly"))) 10#define __read_mostly __attribute__((__section__(".data..read_mostly")))
11 11
12#define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT 12#define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT
13#define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT) 13#define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 8d8797eae5d7..cd2a31dc5fb8 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -53,6 +53,8 @@ extern int pcibios_last_bus;
53extern struct pci_bus *pci_root_bus; 53extern struct pci_bus *pci_root_bus;
54extern struct pci_ops pci_root_ops; 54extern struct pci_ops pci_root_ops;
55 55
56void pcibios_scan_specific_bus(int busn);
57
56/* pci-irq.c */ 58/* pci-irq.c */
57 59
58struct irq_info { 60struct irq_info {
diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S
index 8ded418b0593..13ab720573e3 100644
--- a/arch/x86/kernel/acpi/wakeup_32.S
+++ b/arch/x86/kernel/acpi/wakeup_32.S
@@ -1,4 +1,4 @@
1 .section .text.page_aligned 1 .section .text..page_aligned
2#include <linux/linkage.h> 2#include <linux/linkage.h>
3#include <asm/segment.h> 3#include <asm/segment.h>
4#include <asm/page_types.h> 4#include <asm/page_types.h>
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index fa5a1474cd18..0d20286d78c6 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1487,6 +1487,7 @@ static int __attach_device(struct device *dev,
1487 struct protection_domain *domain) 1487 struct protection_domain *domain)
1488{ 1488{
1489 struct iommu_dev_data *dev_data, *alias_data; 1489 struct iommu_dev_data *dev_data, *alias_data;
1490 int ret;
1490 1491
1491 dev_data = get_dev_data(dev); 1492 dev_data = get_dev_data(dev);
1492 alias_data = get_dev_data(dev_data->alias); 1493 alias_data = get_dev_data(dev_data->alias);
@@ -1498,13 +1499,14 @@ static int __attach_device(struct device *dev,
1498 spin_lock(&domain->lock); 1499 spin_lock(&domain->lock);
1499 1500
1500 /* Some sanity checks */ 1501 /* Some sanity checks */
1502 ret = -EBUSY;
1501 if (alias_data->domain != NULL && 1503 if (alias_data->domain != NULL &&
1502 alias_data->domain != domain) 1504 alias_data->domain != domain)
1503 return -EBUSY; 1505 goto out_unlock;
1504 1506
1505 if (dev_data->domain != NULL && 1507 if (dev_data->domain != NULL &&
1506 dev_data->domain != domain) 1508 dev_data->domain != domain)
1507 return -EBUSY; 1509 goto out_unlock;
1508 1510
1509 /* Do real assignment */ 1511 /* Do real assignment */
1510 if (dev_data->alias != dev) { 1512 if (dev_data->alias != dev) {
@@ -1520,10 +1522,14 @@ static int __attach_device(struct device *dev,
1520 1522
1521 atomic_inc(&dev_data->bind); 1523 atomic_inc(&dev_data->bind);
1522 1524
1525 ret = 0;
1526
1527out_unlock:
1528
1523 /* ready */ 1529 /* ready */
1524 spin_unlock(&domain->lock); 1530 spin_unlock(&domain->lock);
1525 1531
1526 return 0; 1532 return ret;
1527} 1533}
1528 1534
1529/* 1535/*
@@ -2324,10 +2330,6 @@ int __init amd_iommu_init_dma_ops(void)
2324 2330
2325 iommu_detected = 1; 2331 iommu_detected = 1;
2326 swiotlb = 0; 2332 swiotlb = 0;
2327#ifdef CONFIG_GART_IOMMU
2328 gart_iommu_aperture_disabled = 1;
2329 gart_iommu_aperture = 0;
2330#endif
2331 2333
2332 /* Make the driver finally visible to the drivers */ 2334 /* Make the driver finally visible to the drivers */
2333 dma_ops = &amd_iommu_dma_ops; 2335 dma_ops = &amd_iommu_dma_ops;
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 3bacb4d0844c..3cc63e2b8dd4 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -287,8 +287,12 @@ static u8 * __init iommu_map_mmio_space(u64 address)
287{ 287{
288 u8 *ret; 288 u8 *ret;
289 289
290 if (!request_mem_region(address, MMIO_REGION_LENGTH, "amd_iommu")) 290 if (!request_mem_region(address, MMIO_REGION_LENGTH, "amd_iommu")) {
291 pr_err("AMD-Vi: Can not reserve memory region %llx for mmio\n",
292 address);
293 pr_err("AMD-Vi: This is a BIOS bug. Please contact your hardware vendor\n");
291 return NULL; 294 return NULL;
295 }
292 296
293 ret = ioremap_nocache(address, MMIO_REGION_LENGTH); 297 ret = ioremap_nocache(address, MMIO_REGION_LENGTH);
294 if (ret != NULL) 298 if (ret != NULL)
@@ -1314,7 +1318,7 @@ static int __init amd_iommu_init(void)
1314 ret = amd_iommu_init_dma_ops(); 1318 ret = amd_iommu_init_dma_ops();
1315 1319
1316 if (ret) 1320 if (ret)
1317 goto free; 1321 goto free_disable;
1318 1322
1319 amd_iommu_init_api(); 1323 amd_iommu_init_api();
1320 1324
@@ -1332,9 +1336,10 @@ static int __init amd_iommu_init(void)
1332out: 1336out:
1333 return ret; 1337 return ret;
1334 1338
1335free: 1339free_disable:
1336 disable_iommus(); 1340 disable_iommus();
1337 1341
1342free:
1338 amd_iommu_uninit_devices(); 1343 amd_iommu_uninit_devices();
1339 1344
1340 free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, 1345 free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
@@ -1353,6 +1358,15 @@ free:
1353 1358
1354 free_unity_maps(); 1359 free_unity_maps();
1355 1360
1361#ifdef CONFIG_GART_IOMMU
1362 /*
1363 * We failed to initialize the AMD IOMMU - try fallback to GART
1364 * if possible.
1365 */
1366 gart_iommu_init();
1367
1368#endif
1369
1356 goto out; 1370 goto out;
1357} 1371}
1358 1372
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 707165dbc203..18cc42562250 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -36,6 +36,7 @@
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/mm.h> 37#include <linux/mm.h>
38#include <linux/debugfs.h> 38#include <linux/debugfs.h>
39#include <linux/edac_mce.h>
39 40
40#include <asm/processor.h> 41#include <asm/processor.h>
41#include <asm/hw_irq.h> 42#include <asm/hw_irq.h>
@@ -169,6 +170,15 @@ void mce_log(struct mce *mce)
169 entry = rcu_dereference_check_mce(mcelog.next); 170 entry = rcu_dereference_check_mce(mcelog.next);
170 for (;;) { 171 for (;;) {
171 /* 172 /*
173 * If edac_mce is enabled, it will check the error type
174 * and will process it, if it is a known error.
175 * Otherwise, the error will be sent through mcelog
176 * interface
177 */
178 if (edac_mce_parse(mce))
179 return;
180
181 /*
172 * When the buffer fills up discard new entries. 182 * When the buffer fills up discard new entries.
173 * Assume that the earlier errors are the more 183 * Assume that the earlier errors are the more
174 * interesting ones: 184 * interesting ones:
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index c77586061bcb..5db5b7d65a18 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -106,6 +106,7 @@ struct cpu_hw_events {
106 106
107 int n_events; 107 int n_events;
108 int n_added; 108 int n_added;
109 int n_txn;
109 int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */ 110 int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
110 u64 tags[X86_PMC_IDX_MAX]; 111 u64 tags[X86_PMC_IDX_MAX];
111 struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ 112 struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
@@ -983,6 +984,7 @@ static int x86_pmu_enable(struct perf_event *event)
983out: 984out:
984 cpuc->n_events = n; 985 cpuc->n_events = n;
985 cpuc->n_added += n - n0; 986 cpuc->n_added += n - n0;
987 cpuc->n_txn += n - n0;
986 988
987 return 0; 989 return 0;
988} 990}
@@ -1089,6 +1091,14 @@ static void x86_pmu_disable(struct perf_event *event)
1089 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 1091 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1090 int i; 1092 int i;
1091 1093
1094 /*
1095 * If we're called during a txn, we don't need to do anything.
1096 * The events never got scheduled and ->cancel_txn will truncate
1097 * the event_list.
1098 */
1099 if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
1100 return;
1101
1092 x86_pmu_stop(event); 1102 x86_pmu_stop(event);
1093 1103
1094 for (i = 0; i < cpuc->n_events; i++) { 1104 for (i = 0; i < cpuc->n_events; i++) {
@@ -1379,6 +1389,7 @@ static void x86_pmu_start_txn(const struct pmu *pmu)
1379 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 1389 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1380 1390
1381 cpuc->group_flag |= PERF_EVENT_TXN_STARTED; 1391 cpuc->group_flag |= PERF_EVENT_TXN_STARTED;
1392 cpuc->n_txn = 0;
1382} 1393}
1383 1394
1384/* 1395/*
@@ -1391,6 +1402,11 @@ static void x86_pmu_cancel_txn(const struct pmu *pmu)
1391 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 1402 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1392 1403
1393 cpuc->group_flag &= ~PERF_EVENT_TXN_STARTED; 1404 cpuc->group_flag &= ~PERF_EVENT_TXN_STARTED;
1405 /*
1406 * Truncate the collected events.
1407 */
1408 cpuc->n_added -= cpuc->n_txn;
1409 cpuc->n_events -= cpuc->n_txn;
1394} 1410}
1395 1411
1396/* 1412/*
@@ -1419,6 +1435,12 @@ static int x86_pmu_commit_txn(const struct pmu *pmu)
1419 */ 1435 */
1420 memcpy(cpuc->assign, assign, n*sizeof(int)); 1436 memcpy(cpuc->assign, assign, n*sizeof(int));
1421 1437
1438 /*
1439 * Clear out the txn count so that ->cancel_txn() which gets
1440 * run after ->commit_txn() doesn't undo things.
1441 */
1442 cpuc->n_txn = 0;
1443
1422 return 0; 1444 return 0;
1423} 1445}
1424 1446
diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c
index 3a54dcb9cd0e..43e9ccf44947 100644
--- a/arch/x86/kernel/init_task.c
+++ b/arch/x86/kernel/init_task.c
@@ -34,7 +34,7 @@ EXPORT_SYMBOL(init_task);
34/* 34/*
35 * per-CPU TSS segments. Threads are completely 'soft' on Linux, 35 * per-CPU TSS segments. Threads are completely 'soft' on Linux,
36 * no more per-task TSS's. The TSS size is kept cacheline-aligned 36 * no more per-task TSS's. The TSS size is kept cacheline-aligned
37 * so they are allowed to end up in the .data.cacheline_aligned 37 * so they are allowed to end up in the .data..cacheline_aligned
38 * section. Since TSS's are completely CPU-local, we want them 38 * section. Since TSS's are completely CPU-local, we want them
39 * on exact cacheline boundaries, to eliminate cacheline ping-pong. 39 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
40 */ 40 */
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index a867940a6dfc..de3b63ae3da2 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -21,12 +21,6 @@
21#include <asm/cpu.h> 21#include <asm/cpu.h>
22#include <asm/stackprotector.h> 22#include <asm/stackprotector.h>
23 23
24#ifdef CONFIG_DEBUG_PER_CPU_MAPS
25# define DBG(fmt, ...) pr_dbg(fmt, ##__VA_ARGS__)
26#else
27# define DBG(fmt, ...) do { if (0) pr_dbg(fmt, ##__VA_ARGS__); } while (0)
28#endif
29
30DEFINE_PER_CPU(int, cpu_number); 24DEFINE_PER_CPU(int, cpu_number);
31EXPORT_PER_CPU_SYMBOL(cpu_number); 25EXPORT_PER_CPU_SYMBOL(cpu_number);
32 26
@@ -247,7 +241,7 @@ void __init setup_per_cpu_areas(void)
247#endif 241#endif
248#endif 242#endif
249 /* 243 /*
250 * Up to this point, the boot CPU has been using .data.init 244 * Up to this point, the boot CPU has been using .init.data
251 * area. Reload any changed state for the boot CPU. 245 * area. Reload any changed state for the boot CPU.
252 */ 246 */
253 if (cpu == boot_cpu_id) 247 if (cpu == boot_cpu_id)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 37462f1ddba5..c4f33b2e77d6 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -686,7 +686,7 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
686static void __cpuinit announce_cpu(int cpu, int apicid) 686static void __cpuinit announce_cpu(int cpu, int apicid)
687{ 687{
688 static int current_node = -1; 688 static int current_node = -1;
689 int node = cpu_to_node(cpu); 689 int node = early_cpu_to_node(cpu);
690 690
691 if (system_state == SYSTEM_BOOTING) { 691 if (system_state == SYSTEM_BOOTING) {
692 if (node != current_node) { 692 if (node != current_node) {
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 2cc249718c46..d0bb52296fa3 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -97,7 +97,7 @@ SECTIONS
97 HEAD_TEXT 97 HEAD_TEXT
98#ifdef CONFIG_X86_32 98#ifdef CONFIG_X86_32
99 . = ALIGN(PAGE_SIZE); 99 . = ALIGN(PAGE_SIZE);
100 *(.text.page_aligned) 100 *(.text..page_aligned)
101#endif 101#endif
102 . = ALIGN(8); 102 . = ALIGN(8);
103 _stext = .; 103 _stext = .;
@@ -305,7 +305,7 @@ SECTIONS
305 . = ALIGN(PAGE_SIZE); 305 . = ALIGN(PAGE_SIZE);
306 .bss : AT(ADDR(.bss) - LOAD_OFFSET) { 306 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
307 __bss_start = .; 307 __bss_start = .;
308 *(.bss.page_aligned) 308 *(.bss..page_aligned)
309 *(.bss) 309 *(.bss)
310 . = ALIGN(4); 310 . = ALIGN(4);
311 __bss_stop = .; 311 __bss_stop = .;
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 550df481accd..787c52ca49c3 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -3,12 +3,6 @@
3#include <linux/module.h> 3#include <linux/module.h>
4#include <linux/bootmem.h> 4#include <linux/bootmem.h>
5 5
6#ifdef CONFIG_DEBUG_PER_CPU_MAPS
7# define DBG(x...) printk(KERN_DEBUG x)
8#else
9# define DBG(x...)
10#endif
11
12/* 6/*
13 * Which logical CPUs are on which nodes 7 * Which logical CPUs are on which nodes
14 */ 8 */
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index 0db5eaf54560..8d460eaf524f 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -11,28 +11,14 @@
11 */ 11 */
12static void __devinit pcibios_fixup_peer_bridges(void) 12static void __devinit pcibios_fixup_peer_bridges(void)
13{ 13{
14 int n, devfn; 14 int n;
15 long node;
16 15
17 if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff) 16 if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff)
18 return; 17 return;
19 DBG("PCI: Peer bridge fixup\n"); 18 DBG("PCI: Peer bridge fixup\n");
20 19
21 for (n=0; n <= pcibios_last_bus; n++) { 20 for (n=0; n <= pcibios_last_bus; n++)
22 u32 l; 21 pcibios_scan_specific_bus(n);
23 if (pci_find_bus(0, n))
24 continue;
25 node = get_mp_bus_to_node(n);
26 for (devfn = 0; devfn < 256; devfn += 8) {
27 if (!raw_pci_read(0, n, devfn, PCI_VENDOR_ID, 2, &l) &&
28 l != 0x0000 && l != 0xffff) {
29 DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
30 printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
31 pci_scan_bus_on_node(n, &pci_root_ops, node);
32 break;
33 }
34 }
35 }
36} 22}
37 23
38int __init pci_legacy_init(void) 24int __init pci_legacy_init(void)
@@ -50,6 +36,28 @@ int __init pci_legacy_init(void)
50 return 0; 36 return 0;
51} 37}
52 38
39void pcibios_scan_specific_bus(int busn)
40{
41 int devfn;
42 long node;
43 u32 l;
44
45 if (pci_find_bus(0, busn))
46 return;
47
48 node = get_mp_bus_to_node(busn);
49 for (devfn = 0; devfn < 256; devfn += 8) {
50 if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) &&
51 l != 0x0000 && l != 0xffff) {
52 DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l);
53 printk(KERN_INFO "PCI: Discovered peer bus %02x\n", busn);
54 pci_scan_bus_on_node(busn, &pci_root_ops, node);
55 return;
56 }
57 }
58}
59EXPORT_SYMBOL_GPL(pcibios_scan_specific_bus);
60
53int __init pci_subsys_init(void) 61int __init pci_subsys_init(void)
54{ 62{
55 /* 63 /*
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index 987267f79bf5..a9c661108034 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -60,6 +60,6 @@ static void xen_vcpu_notify_restore(void *data)
60 60
61void xen_arch_resume(void) 61void xen_arch_resume(void)
62{ 62{
63 smp_call_function(xen_vcpu_notify_restore, 63 on_each_cpu(xen_vcpu_notify_restore,
64 (void *)CLOCK_EVT_NOTIFY_RESUME, 1); 64 (void *)CLOCK_EVT_NOTIFY_RESUME, 1);
65} 65}
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index bc0733359a88..e367e3026436 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -105,7 +105,6 @@ good_area:
105 * make sure we exit gracefully rather than endlessly redo 105 * make sure we exit gracefully rather than endlessly redo
106 * the fault. 106 * the fault.
107 */ 107 */
108survive:
109 fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); 108 fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0);
110 if (unlikely(fault & VM_FAULT_ERROR)) { 109 if (unlikely(fault & VM_FAULT_ERROR)) {
111 if (fault & VM_FAULT_OOM) 110 if (fault & VM_FAULT_OOM)
@@ -146,15 +145,10 @@ bad_area:
146 */ 145 */
147out_of_memory: 146out_of_memory:
148 up_read(&mm->mmap_sem); 147 up_read(&mm->mmap_sem);
149 if (is_global_init(current)) { 148 if (!user_mode(regs))
150 yield(); 149 bad_page_fault(regs, address, SIGKILL);
151 down_read(&mm->mmap_sem); 150 else
152 goto survive; 151 pagefault_out_of_memory();
153 }
154 printk("VM: killing process %s\n", current->comm);
155 if (user_mode(regs))
156 do_group_exit(SIGKILL);
157 bad_page_fault(regs, address, SIGKILL);
158 return; 152 return;
159 153
160do_sigbus: 154do_sigbus:
diff --git a/block/blk-core.c b/block/blk-core.c
index 3bc5579d6f54..f84cce42fc58 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -467,6 +467,9 @@ static int blk_init_free_list(struct request_queue *q)
467{ 467{
468 struct request_list *rl = &q->rq; 468 struct request_list *rl = &q->rq;
469 469
470 if (unlikely(rl->rq_pool))
471 return 0;
472
470 rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0; 473 rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0;
471 rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0; 474 rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0;
472 rl->elvpriv = 0; 475 rl->elvpriv = 0;
@@ -570,9 +573,17 @@ EXPORT_SYMBOL(blk_init_queue);
570struct request_queue * 573struct request_queue *
571blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) 574blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
572{ 575{
573 struct request_queue *q = blk_alloc_queue_node(GFP_KERNEL, node_id); 576 struct request_queue *uninit_q, *q;
577
578 uninit_q = blk_alloc_queue_node(GFP_KERNEL, node_id);
579 if (!uninit_q)
580 return NULL;
581
582 q = blk_init_allocated_queue_node(uninit_q, rfn, lock, node_id);
583 if (!q)
584 blk_cleanup_queue(uninit_q);
574 585
575 return blk_init_allocated_queue_node(q, rfn, lock, node_id); 586 return q;
576} 587}
577EXPORT_SYMBOL(blk_init_queue_node); 588EXPORT_SYMBOL(blk_init_queue_node);
578 589
@@ -592,10 +603,8 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn,
592 return NULL; 603 return NULL;
593 604
594 q->node = node_id; 605 q->node = node_id;
595 if (blk_init_free_list(q)) { 606 if (blk_init_free_list(q))
596 kmem_cache_free(blk_requestq_cachep, q);
597 return NULL; 607 return NULL;
598 }
599 608
600 q->request_fn = rfn; 609 q->request_fn = rfn;
601 q->prep_rq_fn = NULL; 610 q->prep_rq_fn = NULL;
@@ -618,7 +627,6 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn,
618 return q; 627 return q;
619 } 628 }
620 629
621 blk_put_queue(q);
622 return NULL; 630 return NULL;
623} 631}
624EXPORT_SYMBOL(blk_init_allocated_queue_node); 632EXPORT_SYMBOL(blk_init_allocated_queue_node);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index ed897b5ef315..5ff4f4850e71 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -64,6 +64,9 @@ static DEFINE_PER_CPU(unsigned long, cfq_ioc_count);
64static struct completion *ioc_gone; 64static struct completion *ioc_gone;
65static DEFINE_SPINLOCK(ioc_gone_lock); 65static DEFINE_SPINLOCK(ioc_gone_lock);
66 66
67static DEFINE_SPINLOCK(cic_index_lock);
68static DEFINE_IDA(cic_index_ida);
69
67#define CFQ_PRIO_LISTS IOPRIO_BE_NR 70#define CFQ_PRIO_LISTS IOPRIO_BE_NR
68#define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) 71#define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
69#define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT) 72#define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT)
@@ -271,6 +274,7 @@ struct cfq_data {
271 unsigned int cfq_latency; 274 unsigned int cfq_latency;
272 unsigned int cfq_group_isolation; 275 unsigned int cfq_group_isolation;
273 276
277 unsigned int cic_index;
274 struct list_head cic_list; 278 struct list_head cic_list;
275 279
276 /* 280 /*
@@ -430,6 +434,24 @@ static inline void cic_set_cfqq(struct cfq_io_context *cic,
430 cic->cfqq[is_sync] = cfqq; 434 cic->cfqq[is_sync] = cfqq;
431} 435}
432 436
437#define CIC_DEAD_KEY 1ul
438#define CIC_DEAD_INDEX_SHIFT 1
439
440static inline void *cfqd_dead_key(struct cfq_data *cfqd)
441{
442 return (void *)(cfqd->cic_index << CIC_DEAD_INDEX_SHIFT | CIC_DEAD_KEY);
443}
444
445static inline struct cfq_data *cic_to_cfqd(struct cfq_io_context *cic)
446{
447 struct cfq_data *cfqd = cic->key;
448
449 if (unlikely((unsigned long) cfqd & CIC_DEAD_KEY))
450 return NULL;
451
452 return cfqd;
453}
454
433/* 455/*
434 * We regard a request as SYNC, if it's either a read or has the SYNC bit 456 * We regard a request as SYNC, if it's either a read or has the SYNC bit
435 * set (in which case it could also be direct WRITE). 457 * set (in which case it could also be direct WRITE).
@@ -2510,11 +2532,12 @@ static void cfq_cic_free(struct cfq_io_context *cic)
2510static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) 2532static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
2511{ 2533{
2512 unsigned long flags; 2534 unsigned long flags;
2535 unsigned long dead_key = (unsigned long) cic->key;
2513 2536
2514 BUG_ON(!cic->dead_key); 2537 BUG_ON(!(dead_key & CIC_DEAD_KEY));
2515 2538
2516 spin_lock_irqsave(&ioc->lock, flags); 2539 spin_lock_irqsave(&ioc->lock, flags);
2517 radix_tree_delete(&ioc->radix_root, cic->dead_key); 2540 radix_tree_delete(&ioc->radix_root, dead_key >> CIC_DEAD_INDEX_SHIFT);
2518 hlist_del_rcu(&cic->cic_list); 2541 hlist_del_rcu(&cic->cic_list);
2519 spin_unlock_irqrestore(&ioc->lock, flags); 2542 spin_unlock_irqrestore(&ioc->lock, flags);
2520 2543
@@ -2537,15 +2560,10 @@ static void cfq_free_io_context(struct io_context *ioc)
2537 __call_for_each_cic(ioc, cic_free_func); 2560 __call_for_each_cic(ioc, cic_free_func);
2538} 2561}
2539 2562
2540static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) 2563static void cfq_put_cooperator(struct cfq_queue *cfqq)
2541{ 2564{
2542 struct cfq_queue *__cfqq, *next; 2565 struct cfq_queue *__cfqq, *next;
2543 2566
2544 if (unlikely(cfqq == cfqd->active_queue)) {
2545 __cfq_slice_expired(cfqd, cfqq, 0);
2546 cfq_schedule_dispatch(cfqd);
2547 }
2548
2549 /* 2567 /*
2550 * If this queue was scheduled to merge with another queue, be 2568 * If this queue was scheduled to merge with another queue, be
2551 * sure to drop the reference taken on that queue (and others in 2569 * sure to drop the reference taken on that queue (and others in
@@ -2561,6 +2579,16 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
2561 cfq_put_queue(__cfqq); 2579 cfq_put_queue(__cfqq);
2562 __cfqq = next; 2580 __cfqq = next;
2563 } 2581 }
2582}
2583
2584static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
2585{
2586 if (unlikely(cfqq == cfqd->active_queue)) {
2587 __cfq_slice_expired(cfqd, cfqq, 0);
2588 cfq_schedule_dispatch(cfqd);
2589 }
2590
2591 cfq_put_cooperator(cfqq);
2564 2592
2565 cfq_put_queue(cfqq); 2593 cfq_put_queue(cfqq);
2566} 2594}
@@ -2573,11 +2601,10 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
2573 list_del_init(&cic->queue_list); 2601 list_del_init(&cic->queue_list);
2574 2602
2575 /* 2603 /*
2576 * Make sure key == NULL is seen for dead queues 2604 * Make sure dead mark is seen for dead queues
2577 */ 2605 */
2578 smp_wmb(); 2606 smp_wmb();
2579 cic->dead_key = (unsigned long) cic->key; 2607 cic->key = cfqd_dead_key(cfqd);
2580 cic->key = NULL;
2581 2608
2582 if (ioc->ioc_data == cic) 2609 if (ioc->ioc_data == cic)
2583 rcu_assign_pointer(ioc->ioc_data, NULL); 2610 rcu_assign_pointer(ioc->ioc_data, NULL);
@@ -2596,7 +2623,7 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
2596static void cfq_exit_single_io_context(struct io_context *ioc, 2623static void cfq_exit_single_io_context(struct io_context *ioc,
2597 struct cfq_io_context *cic) 2624 struct cfq_io_context *cic)
2598{ 2625{
2599 struct cfq_data *cfqd = cic->key; 2626 struct cfq_data *cfqd = cic_to_cfqd(cic);
2600 2627
2601 if (cfqd) { 2628 if (cfqd) {
2602 struct request_queue *q = cfqd->queue; 2629 struct request_queue *q = cfqd->queue;
@@ -2609,7 +2636,7 @@ static void cfq_exit_single_io_context(struct io_context *ioc,
2609 * race between exiting task and queue 2636 * race between exiting task and queue
2610 */ 2637 */
2611 smp_read_barrier_depends(); 2638 smp_read_barrier_depends();
2612 if (cic->key) 2639 if (cic->key == cfqd)
2613 __cfq_exit_single_io_context(cfqd, cic); 2640 __cfq_exit_single_io_context(cfqd, cic);
2614 2641
2615 spin_unlock_irqrestore(q->queue_lock, flags); 2642 spin_unlock_irqrestore(q->queue_lock, flags);
@@ -2689,7 +2716,7 @@ static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc)
2689 2716
2690static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic) 2717static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic)
2691{ 2718{
2692 struct cfq_data *cfqd = cic->key; 2719 struct cfq_data *cfqd = cic_to_cfqd(cic);
2693 struct cfq_queue *cfqq; 2720 struct cfq_queue *cfqq;
2694 unsigned long flags; 2721 unsigned long flags;
2695 2722
@@ -2746,7 +2773,7 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
2746static void changed_cgroup(struct io_context *ioc, struct cfq_io_context *cic) 2773static void changed_cgroup(struct io_context *ioc, struct cfq_io_context *cic)
2747{ 2774{
2748 struct cfq_queue *sync_cfqq = cic_to_cfqq(cic, 1); 2775 struct cfq_queue *sync_cfqq = cic_to_cfqq(cic, 1);
2749 struct cfq_data *cfqd = cic->key; 2776 struct cfq_data *cfqd = cic_to_cfqd(cic);
2750 unsigned long flags; 2777 unsigned long flags;
2751 struct request_queue *q; 2778 struct request_queue *q;
2752 2779
@@ -2883,12 +2910,13 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
2883 unsigned long flags; 2910 unsigned long flags;
2884 2911
2885 WARN_ON(!list_empty(&cic->queue_list)); 2912 WARN_ON(!list_empty(&cic->queue_list));
2913 BUG_ON(cic->key != cfqd_dead_key(cfqd));
2886 2914
2887 spin_lock_irqsave(&ioc->lock, flags); 2915 spin_lock_irqsave(&ioc->lock, flags);
2888 2916
2889 BUG_ON(ioc->ioc_data == cic); 2917 BUG_ON(ioc->ioc_data == cic);
2890 2918
2891 radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd); 2919 radix_tree_delete(&ioc->radix_root, cfqd->cic_index);
2892 hlist_del_rcu(&cic->cic_list); 2920 hlist_del_rcu(&cic->cic_list);
2893 spin_unlock_irqrestore(&ioc->lock, flags); 2921 spin_unlock_irqrestore(&ioc->lock, flags);
2894 2922
@@ -2900,7 +2928,6 @@ cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc)
2900{ 2928{
2901 struct cfq_io_context *cic; 2929 struct cfq_io_context *cic;
2902 unsigned long flags; 2930 unsigned long flags;
2903 void *k;
2904 2931
2905 if (unlikely(!ioc)) 2932 if (unlikely(!ioc))
2906 return NULL; 2933 return NULL;
@@ -2917,13 +2944,11 @@ cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc)
2917 } 2944 }
2918 2945
2919 do { 2946 do {
2920 cic = radix_tree_lookup(&ioc->radix_root, (unsigned long) cfqd); 2947 cic = radix_tree_lookup(&ioc->radix_root, cfqd->cic_index);
2921 rcu_read_unlock(); 2948 rcu_read_unlock();
2922 if (!cic) 2949 if (!cic)
2923 break; 2950 break;
2924 /* ->key must be copied to avoid race with cfq_exit_queue() */ 2951 if (unlikely(cic->key != cfqd)) {
2925 k = cic->key;
2926 if (unlikely(!k)) {
2927 cfq_drop_dead_cic(cfqd, ioc, cic); 2952 cfq_drop_dead_cic(cfqd, ioc, cic);
2928 rcu_read_lock(); 2953 rcu_read_lock();
2929 continue; 2954 continue;
@@ -2956,7 +2981,7 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
2956 2981
2957 spin_lock_irqsave(&ioc->lock, flags); 2982 spin_lock_irqsave(&ioc->lock, flags);
2958 ret = radix_tree_insert(&ioc->radix_root, 2983 ret = radix_tree_insert(&ioc->radix_root,
2959 (unsigned long) cfqd, cic); 2984 cfqd->cic_index, cic);
2960 if (!ret) 2985 if (!ret)
2961 hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list); 2986 hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list);
2962 spin_unlock_irqrestore(&ioc->lock, flags); 2987 spin_unlock_irqrestore(&ioc->lock, flags);
@@ -3516,6 +3541,9 @@ split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq)
3516 } 3541 }
3517 3542
3518 cic_set_cfqq(cic, NULL, 1); 3543 cic_set_cfqq(cic, NULL, 1);
3544
3545 cfq_put_cooperator(cfqq);
3546
3519 cfq_put_queue(cfqq); 3547 cfq_put_queue(cfqq);
3520 return NULL; 3548 return NULL;
3521} 3549}
@@ -3708,10 +3736,32 @@ static void cfq_exit_queue(struct elevator_queue *e)
3708 3736
3709 cfq_shutdown_timer_wq(cfqd); 3737 cfq_shutdown_timer_wq(cfqd);
3710 3738
3739 spin_lock(&cic_index_lock);
3740 ida_remove(&cic_index_ida, cfqd->cic_index);
3741 spin_unlock(&cic_index_lock);
3742
3711 /* Wait for cfqg->blkg->key accessors to exit their grace periods. */ 3743 /* Wait for cfqg->blkg->key accessors to exit their grace periods. */
3712 call_rcu(&cfqd->rcu, cfq_cfqd_free); 3744 call_rcu(&cfqd->rcu, cfq_cfqd_free);
3713} 3745}
3714 3746
3747static int cfq_alloc_cic_index(void)
3748{
3749 int index, error;
3750
3751 do {
3752 if (!ida_pre_get(&cic_index_ida, GFP_KERNEL))
3753 return -ENOMEM;
3754
3755 spin_lock(&cic_index_lock);
3756 error = ida_get_new(&cic_index_ida, &index);
3757 spin_unlock(&cic_index_lock);
3758 if (error && error != -EAGAIN)
3759 return error;
3760 } while (error);
3761
3762 return index;
3763}
3764
3715static void *cfq_init_queue(struct request_queue *q) 3765static void *cfq_init_queue(struct request_queue *q)
3716{ 3766{
3717 struct cfq_data *cfqd; 3767 struct cfq_data *cfqd;
@@ -3719,10 +3769,16 @@ static void *cfq_init_queue(struct request_queue *q)
3719 struct cfq_group *cfqg; 3769 struct cfq_group *cfqg;
3720 struct cfq_rb_root *st; 3770 struct cfq_rb_root *st;
3721 3771
3772 i = cfq_alloc_cic_index();
3773 if (i < 0)
3774 return NULL;
3775
3722 cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node); 3776 cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
3723 if (!cfqd) 3777 if (!cfqd)
3724 return NULL; 3778 return NULL;
3725 3779
3780 cfqd->cic_index = i;
3781
3726 /* Init root service tree */ 3782 /* Init root service tree */
3727 cfqd->grp_service_tree = CFQ_RB_ROOT; 3783 cfqd->grp_service_tree = CFQ_RB_ROOT;
3728 3784
@@ -3984,6 +4040,7 @@ static void __exit cfq_exit(void)
3984 */ 4040 */
3985 if (elv_ioc_count_read(cfq_ioc_count)) 4041 if (elv_ioc_count_read(cfq_ioc_count))
3986 wait_for_completion(&all_gone); 4042 wait_for_completion(&all_gone);
4043 ida_destroy(&cic_index_ida);
3987 cfq_slab_kill(); 4044 cfq_slab_kill();
3988} 4045}
3989 4046
diff --git a/block/elevator.c b/block/elevator.c
index 6df2b5056b51..923a9139106c 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -242,9 +242,11 @@ int elevator_init(struct request_queue *q, char *name)
242{ 242{
243 struct elevator_type *e = NULL; 243 struct elevator_type *e = NULL;
244 struct elevator_queue *eq; 244 struct elevator_queue *eq;
245 int ret = 0;
246 void *data; 245 void *data;
247 246
247 if (unlikely(q->elevator))
248 return 0;
249
248 INIT_LIST_HEAD(&q->queue_head); 250 INIT_LIST_HEAD(&q->queue_head);
249 q->last_merge = NULL; 251 q->last_merge = NULL;
250 q->end_sector = 0; 252 q->end_sector = 0;
@@ -284,7 +286,7 @@ int elevator_init(struct request_queue *q, char *name)
284 } 286 }
285 287
286 elevator_attach(q, eq, data); 288 elevator_attach(q, eq, data);
287 return ret; 289 return 0;
288} 290}
289EXPORT_SYMBOL(elevator_init); 291EXPORT_SYMBOL(elevator_init);
290 292
@@ -1097,7 +1099,7 @@ ssize_t elv_iosched_show(struct request_queue *q, char *name)
1097 struct elevator_type *__e; 1099 struct elevator_type *__e;
1098 int len = 0; 1100 int len = 0;
1099 1101
1100 if (!q->elevator) 1102 if (!q->elevator || !blk_queue_stackable(q))
1101 return sprintf(name, "none\n"); 1103 return sprintf(name, "none\n");
1102 1104
1103 elv = e->elevator_type; 1105 elv = e->elevator_type;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e61d4f8e62a5..5f2027d782e8 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -79,7 +79,7 @@ enum {
79 EC_FLAGS_GPE_STORM, /* GPE storm detected */ 79 EC_FLAGS_GPE_STORM, /* GPE storm detected */
80 EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and 80 EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and
81 * OpReg are installed */ 81 * OpReg are installed */
82 EC_FLAGS_FROZEN, /* Transactions are suspended */ 82 EC_FLAGS_BLOCKED, /* Transactions are blocked */
83}; 83};
84 84
85/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 85/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -293,7 +293,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
293 if (t->rdata) 293 if (t->rdata)
294 memset(t->rdata, 0, t->rlen); 294 memset(t->rdata, 0, t->rlen);
295 mutex_lock(&ec->lock); 295 mutex_lock(&ec->lock);
296 if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) { 296 if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) {
297 status = -EINVAL; 297 status = -EINVAL;
298 goto unlock; 298 goto unlock;
299 } 299 }
@@ -459,7 +459,7 @@ int ec_transaction(u8 command,
459 459
460EXPORT_SYMBOL(ec_transaction); 460EXPORT_SYMBOL(ec_transaction);
461 461
462void acpi_ec_suspend_transactions(void) 462void acpi_ec_block_transactions(void)
463{ 463{
464 struct acpi_ec *ec = first_ec; 464 struct acpi_ec *ec = first_ec;
465 465
@@ -468,11 +468,11 @@ void acpi_ec_suspend_transactions(void)
468 468
469 mutex_lock(&ec->lock); 469 mutex_lock(&ec->lock);
470 /* Prevent transactions from being carried out */ 470 /* Prevent transactions from being carried out */
471 set_bit(EC_FLAGS_FROZEN, &ec->flags); 471 set_bit(EC_FLAGS_BLOCKED, &ec->flags);
472 mutex_unlock(&ec->lock); 472 mutex_unlock(&ec->lock);
473} 473}
474 474
475void acpi_ec_resume_transactions(void) 475void acpi_ec_unblock_transactions(void)
476{ 476{
477 struct acpi_ec *ec = first_ec; 477 struct acpi_ec *ec = first_ec;
478 478
@@ -481,10 +481,20 @@ void acpi_ec_resume_transactions(void)
481 481
482 mutex_lock(&ec->lock); 482 mutex_lock(&ec->lock);
483 /* Allow transactions to be carried out again */ 483 /* Allow transactions to be carried out again */
484 clear_bit(EC_FLAGS_FROZEN, &ec->flags); 484 clear_bit(EC_FLAGS_BLOCKED, &ec->flags);
485 mutex_unlock(&ec->lock); 485 mutex_unlock(&ec->lock);
486} 486}
487 487
488void acpi_ec_unblock_transactions_early(void)
489{
490 /*
491 * Allow transactions to happen again (this function is called from
492 * atomic context during wakeup, so we don't need to acquire the mutex).
493 */
494 if (first_ec)
495 clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags);
496}
497
488static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) 498static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
489{ 499{
490 int result; 500 int result;
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index e28411367239..f8f190ec066e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -49,8 +49,9 @@ void acpi_early_processor_set_pdc(void);
49int acpi_ec_init(void); 49int acpi_ec_init(void);
50int acpi_ec_ecdt_probe(void); 50int acpi_ec_ecdt_probe(void);
51int acpi_boot_ec_enable(void); 51int acpi_boot_ec_enable(void);
52void acpi_ec_suspend_transactions(void); 52void acpi_ec_block_transactions(void);
53void acpi_ec_resume_transactions(void); 53void acpi_ec_unblock_transactions(void);
54void acpi_ec_unblock_transactions_early(void);
54 55
55/*-------------------------------------------------------------------------- 56/*--------------------------------------------------------------------------
56 Suspend/Resume 57 Suspend/Resume
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 2e8c27d48f2b..b1b385692f46 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -80,7 +80,7 @@ module_param(nocst, uint, 0000);
80static unsigned int latency_factor __read_mostly = 2; 80static unsigned int latency_factor __read_mostly = 2;
81module_param(latency_factor, uint, 0644); 81module_param(latency_factor, uint, 0644);
82 82
83static s64 us_to_pm_timer_ticks(s64 t) 83static u64 us_to_pm_timer_ticks(s64 t)
84{ 84{
85 return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); 85 return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
86} 86}
@@ -731,10 +731,10 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
731 731
732 seq_puts(seq, "demotion[--] "); 732 seq_puts(seq, "demotion[--] ");
733 733
734 seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", 734 seq_printf(seq, "latency[%03d] usage[%08d] duration[%020Lu]\n",
735 pr->power.states[i].latency, 735 pr->power.states[i].latency,
736 pr->power.states[i].usage, 736 pr->power.states[i].usage,
737 (unsigned long long)pr->power.states[i].time); 737 us_to_pm_timer_ticks(pr->power.states[i].time));
738 } 738 }
739 739
740 end: 740 end:
@@ -861,7 +861,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
861 ktime_t kt1, kt2; 861 ktime_t kt1, kt2;
862 s64 idle_time_ns; 862 s64 idle_time_ns;
863 s64 idle_time; 863 s64 idle_time;
864 s64 sleep_ticks = 0;
865 864
866 pr = __get_cpu_var(processors); 865 pr = __get_cpu_var(processors);
867 866
@@ -906,8 +905,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
906 idle_time = idle_time_ns; 905 idle_time = idle_time_ns;
907 do_div(idle_time, NSEC_PER_USEC); 906 do_div(idle_time, NSEC_PER_USEC);
908 907
909 sleep_ticks = us_to_pm_timer_ticks(idle_time);
910
911 /* Tell the scheduler how much we idled: */ 908 /* Tell the scheduler how much we idled: */
912 sched_clock_idle_wakeup_event(idle_time_ns); 909 sched_clock_idle_wakeup_event(idle_time_ns);
913 910
@@ -918,7 +915,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
918 cx->usage++; 915 cx->usage++;
919 916
920 lapic_timer_state_broadcast(pr, cx, 0); 917 lapic_timer_state_broadcast(pr, cx, 0);
921 cx->time += sleep_ticks; 918 cx->time += idle_time;
922 return idle_time; 919 return idle_time;
923} 920}
924 921
@@ -940,7 +937,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
940 ktime_t kt1, kt2; 937 ktime_t kt1, kt2;
941 s64 idle_time_ns; 938 s64 idle_time_ns;
942 s64 idle_time; 939 s64 idle_time;
943 s64 sleep_ticks = 0;
944 940
945 941
946 pr = __get_cpu_var(processors); 942 pr = __get_cpu_var(processors);
@@ -1022,11 +1018,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1022 spin_unlock(&c3_lock); 1018 spin_unlock(&c3_lock);
1023 } 1019 }
1024 kt2 = ktime_get_real(); 1020 kt2 = ktime_get_real();
1025 idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1)); 1021 idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
1026 idle_time = idle_time_ns; 1022 idle_time = idle_time_ns;
1027 do_div(idle_time, NSEC_PER_USEC); 1023 do_div(idle_time, NSEC_PER_USEC);
1028 1024
1029 sleep_ticks = us_to_pm_timer_ticks(idle_time);
1030 /* Tell the scheduler how much we idled: */ 1025 /* Tell the scheduler how much we idled: */
1031 sched_clock_idle_wakeup_event(idle_time_ns); 1026 sched_clock_idle_wakeup_event(idle_time_ns);
1032 1027
@@ -1037,7 +1032,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1037 cx->usage++; 1032 cx->usage++;
1038 1033
1039 lapic_timer_state_broadcast(pr, cx, 0); 1034 lapic_timer_state_broadcast(pr, cx, 0);
1040 cx->time += sleep_ticks; 1035 cx->time += idle_time;
1041 return idle_time; 1036 return idle_time;
1042} 1037}
1043 1038
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 4ab2275b4461..3fb4bdea7e06 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -94,11 +94,13 @@ void __init acpi_old_suspend_ordering(void)
94} 94}
95 95
96/** 96/**
97 * acpi_pm_disable_gpes - Disable the GPEs. 97 * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
98 */ 98 */
99static int acpi_pm_disable_gpes(void) 99static int acpi_pm_freeze(void)
100{ 100{
101 acpi_disable_all_gpes(); 101 acpi_disable_all_gpes();
102 acpi_os_wait_events_complete(NULL);
103 acpi_ec_block_transactions();
102 return 0; 104 return 0;
103} 105}
104 106
@@ -126,7 +128,8 @@ static int acpi_pm_prepare(void)
126 int error = __acpi_pm_prepare(); 128 int error = __acpi_pm_prepare();
127 129
128 if (!error) 130 if (!error)
129 acpi_disable_all_gpes(); 131 acpi_pm_freeze();
132
130 return error; 133 return error;
131} 134}
132 135
@@ -256,6 +259,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
256 * acpi_leave_sleep_state will reenable specific GPEs later 259 * acpi_leave_sleep_state will reenable specific GPEs later
257 */ 260 */
258 acpi_disable_all_gpes(); 261 acpi_disable_all_gpes();
262 /* Allow EC transactions to happen. */
263 acpi_ec_unblock_transactions_early();
259 264
260 local_irq_restore(flags); 265 local_irq_restore(flags);
261 printk(KERN_DEBUG "Back to C!\n"); 266 printk(KERN_DEBUG "Back to C!\n");
@@ -267,6 +272,12 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
267 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 272 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
268} 273}
269 274
275static void acpi_suspend_finish(void)
276{
277 acpi_ec_unblock_transactions();
278 acpi_pm_finish();
279}
280
270static int acpi_suspend_state_valid(suspend_state_t pm_state) 281static int acpi_suspend_state_valid(suspend_state_t pm_state)
271{ 282{
272 u32 acpi_state; 283 u32 acpi_state;
@@ -288,7 +299,7 @@ static struct platform_suspend_ops acpi_suspend_ops = {
288 .begin = acpi_suspend_begin, 299 .begin = acpi_suspend_begin,
289 .prepare_late = acpi_pm_prepare, 300 .prepare_late = acpi_pm_prepare,
290 .enter = acpi_suspend_enter, 301 .enter = acpi_suspend_enter,
291 .wake = acpi_pm_finish, 302 .wake = acpi_suspend_finish,
292 .end = acpi_pm_end, 303 .end = acpi_pm_end,
293}; 304};
294 305
@@ -314,9 +325,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
314static struct platform_suspend_ops acpi_suspend_ops_old = { 325static struct platform_suspend_ops acpi_suspend_ops_old = {
315 .valid = acpi_suspend_state_valid, 326 .valid = acpi_suspend_state_valid,
316 .begin = acpi_suspend_begin_old, 327 .begin = acpi_suspend_begin_old,
317 .prepare_late = acpi_pm_disable_gpes, 328 .prepare_late = acpi_pm_freeze,
318 .enter = acpi_suspend_enter, 329 .enter = acpi_suspend_enter,
319 .wake = acpi_pm_finish, 330 .wake = acpi_suspend_finish,
320 .end = acpi_pm_end, 331 .end = acpi_pm_end,
321 .recover = acpi_pm_finish, 332 .recover = acpi_pm_finish,
322}; 333};
@@ -433,6 +444,7 @@ static int acpi_hibernation_enter(void)
433static void acpi_hibernation_finish(void) 444static void acpi_hibernation_finish(void)
434{ 445{
435 hibernate_nvs_free(); 446 hibernate_nvs_free();
447 acpi_ec_unblock_transactions();
436 acpi_pm_finish(); 448 acpi_pm_finish();
437} 449}
438 450
@@ -453,19 +465,13 @@ static void acpi_hibernation_leave(void)
453 } 465 }
454 /* Restore the NVS memory area */ 466 /* Restore the NVS memory area */
455 hibernate_nvs_restore(); 467 hibernate_nvs_restore();
468 /* Allow EC transactions to happen. */
469 acpi_ec_unblock_transactions_early();
456} 470}
457 471
458static int acpi_pm_pre_restore(void) 472static void acpi_pm_thaw(void)
459{
460 acpi_disable_all_gpes();
461 acpi_os_wait_events_complete(NULL);
462 acpi_ec_suspend_transactions();
463 return 0;
464}
465
466static void acpi_pm_restore_cleanup(void)
467{ 473{
468 acpi_ec_resume_transactions(); 474 acpi_ec_unblock_transactions();
469 acpi_enable_all_runtime_gpes(); 475 acpi_enable_all_runtime_gpes();
470} 476}
471 477
@@ -477,8 +483,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
477 .prepare = acpi_pm_prepare, 483 .prepare = acpi_pm_prepare,
478 .enter = acpi_hibernation_enter, 484 .enter = acpi_hibernation_enter,
479 .leave = acpi_hibernation_leave, 485 .leave = acpi_hibernation_leave,
480 .pre_restore = acpi_pm_pre_restore, 486 .pre_restore = acpi_pm_freeze,
481 .restore_cleanup = acpi_pm_restore_cleanup, 487 .restore_cleanup = acpi_pm_thaw,
482}; 488};
483 489
484/** 490/**
@@ -510,12 +516,9 @@ static int acpi_hibernation_begin_old(void)
510 516
511static int acpi_hibernation_pre_snapshot_old(void) 517static int acpi_hibernation_pre_snapshot_old(void)
512{ 518{
513 int error = acpi_pm_disable_gpes(); 519 acpi_pm_freeze();
514 520 hibernate_nvs_save();
515 if (!error) 521 return 0;
516 hibernate_nvs_save();
517
518 return error;
519} 522}
520 523
521/* 524/*
@@ -527,11 +530,11 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
527 .end = acpi_pm_end, 530 .end = acpi_pm_end,
528 .pre_snapshot = acpi_hibernation_pre_snapshot_old, 531 .pre_snapshot = acpi_hibernation_pre_snapshot_old,
529 .finish = acpi_hibernation_finish, 532 .finish = acpi_hibernation_finish,
530 .prepare = acpi_pm_disable_gpes, 533 .prepare = acpi_pm_freeze,
531 .enter = acpi_hibernation_enter, 534 .enter = acpi_hibernation_enter,
532 .leave = acpi_hibernation_leave, 535 .leave = acpi_hibernation_leave,
533 .pre_restore = acpi_pm_pre_restore, 536 .pre_restore = acpi_pm_freeze,
534 .restore_cleanup = acpi_pm_restore_cleanup, 537 .restore_cleanup = acpi_pm_thaw,
535 .recover = acpi_pm_finish, 538 .recover = acpi_pm_finish,
536}; 539};
537#endif /* CONFIG_HIBERNATION */ 540#endif /* CONFIG_HIBERNATION */
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 73f883333a0d..aa85a98d3a4f 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -168,10 +168,10 @@ config ATA_BMDMA
168 default y 168 default y
169 help 169 help
170 This option adds support for SFF ATA controllers with BMDMA 170 This option adds support for SFF ATA controllers with BMDMA
171 capability. BMDMA stands for bus-master DMA and the 171 capability. BMDMA stands for bus-master DMA and is the
172 de-facto DMA interface for SFF controllers. 172 de facto DMA interface for SFF controllers.
173 173
174 If unuser, say Y. 174 If unsure, say Y.
175 175
176if ATA_BMDMA 176if ATA_BMDMA
177 177
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 06b7e49e039c..ddf8e4862787 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4119,9 +4119,8 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
4119 dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) { 4119 dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) {
4120 ata_dev_printk(dev, KERN_WARNING, 4120 ata_dev_printk(dev, KERN_WARNING,
4121 "new n_sectors matches native, probably " 4121 "new n_sectors matches native, probably "
4122 "late HPA unlock, continuing\n"); 4122 "late HPA unlock, n_sectors updated\n");
4123 /* keep using the old n_sectors */ 4123 /* use the larger n_sectors */
4124 dev->n_sectors = n_sectors;
4125 return 0; 4124 return 0;
4126 } 4125 }
4127 4126
@@ -6669,6 +6668,7 @@ EXPORT_SYMBOL_GPL(ata_dummy_port_info);
6669EXPORT_SYMBOL_GPL(ata_link_next); 6668EXPORT_SYMBOL_GPL(ata_link_next);
6670EXPORT_SYMBOL_GPL(ata_dev_next); 6669EXPORT_SYMBOL_GPL(ata_dev_next);
6671EXPORT_SYMBOL_GPL(ata_std_bios_param); 6670EXPORT_SYMBOL_GPL(ata_std_bios_param);
6671EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity);
6672EXPORT_SYMBOL_GPL(ata_host_init); 6672EXPORT_SYMBOL_GPL(ata_host_init);
6673EXPORT_SYMBOL_GPL(ata_host_alloc); 6673EXPORT_SYMBOL_GPL(ata_host_alloc);
6674EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); 6674EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index cfa9dd3d7253..a54273d2c3c6 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -415,6 +415,35 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
415} 415}
416 416
417/** 417/**
418 * ata_scsi_unlock_native_capacity - unlock native capacity
419 * @sdev: SCSI device to adjust device capacity for
420 *
421 * This function is called if a partition on @sdev extends beyond
422 * the end of the device. It requests EH to unlock HPA.
423 *
424 * LOCKING:
425 * Defined by the SCSI layer. Might sleep.
426 */
427void ata_scsi_unlock_native_capacity(struct scsi_device *sdev)
428{
429 struct ata_port *ap = ata_shost_to_port(sdev->host);
430 struct ata_device *dev;
431 unsigned long flags;
432
433 spin_lock_irqsave(ap->lock, flags);
434
435 dev = ata_scsi_find_dev(ap, sdev);
436 if (dev && dev->n_sectors < dev->n_native_sectors) {
437 dev->flags |= ATA_DFLAG_UNLOCK_HPA;
438 dev->link->eh_info.action |= ATA_EH_RESET;
439 ata_port_schedule_eh(ap);
440 }
441
442 spin_unlock_irqrestore(ap->lock, flags);
443 ata_port_wait_eh(ap);
444}
445
446/**
418 * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl 447 * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
419 * @ap: target port 448 * @ap: target port
420 * @sdev: SCSI device to get identify data for 449 * @sdev: SCSI device to get identify data for
diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c
index 76640ac76888..75b49d01780b 100644
--- a/drivers/ata/pata_macio.c
+++ b/drivers/ata/pata_macio.c
@@ -1355,8 +1355,11 @@ static struct of_device_id pata_macio_match[] =
1355 1355
1356static struct macio_driver pata_macio_driver = 1356static struct macio_driver pata_macio_driver =
1357{ 1357{
1358 .name = "pata-macio", 1358 .driver = {
1359 .match_table = pata_macio_match, 1359 .name = "pata-macio",
1360 .owner = THIS_MODULE,
1361 .of_match_table = pata_macio_match,
1362 },
1360 .probe = pata_macio_attach, 1363 .probe = pata_macio_attach,
1361 .remove = pata_macio_detach, 1364 .remove = pata_macio_detach,
1362#ifdef CONFIG_PM 1365#ifdef CONFIG_PM
@@ -1366,9 +1369,6 @@ static struct macio_driver pata_macio_driver =
1366#ifdef CONFIG_PMAC_MEDIABAY 1369#ifdef CONFIG_PMAC_MEDIABAY
1367 .mediabay_event = pata_macio_mb_event, 1370 .mediabay_event = pata_macio_mb_event,
1368#endif 1371#endif
1369 .driver = {
1370 .owner = THIS_MODULE,
1371 },
1372}; 1372};
1373 1373
1374static const struct pci_device_id pata_macio_pci_match[] = { 1374static const struct pci_device_id pata_macio_pci_match[] = {
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 6fd114784116..21161136cad0 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1669,7 +1669,6 @@ static void nv_mcp55_freeze(struct ata_port *ap)
1669 mask = readl(mmio_base + NV_INT_ENABLE_MCP55); 1669 mask = readl(mmio_base + NV_INT_ENABLE_MCP55);
1670 mask &= ~(NV_INT_ALL_MCP55 << shift); 1670 mask &= ~(NV_INT_ALL_MCP55 << shift);
1671 writel(mask, mmio_base + NV_INT_ENABLE_MCP55); 1671 writel(mask, mmio_base + NV_INT_ENABLE_MCP55);
1672 ata_sff_freeze(ap);
1673} 1672}
1674 1673
1675static void nv_mcp55_thaw(struct ata_port *ap) 1674static void nv_mcp55_thaw(struct ata_port *ap)
@@ -1683,7 +1682,6 @@ static void nv_mcp55_thaw(struct ata_port *ap)
1683 mask = readl(mmio_base + NV_INT_ENABLE_MCP55); 1682 mask = readl(mmio_base + NV_INT_ENABLE_MCP55);
1684 mask |= (NV_INT_MASK_MCP55 << shift); 1683 mask |= (NV_INT_MASK_MCP55 << shift);
1685 writel(mask, mmio_base + NV_INT_ENABLE_MCP55); 1684 writel(mask, mmio_base + NV_INT_ENABLE_MCP55);
1686 ata_sff_thaw(ap);
1687} 1685}
1688 1686
1689static void nv_adma_error_handler(struct ata_port *ap) 1687static void nv_adma_error_handler(struct ata_port *ap)
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 101d8c219caf..0ecd0f6aa2c0 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -575,6 +575,19 @@ static void svia_configure(struct pci_dev *pdev)
575 tmp8 |= NATIVE_MODE_ALL; 575 tmp8 |= NATIVE_MODE_ALL;
576 pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); 576 pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
577 } 577 }
578
579 /*
580 * vt6421 has problems talking to some drives. The following
581 * is the magic fix from Joseph Chan <JosephChan@via.com.tw>.
582 * Please add proper documentation if possible.
583 *
584 * https://bugzilla.kernel.org/show_bug.cgi?id=15173
585 */
586 if (pdev->device == 0x3249) {
587 pci_read_config_byte(pdev, 0x52, &tmp8);
588 tmp8 |= 1 << 2;
589 pci_write_config_byte(pdev, 0x52, tmp8);
590 }
578} 591}
579 592
580static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 593static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 6081e81d5738..f1bf79d9bc0a 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -133,6 +133,28 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
133 return page; 133 return page;
134} 134}
135 135
136static void brd_free_page(struct brd_device *brd, sector_t sector)
137{
138 struct page *page;
139 pgoff_t idx;
140
141 spin_lock(&brd->brd_lock);
142 idx = sector >> PAGE_SECTORS_SHIFT;
143 page = radix_tree_delete(&brd->brd_pages, idx);
144 spin_unlock(&brd->brd_lock);
145 if (page)
146 __free_page(page);
147}
148
149static void brd_zero_page(struct brd_device *brd, sector_t sector)
150{
151 struct page *page;
152
153 page = brd_lookup_page(brd, sector);
154 if (page)
155 clear_highpage(page);
156}
157
136/* 158/*
137 * Free all backing store pages and radix tree. This must only be called when 159 * Free all backing store pages and radix tree. This must only be called when
138 * there are no other users of the device. 160 * there are no other users of the device.
@@ -189,6 +211,24 @@ static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n)
189 return 0; 211 return 0;
190} 212}
191 213
214static void discard_from_brd(struct brd_device *brd,
215 sector_t sector, size_t n)
216{
217 while (n >= PAGE_SIZE) {
218 /*
219 * Don't want to actually discard pages here because
220 * re-allocating the pages can result in writeback
221 * deadlocks under heavy load.
222 */
223 if (0)
224 brd_free_page(brd, sector);
225 else
226 brd_zero_page(brd, sector);
227 sector += PAGE_SIZE >> SECTOR_SHIFT;
228 n -= PAGE_SIZE;
229 }
230}
231
192/* 232/*
193 * Copy n bytes from src to the brd starting at sector. Does not sleep. 233 * Copy n bytes from src to the brd starting at sector. Does not sleep.
194 */ 234 */
@@ -300,6 +340,12 @@ static int brd_make_request(struct request_queue *q, struct bio *bio)
300 get_capacity(bdev->bd_disk)) 340 get_capacity(bdev->bd_disk))
301 goto out; 341 goto out;
302 342
343 if (unlikely(bio_rw_flagged(bio, BIO_RW_DISCARD))) {
344 err = 0;
345 discard_from_brd(brd, sector, bio->bi_size);
346 goto out;
347 }
348
303 rw = bio_rw(bio); 349 rw = bio_rw(bio);
304 if (rw == READA) 350 if (rw == READA)
305 rw = READ; 351 rw = READ;
@@ -320,7 +366,7 @@ out:
320} 366}
321 367
322#ifdef CONFIG_BLK_DEV_XIP 368#ifdef CONFIG_BLK_DEV_XIP
323static int brd_direct_access (struct block_device *bdev, sector_t sector, 369static int brd_direct_access(struct block_device *bdev, sector_t sector,
324 void **kaddr, unsigned long *pfn) 370 void **kaddr, unsigned long *pfn)
325{ 371{
326 struct brd_device *brd = bdev->bd_disk->private_data; 372 struct brd_device *brd = bdev->bd_disk->private_data;
@@ -437,6 +483,11 @@ static struct brd_device *brd_alloc(int i)
437 blk_queue_max_hw_sectors(brd->brd_queue, 1024); 483 blk_queue_max_hw_sectors(brd->brd_queue, 1024);
438 blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY); 484 blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY);
439 485
486 brd->brd_queue->limits.discard_granularity = PAGE_SIZE;
487 brd->brd_queue->limits.max_discard_sectors = UINT_MAX;
488 brd->brd_queue->limits.discard_zeroes_data = 1;
489 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, brd->brd_queue);
490
440 disk = brd->brd_disk = alloc_disk(1 << part_shift); 491 disk = brd->brd_disk = alloc_disk(1 << part_shift);
441 if (!disk) 492 if (!disk)
442 goto out_free_queue; 493 goto out_free_queue;
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index e1d0e2cfec72..3381505c8a6c 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -188,11 +188,11 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd)
188 188
189 sa = h->scsi_ctlr; 189 sa = h->scsi_ctlr;
190 stk = &sa->cmd_stack; 190 stk = &sa->cmd_stack;
191 stk->top++;
191 if (stk->top >= CMD_STACK_SIZE) { 192 if (stk->top >= CMD_STACK_SIZE) {
192 printk("cciss: scsi_cmd_free called too many times.\n"); 193 printk("cciss: scsi_cmd_free called too many times.\n");
193 BUG(); 194 BUG();
194 } 195 }
195 stk->top++;
196 stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd; 196 stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd;
197} 197}
198 198
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e9654c8d5b62..485ed8c7d623 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -943,8 +943,7 @@ struct drbd_conf {
943 struct drbd_work resync_work, 943 struct drbd_work resync_work,
944 unplug_work, 944 unplug_work,
945 md_sync_work, 945 md_sync_work,
946 delay_probe_work, 946 delay_probe_work;
947 uuid_work;
948 struct timer_list resync_timer; 947 struct timer_list resync_timer;
949 struct timer_list md_sync_timer; 948 struct timer_list md_sync_timer;
950 struct timer_list delay_probe_timer; 949 struct timer_list delay_probe_timer;
@@ -1069,7 +1068,6 @@ struct drbd_conf {
1069 struct timeval dps_time; /* delay-probes-start-time */ 1068 struct timeval dps_time; /* delay-probes-start-time */
1070 unsigned int dp_volume_last; /* send_cnt of last delay probe */ 1069 unsigned int dp_volume_last; /* send_cnt of last delay probe */
1071 int c_sync_rate; /* current resync rate after delay_probe magic */ 1070 int c_sync_rate; /* current resync rate after delay_probe magic */
1072 atomic_t new_c_uuid;
1073}; 1071};
1074 1072
1075static inline struct drbd_conf *minor_to_mdev(unsigned int minor) 1073static inline struct drbd_conf *minor_to_mdev(unsigned int minor)
@@ -1476,7 +1474,6 @@ extern int w_e_end_ov_req(struct drbd_conf *, struct drbd_work *, int);
1476extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int); 1474extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int);
1477extern int w_resync_inactive(struct drbd_conf *, struct drbd_work *, int); 1475extern int w_resync_inactive(struct drbd_conf *, struct drbd_work *, int);
1478extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int); 1476extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int);
1479extern int w_io_error(struct drbd_conf *, struct drbd_work *, int);
1480extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int); 1477extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int);
1481extern int w_make_resync_request(struct drbd_conf *, struct drbd_work *, int); 1478extern int w_make_resync_request(struct drbd_conf *, struct drbd_work *, int);
1482extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int); 1479extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int);
@@ -1542,7 +1539,7 @@ static inline void drbd_tcp_nodelay(struct socket *sock)
1542 1539
1543static inline void drbd_tcp_quickack(struct socket *sock) 1540static inline void drbd_tcp_quickack(struct socket *sock)
1544{ 1541{
1545 int __user val = 1; 1542 int __user val = 2;
1546 (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK, 1543 (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK,
1547 (char __user *)&val, sizeof(val)); 1544 (char __user *)&val, sizeof(val));
1548} 1545}
@@ -1728,7 +1725,7 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach,
1728 switch (mdev->ldev->dc.on_io_error) { 1725 switch (mdev->ldev->dc.on_io_error) {
1729 case EP_PASS_ON: 1726 case EP_PASS_ON:
1730 if (!forcedetach) { 1727 if (!forcedetach) {
1731 if (printk_ratelimit()) 1728 if (__ratelimit(&drbd_ratelimit_state))
1732 dev_err(DEV, "Local IO failed in %s." 1729 dev_err(DEV, "Local IO failed in %s."
1733 "Passing error on...\n", where); 1730 "Passing error on...\n", where);
1734 break; 1731 break;
@@ -2219,8 +2216,6 @@ static inline int __inc_ap_bio_cond(struct drbd_conf *mdev)
2219 return 0; 2216 return 0;
2220 if (test_bit(BITMAP_IO, &mdev->flags)) 2217 if (test_bit(BITMAP_IO, &mdev->flags))
2221 return 0; 2218 return 0;
2222 if (atomic_read(&mdev->new_c_uuid))
2223 return 0;
2224 return 1; 2219 return 1;
2225} 2220}
2226 2221
@@ -2241,9 +2236,6 @@ static inline void inc_ap_bio(struct drbd_conf *mdev, int count)
2241 * to avoid races with the reconnect code, 2236 * to avoid races with the reconnect code,
2242 * we need to atomic_inc within the spinlock. */ 2237 * we need to atomic_inc within the spinlock. */
2243 2238
2244 if (atomic_read(&mdev->new_c_uuid) && atomic_add_unless(&mdev->new_c_uuid, -1, 1))
2245 drbd_queue_work_front(&mdev->data.work, &mdev->uuid_work);
2246
2247 spin_lock_irq(&mdev->req_lock); 2239 spin_lock_irq(&mdev->req_lock);
2248 while (!__inc_ap_bio_cond(mdev)) { 2240 while (!__inc_ap_bio_cond(mdev)) {
2249 prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE); 2241 prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index be2d2da9cdba..6b077f93acc6 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1215,18 +1215,17 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1215 ns.pdsk == D_OUTDATED)) { 1215 ns.pdsk == D_OUTDATED)) {
1216 if (get_ldev(mdev)) { 1216 if (get_ldev(mdev)) {
1217 if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && 1217 if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) &&
1218 mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE && 1218 mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
1219 !atomic_read(&mdev->new_c_uuid)) 1219 drbd_uuid_new_current(mdev);
1220 atomic_set(&mdev->new_c_uuid, 2); 1220 drbd_send_uuids(mdev);
1221 }
1221 put_ldev(mdev); 1222 put_ldev(mdev);
1222 } 1223 }
1223 } 1224 }
1224 1225
1225 if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) { 1226 if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) {
1226 /* Diskless peer becomes primary or got connected do diskless, primary peer. */ 1227 if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0)
1227 if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0 && 1228 drbd_uuid_new_current(mdev);
1228 !atomic_read(&mdev->new_c_uuid))
1229 atomic_set(&mdev->new_c_uuid, 2);
1230 1229
1231 /* D_DISKLESS Peer becomes secondary */ 1230 /* D_DISKLESS Peer becomes secondary */
1232 if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) 1231 if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
@@ -1350,24 +1349,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1350 drbd_md_sync(mdev); 1349 drbd_md_sync(mdev);
1351} 1350}
1352 1351
1353static int w_new_current_uuid(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
1354{
1355 if (get_ldev(mdev)) {
1356 if (mdev->ldev->md.uuid[UI_BITMAP] == 0) {
1357 drbd_uuid_new_current(mdev);
1358 if (get_net_conf(mdev)) {
1359 drbd_send_uuids(mdev);
1360 put_net_conf(mdev);
1361 }
1362 drbd_md_sync(mdev);
1363 }
1364 put_ldev(mdev);
1365 }
1366 atomic_dec(&mdev->new_c_uuid);
1367 wake_up(&mdev->misc_wait);
1368
1369 return 1;
1370}
1371 1352
1372static int drbd_thread_setup(void *arg) 1353static int drbd_thread_setup(void *arg)
1373{ 1354{
@@ -2291,9 +2272,9 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *
2291 * with page_count == 0 or PageSlab. 2272 * with page_count == 0 or PageSlab.
2292 */ 2273 */
2293static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, 2274static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page,
2294 int offset, size_t size) 2275 int offset, size_t size, unsigned msg_flags)
2295{ 2276{
2296 int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, 0); 2277 int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, msg_flags);
2297 kunmap(page); 2278 kunmap(page);
2298 if (sent == size) 2279 if (sent == size)
2299 mdev->send_cnt += size>>9; 2280 mdev->send_cnt += size>>9;
@@ -2301,7 +2282,7 @@ static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page,
2301} 2282}
2302 2283
2303static int _drbd_send_page(struct drbd_conf *mdev, struct page *page, 2284static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
2304 int offset, size_t size) 2285 int offset, size_t size, unsigned msg_flags)
2305{ 2286{
2306 mm_segment_t oldfs = get_fs(); 2287 mm_segment_t oldfs = get_fs();
2307 int sent, ok; 2288 int sent, ok;
@@ -2314,14 +2295,15 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
2314 * __page_cache_release a page that would actually still be referenced 2295 * __page_cache_release a page that would actually still be referenced
2315 * by someone, leading to some obscure delayed Oops somewhere else. */ 2296 * by someone, leading to some obscure delayed Oops somewhere else. */
2316 if (disable_sendpage || (page_count(page) < 1) || PageSlab(page)) 2297 if (disable_sendpage || (page_count(page) < 1) || PageSlab(page))
2317 return _drbd_no_send_page(mdev, page, offset, size); 2298 return _drbd_no_send_page(mdev, page, offset, size, msg_flags);
2318 2299
2300 msg_flags |= MSG_NOSIGNAL;
2319 drbd_update_congested(mdev); 2301 drbd_update_congested(mdev);
2320 set_fs(KERNEL_DS); 2302 set_fs(KERNEL_DS);
2321 do { 2303 do {
2322 sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page, 2304 sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page,
2323 offset, len, 2305 offset, len,
2324 MSG_NOSIGNAL); 2306 msg_flags);
2325 if (sent == -EAGAIN) { 2307 if (sent == -EAGAIN) {
2326 if (we_should_drop_the_connection(mdev, 2308 if (we_should_drop_the_connection(mdev,
2327 mdev->data.socket)) 2309 mdev->data.socket))
@@ -2350,9 +2332,11 @@ static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
2350{ 2332{
2351 struct bio_vec *bvec; 2333 struct bio_vec *bvec;
2352 int i; 2334 int i;
2335 /* hint all but last page with MSG_MORE */
2353 __bio_for_each_segment(bvec, bio, i, 0) { 2336 __bio_for_each_segment(bvec, bio, i, 0) {
2354 if (!_drbd_no_send_page(mdev, bvec->bv_page, 2337 if (!_drbd_no_send_page(mdev, bvec->bv_page,
2355 bvec->bv_offset, bvec->bv_len)) 2338 bvec->bv_offset, bvec->bv_len,
2339 i == bio->bi_vcnt -1 ? 0 : MSG_MORE))
2356 return 0; 2340 return 0;
2357 } 2341 }
2358 return 1; 2342 return 1;
@@ -2362,12 +2346,13 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
2362{ 2346{
2363 struct bio_vec *bvec; 2347 struct bio_vec *bvec;
2364 int i; 2348 int i;
2349 /* hint all but last page with MSG_MORE */
2365 __bio_for_each_segment(bvec, bio, i, 0) { 2350 __bio_for_each_segment(bvec, bio, i, 0) {
2366 if (!_drbd_send_page(mdev, bvec->bv_page, 2351 if (!_drbd_send_page(mdev, bvec->bv_page,
2367 bvec->bv_offset, bvec->bv_len)) 2352 bvec->bv_offset, bvec->bv_len,
2353 i == bio->bi_vcnt -1 ? 0 : MSG_MORE))
2368 return 0; 2354 return 0;
2369 } 2355 }
2370
2371 return 1; 2356 return 1;
2372} 2357}
2373 2358
@@ -2375,9 +2360,11 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e)
2375{ 2360{
2376 struct page *page = e->pages; 2361 struct page *page = e->pages;
2377 unsigned len = e->size; 2362 unsigned len = e->size;
2363 /* hint all but last page with MSG_MORE */
2378 page_chain_for_each(page) { 2364 page_chain_for_each(page) {
2379 unsigned l = min_t(unsigned, len, PAGE_SIZE); 2365 unsigned l = min_t(unsigned, len, PAGE_SIZE);
2380 if (!_drbd_send_page(mdev, page, 0, l)) 2366 if (!_drbd_send_page(mdev, page, 0, l,
2367 page_chain_next(page) ? MSG_MORE : 0))
2381 return 0; 2368 return 0;
2382 len -= l; 2369 len -= l;
2383 } 2370 }
@@ -2457,11 +2444,11 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
2457 p.dp_flags = cpu_to_be32(dp_flags); 2444 p.dp_flags = cpu_to_be32(dp_flags);
2458 set_bit(UNPLUG_REMOTE, &mdev->flags); 2445 set_bit(UNPLUG_REMOTE, &mdev->flags);
2459 ok = (sizeof(p) == 2446 ok = (sizeof(p) ==
2460 drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE)); 2447 drbd_send(mdev, mdev->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0));
2461 if (ok && dgs) { 2448 if (ok && dgs) {
2462 dgb = mdev->int_dig_out; 2449 dgb = mdev->int_dig_out;
2463 drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); 2450 drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb);
2464 ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); 2451 ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0);
2465 } 2452 }
2466 if (ok) { 2453 if (ok) {
2467 if (mdev->net_conf->wire_protocol == DRBD_PROT_A) 2454 if (mdev->net_conf->wire_protocol == DRBD_PROT_A)
@@ -2510,11 +2497,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
2510 return 0; 2497 return 0;
2511 2498
2512 ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, 2499 ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p,
2513 sizeof(p), MSG_MORE); 2500 sizeof(p), dgs ? MSG_MORE : 0);
2514 if (ok && dgs) { 2501 if (ok && dgs) {
2515 dgb = mdev->int_dig_out; 2502 dgb = mdev->int_dig_out;
2516 drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb); 2503 drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb);
2517 ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); 2504 ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0);
2518 } 2505 }
2519 if (ok) 2506 if (ok)
2520 ok = _drbd_send_zc_ee(mdev, e); 2507 ok = _drbd_send_zc_ee(mdev, e);
@@ -2708,7 +2695,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
2708 atomic_set(&mdev->net_cnt, 0); 2695 atomic_set(&mdev->net_cnt, 0);
2709 atomic_set(&mdev->packet_seq, 0); 2696 atomic_set(&mdev->packet_seq, 0);
2710 atomic_set(&mdev->pp_in_use, 0); 2697 atomic_set(&mdev->pp_in_use, 0);
2711 atomic_set(&mdev->new_c_uuid, 0);
2712 2698
2713 mutex_init(&mdev->md_io_mutex); 2699 mutex_init(&mdev->md_io_mutex);
2714 mutex_init(&mdev->data.mutex); 2700 mutex_init(&mdev->data.mutex);
@@ -2739,14 +2725,12 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
2739 INIT_LIST_HEAD(&mdev->bm_io_work.w.list); 2725 INIT_LIST_HEAD(&mdev->bm_io_work.w.list);
2740 INIT_LIST_HEAD(&mdev->delay_probes); 2726 INIT_LIST_HEAD(&mdev->delay_probes);
2741 INIT_LIST_HEAD(&mdev->delay_probe_work.list); 2727 INIT_LIST_HEAD(&mdev->delay_probe_work.list);
2742 INIT_LIST_HEAD(&mdev->uuid_work.list);
2743 2728
2744 mdev->resync_work.cb = w_resync_inactive; 2729 mdev->resync_work.cb = w_resync_inactive;
2745 mdev->unplug_work.cb = w_send_write_hint; 2730 mdev->unplug_work.cb = w_send_write_hint;
2746 mdev->md_sync_work.cb = w_md_sync; 2731 mdev->md_sync_work.cb = w_md_sync;
2747 mdev->bm_io_work.w.cb = w_bitmap_io; 2732 mdev->bm_io_work.w.cb = w_bitmap_io;
2748 mdev->delay_probe_work.cb = w_delay_probes; 2733 mdev->delay_probe_work.cb = w_delay_probes;
2749 mdev->uuid_work.cb = w_new_current_uuid;
2750 init_timer(&mdev->resync_timer); 2734 init_timer(&mdev->resync_timer);
2751 init_timer(&mdev->md_sync_timer); 2735 init_timer(&mdev->md_sync_timer);
2752 init_timer(&mdev->delay_probe_timer); 2736 init_timer(&mdev->delay_probe_timer);
@@ -3799,7 +3783,7 @@ _drbd_insert_fault(struct drbd_conf *mdev, unsigned int type)
3799 if (ret) { 3783 if (ret) {
3800 fault_count++; 3784 fault_count++;
3801 3785
3802 if (printk_ratelimit()) 3786 if (__ratelimit(&drbd_ratelimit_state))
3803 dev_warn(DEV, "***Simulating %s failure\n", 3787 dev_warn(DEV, "***Simulating %s failure\n",
3804 _drbd_fault_str(type)); 3788 _drbd_fault_str(type));
3805 } 3789 }
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index bc9ab7fb2cc7..dff48701b84d 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -42,7 +42,6 @@
42#include <linux/unistd.h> 42#include <linux/unistd.h>
43#include <linux/vmalloc.h> 43#include <linux/vmalloc.h>
44#include <linux/random.h> 44#include <linux/random.h>
45#include <linux/mm.h>
46#include <linux/string.h> 45#include <linux/string.h>
47#include <linux/scatterlist.h> 46#include <linux/scatterlist.h>
48#include "drbd_int.h" 47#include "drbd_int.h"
@@ -571,6 +570,25 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size)
571 return rv; 570 return rv;
572} 571}
573 572
573/* quoting tcp(7):
574 * On individual connections, the socket buffer size must be set prior to the
575 * listen(2) or connect(2) calls in order to have it take effect.
576 * This is our wrapper to do so.
577 */
578static void drbd_setbufsize(struct socket *sock, unsigned int snd,
579 unsigned int rcv)
580{
581 /* open coded SO_SNDBUF, SO_RCVBUF */
582 if (snd) {
583 sock->sk->sk_sndbuf = snd;
584 sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
585 }
586 if (rcv) {
587 sock->sk->sk_rcvbuf = rcv;
588 sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
589 }
590}
591
574static struct socket *drbd_try_connect(struct drbd_conf *mdev) 592static struct socket *drbd_try_connect(struct drbd_conf *mdev)
575{ 593{
576 const char *what; 594 const char *what;
@@ -592,6 +610,8 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
592 610
593 sock->sk->sk_rcvtimeo = 611 sock->sk->sk_rcvtimeo =
594 sock->sk->sk_sndtimeo = mdev->net_conf->try_connect_int*HZ; 612 sock->sk->sk_sndtimeo = mdev->net_conf->try_connect_int*HZ;
613 drbd_setbufsize(sock, mdev->net_conf->sndbuf_size,
614 mdev->net_conf->rcvbuf_size);
595 615
596 /* explicitly bind to the configured IP as source IP 616 /* explicitly bind to the configured IP as source IP
597 * for the outgoing connections. 617 * for the outgoing connections.
@@ -670,6 +690,8 @@ static struct socket *drbd_wait_for_connect(struct drbd_conf *mdev)
670 s_listen->sk->sk_reuse = 1; /* SO_REUSEADDR */ 690 s_listen->sk->sk_reuse = 1; /* SO_REUSEADDR */
671 s_listen->sk->sk_rcvtimeo = timeo; 691 s_listen->sk->sk_rcvtimeo = timeo;
672 s_listen->sk->sk_sndtimeo = timeo; 692 s_listen->sk->sk_sndtimeo = timeo;
693 drbd_setbufsize(s_listen, mdev->net_conf->sndbuf_size,
694 mdev->net_conf->rcvbuf_size);
673 695
674 what = "bind before listen"; 696 what = "bind before listen";
675 err = s_listen->ops->bind(s_listen, 697 err = s_listen->ops->bind(s_listen,
@@ -856,16 +878,6 @@ retry:
856 sock->sk->sk_priority = TC_PRIO_INTERACTIVE_BULK; 878 sock->sk->sk_priority = TC_PRIO_INTERACTIVE_BULK;
857 msock->sk->sk_priority = TC_PRIO_INTERACTIVE; 879 msock->sk->sk_priority = TC_PRIO_INTERACTIVE;
858 880
859 if (mdev->net_conf->sndbuf_size) {
860 sock->sk->sk_sndbuf = mdev->net_conf->sndbuf_size;
861 sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
862 }
863
864 if (mdev->net_conf->rcvbuf_size) {
865 sock->sk->sk_rcvbuf = mdev->net_conf->rcvbuf_size;
866 sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
867 }
868
869 /* NOT YET ... 881 /* NOT YET ...
870 * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; 882 * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
871 * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; 883 * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
@@ -1154,17 +1166,6 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e,
1154 unsigned n_bios = 0; 1166 unsigned n_bios = 0;
1155 unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT; 1167 unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT;
1156 1168
1157 if (atomic_read(&mdev->new_c_uuid)) {
1158 if (atomic_add_unless(&mdev->new_c_uuid, -1, 1)) {
1159 drbd_uuid_new_current(mdev);
1160 drbd_md_sync(mdev);
1161
1162 atomic_dec(&mdev->new_c_uuid);
1163 wake_up(&mdev->misc_wait);
1164 }
1165 wait_event(mdev->misc_wait, !atomic_read(&mdev->new_c_uuid));
1166 }
1167
1168 /* In most cases, we will only need one bio. But in case the lower 1169 /* In most cases, we will only need one bio. But in case the lower
1169 * level restrictions happen to be different at this offset on this 1170 * level restrictions happen to be different at this offset on this
1170 * side than those of the sending peer, we may need to submit the 1171 * side than those of the sending peer, we may need to submit the
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 3397f11d0ba9..654f1ef5cbb0 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -102,32 +102,7 @@ static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const
102 } 102 }
103 } 103 }
104 104
105 /* if it was a local io error, we want to notify our 105 drbd_req_free(req);
106 * peer about that, and see if we need to
107 * detach the disk and stuff.
108 * to avoid allocating some special work
109 * struct, reuse the request. */
110
111 /* THINK
112 * why do we do this not when we detect the error,
113 * but delay it until it is "done", i.e. possibly
114 * until the next barrier ack? */
115
116 if (rw == WRITE &&
117 ((s & RQ_LOCAL_MASK) && !(s & RQ_LOCAL_OK))) {
118 if (!(req->w.list.next == LIST_POISON1 ||
119 list_empty(&req->w.list))) {
120 /* DEBUG ASSERT only; if this triggers, we
121 * probably corrupt the worker list here */
122 dev_err(DEV, "req->w.list.next = %p\n", req->w.list.next);
123 dev_err(DEV, "req->w.list.prev = %p\n", req->w.list.prev);
124 }
125 req->w.cb = w_io_error;
126 drbd_queue_work(&mdev->data.work, &req->w);
127 /* drbd_req_free() is done in w_io_error */
128 } else {
129 drbd_req_free(req);
130 }
131} 106}
132 107
133static void queue_barrier(struct drbd_conf *mdev) 108static void queue_barrier(struct drbd_conf *mdev)
@@ -453,9 +428,6 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what,
453 req->rq_state |= RQ_LOCAL_COMPLETED; 428 req->rq_state |= RQ_LOCAL_COMPLETED;
454 req->rq_state &= ~RQ_LOCAL_PENDING; 429 req->rq_state &= ~RQ_LOCAL_PENDING;
455 430
456 dev_alert(DEV, "Local WRITE failed sec=%llus size=%u\n",
457 (unsigned long long)req->sector, req->size);
458 /* and now: check how to handle local io error. */
459 __drbd_chk_io_error(mdev, FALSE); 431 __drbd_chk_io_error(mdev, FALSE);
460 _req_may_be_done(req, m); 432 _req_may_be_done(req, m);
461 put_ldev(mdev); 433 put_ldev(mdev);
@@ -475,22 +447,21 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what,
475 req->rq_state |= RQ_LOCAL_COMPLETED; 447 req->rq_state |= RQ_LOCAL_COMPLETED;
476 req->rq_state &= ~RQ_LOCAL_PENDING; 448 req->rq_state &= ~RQ_LOCAL_PENDING;
477 449
478 dev_alert(DEV, "Local READ failed sec=%llus size=%u\n",
479 (unsigned long long)req->sector, req->size);
480 /* _req_mod(req,to_be_send); oops, recursion... */
481 D_ASSERT(!(req->rq_state & RQ_NET_MASK)); 450 D_ASSERT(!(req->rq_state & RQ_NET_MASK));
482 req->rq_state |= RQ_NET_PENDING;
483 inc_ap_pending(mdev);
484 451
485 __drbd_chk_io_error(mdev, FALSE); 452 __drbd_chk_io_error(mdev, FALSE);
486 put_ldev(mdev); 453 put_ldev(mdev);
487 /* NOTE: if we have no connection,
488 * or know the peer has no good data either,
489 * then we don't actually need to "queue_for_net_read",
490 * but we do so anyways, since the drbd_io_error()
491 * and the potential state change to "Diskless"
492 * needs to be done from process context */
493 454
455 /* no point in retrying if there is no good remote data,
456 * or we have no connection. */
457 if (mdev->state.pdsk != D_UP_TO_DATE) {
458 _req_may_be_done(req, m);
459 break;
460 }
461
462 /* _req_mod(req,to_be_send); oops, recursion... */
463 req->rq_state |= RQ_NET_PENDING;
464 inc_ap_pending(mdev);
494 /* fall through: _req_mod(req,queue_for_net_read); */ 465 /* fall through: _req_mod(req,queue_for_net_read); */
495 466
496 case queue_for_net_read: 467 case queue_for_net_read:
@@ -600,6 +571,9 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what,
600 _req_may_be_done(req, m); 571 _req_may_be_done(req, m);
601 break; 572 break;
602 573
574 case read_retry_remote_canceled:
575 req->rq_state &= ~RQ_NET_QUEUED;
576 /* fall through, in case we raced with drbd_disconnect */
603 case connection_lost_while_pending: 577 case connection_lost_while_pending:
604 /* transfer log cleanup after connection loss */ 578 /* transfer log cleanup after connection loss */
605 /* assert something? */ 579 /* assert something? */
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 16119d7056cc..02d575d24518 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -91,6 +91,7 @@ enum drbd_req_event {
91 send_failed, 91 send_failed,
92 handed_over_to_network, 92 handed_over_to_network,
93 connection_lost_while_pending, 93 connection_lost_while_pending,
94 read_retry_remote_canceled,
94 recv_acked_by_peer, 95 recv_acked_by_peer,
95 write_acked_by_peer, 96 write_acked_by_peer,
96 write_acked_by_peer_and_sis, /* and set_in_sync */ 97 write_acked_by_peer_and_sis, /* and set_in_sync */
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 727ff6339754..b623ceee2a4a 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -224,9 +224,6 @@ void drbd_endio_pri(struct bio *bio, int error)
224 enum drbd_req_event what; 224 enum drbd_req_event what;
225 int uptodate = bio_flagged(bio, BIO_UPTODATE); 225 int uptodate = bio_flagged(bio, BIO_UPTODATE);
226 226
227 if (error)
228 dev_warn(DEV, "p %s: error=%d\n",
229 bio_data_dir(bio) == WRITE ? "write" : "read", error);
230 if (!error && !uptodate) { 227 if (!error && !uptodate) {
231 dev_warn(DEV, "p %s: setting error to -EIO\n", 228 dev_warn(DEV, "p %s: setting error to -EIO\n",
232 bio_data_dir(bio) == WRITE ? "write" : "read"); 229 bio_data_dir(bio) == WRITE ? "write" : "read");
@@ -257,20 +254,6 @@ void drbd_endio_pri(struct bio *bio, int error)
257 complete_master_bio(mdev, &m); 254 complete_master_bio(mdev, &m);
258} 255}
259 256
260int w_io_error(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
261{
262 struct drbd_request *req = container_of(w, struct drbd_request, w);
263
264 /* NOTE: mdev->ldev can be NULL by the time we get here! */
265 /* D_ASSERT(mdev->ldev->dc.on_io_error != EP_PASS_ON); */
266
267 /* the only way this callback is scheduled is from _req_may_be_done,
268 * when it is done and had a local write error, see comments there */
269 drbd_req_free(req);
270
271 return TRUE;
272}
273
274int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) 257int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
275{ 258{
276 struct drbd_request *req = container_of(w, struct drbd_request, w); 259 struct drbd_request *req = container_of(w, struct drbd_request, w);
@@ -280,12 +263,9 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
280 * to give the disk the chance to relocate that block */ 263 * to give the disk the chance to relocate that block */
281 264
282 spin_lock_irq(&mdev->req_lock); 265 spin_lock_irq(&mdev->req_lock);
283 if (cancel || 266 if (cancel || mdev->state.pdsk != D_UP_TO_DATE) {
284 mdev->state.conn < C_CONNECTED || 267 _req_mod(req, read_retry_remote_canceled);
285 mdev->state.pdsk <= D_INCONSISTENT) {
286 _req_mod(req, send_canceled);
287 spin_unlock_irq(&mdev->req_lock); 268 spin_unlock_irq(&mdev->req_lock);
288 dev_alert(DEV, "WE ARE LOST. Local IO failure, no peer.\n");
289 return 1; 269 return 1;
290 } 270 }
291 spin_unlock_irq(&mdev->req_lock); 271 spin_unlock_irq(&mdev->req_lock);
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 52f2d11bc7b9..ed6fb91123ab 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -1159,8 +1159,10 @@ static struct of_device_id swim3_match[] =
1159 1159
1160static struct macio_driver swim3_driver = 1160static struct macio_driver swim3_driver =
1161{ 1161{
1162 .name = "swim3", 1162 .driver = {
1163 .match_table = swim3_match, 1163 .name = "swim3",
1164 .of_match_table = swim3_match,
1165 },
1164 .probe = swim3_attach, 1166 .probe = swim3_attach,
1165#if 0 1167#if 0
1166 .suspend = swim3_suspend, 1168 .suspend = swim3_suspend,
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 83fa09a836ca..258bc2ae2885 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -298,7 +298,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
298 err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, 298 err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX,
299 offsetof(struct virtio_blk_config, seg_max), 299 offsetof(struct virtio_blk_config, seg_max),
300 &sg_elems); 300 &sg_elems);
301 if (err) 301
302 /* We need at least one SG element, whatever they say. */
303 if (err || !sg_elems)
302 sg_elems = 1; 304 sg_elems = 1;
303 305
304 /* We need an extra sg elements at head and tail. */ 306 /* We need an extra sg elements at head and tail. */
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index f09fc0e2062d..7cfcc629a7fd 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -1123,6 +1123,7 @@ source "drivers/s390/char/Kconfig"
1123 1123
1124config RAMOOPS 1124config RAMOOPS
1125 tristate "Log panic/oops to a RAM buffer" 1125 tristate "Log panic/oops to a RAM buffer"
1126 depends on HAS_IOMEM
1126 default n 1127 default n
1127 help 1128 help
1128 This enables panic and oops messages to be logged to a circular 1129 This enables panic and oops messages to be logged to a circular
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index e8ea6825822c..9344216183a4 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -1059,7 +1059,7 @@ static void intel_i9xx_setup_flush(void)
1059 } 1059 }
1060} 1060}
1061 1061
1062static int intel_i915_configure(void) 1062static int intel_i9xx_configure(void)
1063{ 1063{
1064 struct aper_size_info_fixed *current_size; 1064 struct aper_size_info_fixed *current_size;
1065 u32 temp; 1065 u32 temp;
@@ -1207,6 +1207,38 @@ static int intel_i9xx_fetch_size(void)
1207 return 0; 1207 return 0;
1208} 1208}
1209 1209
1210static int intel_i915_get_gtt_size(void)
1211{
1212 int size;
1213
1214 if (IS_G33) {
1215 u16 gmch_ctrl;
1216
1217 /* G33's GTT size defined in gmch_ctrl */
1218 pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
1219 switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
1220 case G33_PGETBL_SIZE_1M:
1221 size = 1024;
1222 break;
1223 case G33_PGETBL_SIZE_2M:
1224 size = 2048;
1225 break;
1226 default:
1227 dev_info(&agp_bridge->dev->dev,
1228 "unknown page table size 0x%x, assuming 512KB\n",
1229 (gmch_ctrl & G33_PGETBL_SIZE_MASK));
1230 size = 512;
1231 }
1232 } else {
1233 /* On previous hardware, the GTT size was just what was
1234 * required to map the aperture.
1235 */
1236 size = agp_bridge->driver->fetch_size();
1237 }
1238
1239 return KB(size);
1240}
1241
1210/* The intel i915 automatically initializes the agp aperture during POST. 1242/* The intel i915 automatically initializes the agp aperture during POST.
1211 * Use the memory already set aside for in the GTT. 1243 * Use the memory already set aside for in the GTT.
1212 */ 1244 */
@@ -1216,7 +1248,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
1216 struct aper_size_info_fixed *size; 1248 struct aper_size_info_fixed *size;
1217 int num_entries; 1249 int num_entries;
1218 u32 temp, temp2; 1250 u32 temp, temp2;
1219 int gtt_map_size = 256 * 1024; 1251 int gtt_map_size;
1220 1252
1221 size = agp_bridge->current_size; 1253 size = agp_bridge->current_size;
1222 page_order = size->page_order; 1254 page_order = size->page_order;
@@ -1226,8 +1258,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
1226 pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); 1258 pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
1227 pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); 1259 pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2);
1228 1260
1229 if (IS_G33) 1261 gtt_map_size = intel_i915_get_gtt_size();
1230 gtt_map_size = 1024 * 1024; /* 1M on G33 */ 1262
1231 intel_private.gtt = ioremap(temp2, gtt_map_size); 1263 intel_private.gtt = ioremap(temp2, gtt_map_size);
1232 if (!intel_private.gtt) 1264 if (!intel_private.gtt)
1233 return -ENOMEM; 1265 return -ENOMEM;
@@ -1422,7 +1454,7 @@ static const struct agp_bridge_driver intel_915_driver = {
1422 .size_type = FIXED_APER_SIZE, 1454 .size_type = FIXED_APER_SIZE,
1423 .num_aperture_sizes = 4, 1455 .num_aperture_sizes = 4,
1424 .needs_scratch_page = true, 1456 .needs_scratch_page = true,
1425 .configure = intel_i915_configure, 1457 .configure = intel_i9xx_configure,
1426 .fetch_size = intel_i9xx_fetch_size, 1458 .fetch_size = intel_i9xx_fetch_size,
1427 .cleanup = intel_i915_cleanup, 1459 .cleanup = intel_i915_cleanup,
1428 .mask_memory = intel_i810_mask_memory, 1460 .mask_memory = intel_i810_mask_memory,
@@ -1455,7 +1487,7 @@ static const struct agp_bridge_driver intel_i965_driver = {
1455 .size_type = FIXED_APER_SIZE, 1487 .size_type = FIXED_APER_SIZE,
1456 .num_aperture_sizes = 4, 1488 .num_aperture_sizes = 4,
1457 .needs_scratch_page = true, 1489 .needs_scratch_page = true,
1458 .configure = intel_i915_configure, 1490 .configure = intel_i9xx_configure,
1459 .fetch_size = intel_i9xx_fetch_size, 1491 .fetch_size = intel_i9xx_fetch_size,
1460 .cleanup = intel_i915_cleanup, 1492 .cleanup = intel_i915_cleanup,
1461 .mask_memory = intel_i965_mask_memory, 1493 .mask_memory = intel_i965_mask_memory,
@@ -1488,7 +1520,7 @@ static const struct agp_bridge_driver intel_g33_driver = {
1488 .size_type = FIXED_APER_SIZE, 1520 .size_type = FIXED_APER_SIZE,
1489 .num_aperture_sizes = 4, 1521 .num_aperture_sizes = 4,
1490 .needs_scratch_page = true, 1522 .needs_scratch_page = true,
1491 .configure = intel_i915_configure, 1523 .configure = intel_i9xx_configure,
1492 .fetch_size = intel_i9xx_fetch_size, 1524 .fetch_size = intel_i9xx_fetch_size,
1493 .cleanup = intel_i915_cleanup, 1525 .cleanup = intel_i915_cleanup,
1494 .mask_memory = intel_i965_mask_memory, 1526 .mask_memory = intel_i965_mask_memory,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 95db71360d24..f845a8f718b3 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -415,7 +415,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
415 bridge->gatt_table_real = (u32 *) table; 415 bridge->gatt_table_real = (u32 *) table;
416 /* Need to clear out any dirty data still sitting in caches */ 416 /* Need to clear out any dirty data still sitting in caches */
417 flush_dcache_range((unsigned long)table, 417 flush_dcache_range((unsigned long)table,
418 (unsigned long)(table_end + PAGE_SIZE)); 418 (unsigned long)table_end + 1);
419 bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG); 419 bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
420 420
421 if (bridge->gatt_table == NULL) 421 if (bridge->gatt_table == NULL)
diff --git a/drivers/char/n_gsm.c b/drivers/char/n_gsm.c
index c4161d5e053d..e4089c432f15 100644
--- a/drivers/char/n_gsm.c
+++ b/drivers/char/n_gsm.c
@@ -904,9 +904,7 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
904 int len; 904 int len;
905 /* Priority ordering: We should do priority with RR of the groups */ 905 /* Priority ordering: We should do priority with RR of the groups */
906 int i = 1; 906 int i = 1;
907 unsigned long flags;
908 907
909 spin_lock_irqsave(&gsm->tx_lock, flags);
910 while (i < NUM_DLCI) { 908 while (i < NUM_DLCI) {
911 struct gsm_dlci *dlci; 909 struct gsm_dlci *dlci;
912 910
@@ -927,7 +925,6 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
927 if (len == 0) 925 if (len == 0)
928 i++; 926 i++;
929 } 927 }
930 spin_unlock_irqrestore(&gsm->tx_lock, flags);
931} 928}
932 929
933/** 930/**
@@ -2230,12 +2227,16 @@ static int gsmld_open(struct tty_struct *tty)
2230static void gsmld_write_wakeup(struct tty_struct *tty) 2227static void gsmld_write_wakeup(struct tty_struct *tty)
2231{ 2228{
2232 struct gsm_mux *gsm = tty->disc_data; 2229 struct gsm_mux *gsm = tty->disc_data;
2230 unsigned long flags;
2233 2231
2234 /* Queue poll */ 2232 /* Queue poll */
2235 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); 2233 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
2236 gsm_data_kick(gsm); 2234 gsm_data_kick(gsm);
2237 if (gsm->tx_bytes < TX_THRESH_LO) 2235 if (gsm->tx_bytes < TX_THRESH_LO) {
2236 spin_lock_irqsave(&gsm->tx_lock, flags);
2238 gsm_dlci_data_sweep(gsm); 2237 gsm_dlci_data_sweep(gsm);
2238 spin_unlock_irqrestore(&gsm->tx_lock, flags);
2239 }
2239} 2240}
2240 2241
2241/** 2242/**
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 8c99bf1b5e9f..942a9826bd23 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -529,6 +529,10 @@ static bool will_write_block(struct port *port)
529{ 529{
530 bool ret; 530 bool ret;
531 531
532 if (!port->guest_connected) {
533 /* Port got hot-unplugged. Let's exit. */
534 return false;
535 }
532 if (!port->host_connected) 536 if (!port->host_connected)
533 return true; 537 return true;
534 538
@@ -1099,6 +1103,13 @@ static int remove_port(struct port *port)
1099{ 1103{
1100 struct port_buffer *buf; 1104 struct port_buffer *buf;
1101 1105
1106 if (port->guest_connected) {
1107 port->guest_connected = false;
1108 port->host_connected = false;
1109 wake_up_interruptible(&port->waitqueue);
1110 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
1111 }
1112
1102 spin_lock_irq(&port->portdev->ports_lock); 1113 spin_lock_irq(&port->portdev->ports_lock);
1103 list_del(&port->list); 1114 list_del(&port->list);
1104 spin_unlock_irq(&port->portdev->ports_lock); 1115 spin_unlock_irq(&port->portdev->ports_lock);
@@ -1120,9 +1131,6 @@ static int remove_port(struct port *port)
1120 hvc_remove(port->cons.hvc); 1131 hvc_remove(port->cons.hvc);
1121#endif 1132#endif
1122 } 1133 }
1123 if (port->guest_connected)
1124 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
1125
1126 sysfs_remove_group(&port->dev->kobj, &port_attribute_group); 1134 sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
1127 device_destroy(pdrvdata.class, port->dev->devt); 1135 device_destroy(pdrvdata.class, port->dev->devt);
1128 cdev_del(&port->cdev); 1136 cdev_del(&port->cdev);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 7cdb6ee569cd..1296c42ed5c6 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -304,7 +304,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
304 d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); 304 d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
305 s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); 305 s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
306 scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); 306 scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);
307 scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char, 307 scr_memsetw(d + (b - t - nr) * vc->vc_size_row, vc->vc_video_erase_char,
308 vc->vc_size_row * nr); 308 vc->vc_size_row * nr);
309} 309}
310 310
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 6aa10284104a..cb19dbc52136 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -1303,7 +1303,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
1303 if (!perm) 1303 if (!perm)
1304 goto eperm; 1304 goto eperm;
1305 ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); 1305 ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
1306 if (!ret) 1306 if (ret)
1307 ret = -EFAULT;
1308 else
1307 con_clear_unimap(vc, &ui); 1309 con_clear_unimap(vc, &ui);
1308 break; 1310 break;
1309 } 1311 }
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index f6677cb19789..f3d3898898ed 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -412,18 +412,10 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
412static int sh_cmt_clocksource_enable(struct clocksource *cs) 412static int sh_cmt_clocksource_enable(struct clocksource *cs)
413{ 413{
414 struct sh_cmt_priv *p = cs_to_sh_cmt(cs); 414 struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
415 int ret;
416 415
417 p->total_cycles = 0; 416 p->total_cycles = 0;
418 417
419 ret = sh_cmt_start(p, FLAG_CLOCKSOURCE); 418 return sh_cmt_start(p, FLAG_CLOCKSOURCE);
420 if (ret)
421 return ret;
422
423 /* TODO: calculate good shift from rate and counter bit width */
424 cs->shift = 0;
425 cs->mult = clocksource_hz2mult(p->rate, cs->shift);
426 return 0;
427} 419}
428 420
429static void sh_cmt_clocksource_disable(struct clocksource *cs) 421static void sh_cmt_clocksource_disable(struct clocksource *cs)
@@ -450,8 +442,20 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
450 cs->resume = sh_cmt_clocksource_resume; 442 cs->resume = sh_cmt_clocksource_resume;
451 cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); 443 cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
452 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; 444 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
445
446 /* clk_get_rate() needs an enabled clock */
447 clk_enable(p->clk);
448 p->rate = clk_get_rate(p->clk) / (p->width == 16) ? 512 : 8;
449 clk_disable(p->clk);
450
451 /* TODO: calculate good shift from rate and counter bit width */
452 cs->shift = 10;
453 cs->mult = clocksource_hz2mult(p->rate, cs->shift);
454
453 dev_info(&p->pdev->dev, "used as clock source\n"); 455 dev_info(&p->pdev->dev, "used as clock source\n");
456
454 clocksource_register(cs); 457 clocksource_register(cs);
458
455 return 0; 459 return 0;
456} 460}
457 461
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 8e44e14ec4c2..de715901b82a 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -199,16 +199,8 @@ static cycle_t sh_tmu_clocksource_read(struct clocksource *cs)
199static int sh_tmu_clocksource_enable(struct clocksource *cs) 199static int sh_tmu_clocksource_enable(struct clocksource *cs)
200{ 200{
201 struct sh_tmu_priv *p = cs_to_sh_tmu(cs); 201 struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
202 int ret;
203
204 ret = sh_tmu_enable(p);
205 if (ret)
206 return ret;
207 202
208 /* TODO: calculate good shift from rate and counter bit width */ 203 return sh_tmu_enable(p);
209 cs->shift = 10;
210 cs->mult = clocksource_hz2mult(p->rate, cs->shift);
211 return 0;
212} 204}
213 205
214static void sh_tmu_clocksource_disable(struct clocksource *cs) 206static void sh_tmu_clocksource_disable(struct clocksource *cs)
@@ -228,6 +220,16 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p,
228 cs->disable = sh_tmu_clocksource_disable; 220 cs->disable = sh_tmu_clocksource_disable;
229 cs->mask = CLOCKSOURCE_MASK(32); 221 cs->mask = CLOCKSOURCE_MASK(32);
230 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; 222 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
223
224 /* clk_get_rate() needs an enabled clock */
225 clk_enable(p->clk);
226 /* channel will be configured at parent clock / 4 */
227 p->rate = clk_get_rate(p->clk) / 4;
228 clk_disable(p->clk);
229 /* TODO: calculate good shift from rate and counter bit width */
230 cs->shift = 10;
231 cs->mult = clocksource_hz2mult(p->rate, cs->shift);
232
231 dev_info(&p->pdev->dev, "used as clock source\n"); 233 dev_info(&p->pdev->dev, "used as clock source\n");
232 clocksource_register(cs); 234 clocksource_register(cs);
233 return 0; 235 return 0;
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
index 9d65b371de64..983530ba04a7 100644
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -1158,7 +1158,7 @@ static int __init crypto4xx_probe(struct of_device *ofdev,
1158 struct device *dev = &ofdev->dev; 1158 struct device *dev = &ofdev->dev;
1159 struct crypto4xx_core_device *core_dev; 1159 struct crypto4xx_core_device *core_dev;
1160 1160
1161 rc = of_address_to_resource(ofdev->node, 0, &res); 1161 rc = of_address_to_resource(ofdev->dev.of_node, 0, &res);
1162 if (rc) 1162 if (rc)
1163 return -ENODEV; 1163 return -ENODEV;
1164 1164
@@ -1215,13 +1215,13 @@ static int __init crypto4xx_probe(struct of_device *ofdev,
1215 (unsigned long) dev); 1215 (unsigned long) dev);
1216 1216
1217 /* Register for Crypto isr, Crypto Engine IRQ */ 1217 /* Register for Crypto isr, Crypto Engine IRQ */
1218 core_dev->irq = irq_of_parse_and_map(ofdev->node, 0); 1218 core_dev->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
1219 rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0, 1219 rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0,
1220 core_dev->dev->name, dev); 1220 core_dev->dev->name, dev);
1221 if (rc) 1221 if (rc)
1222 goto err_request_irq; 1222 goto err_request_irq;
1223 1223
1224 core_dev->dev->ce_base = of_iomap(ofdev->node, 0); 1224 core_dev->dev->ce_base = of_iomap(ofdev->dev.of_node, 0);
1225 if (!core_dev->dev->ce_base) { 1225 if (!core_dev->dev->ce_base) {
1226 dev_err(dev, "failed to of_iomap\n"); 1226 dev_err(dev, "failed to of_iomap\n");
1227 goto err_iomap; 1227 goto err_iomap;
diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c
index 8566be832f51..23163fda5035 100644
--- a/drivers/crypto/n2_core.c
+++ b/drivers/crypto/n2_core.c
@@ -251,16 +251,10 @@ static void n2_base_ctx_init(struct n2_base_ctx *ctx)
251struct n2_hash_ctx { 251struct n2_hash_ctx {
252 struct n2_base_ctx base; 252 struct n2_base_ctx base;
253 253
254 struct crypto_ahash *fallback; 254 struct crypto_ahash *fallback_tfm;
255};
255 256
256 /* These next three members must match the layout created by 257struct n2_hash_req_ctx {
257 * crypto_init_shash_ops_async. This allows us to properly
258 * plumb requests we can't do in hardware down to the fallback
259 * operation, providing all of the data structures and layouts
260 * expected by those paths.
261 */
262 struct ahash_request fallback_req;
263 struct shash_desc fallback_desc;
264 union { 258 union {
265 struct md5_state md5; 259 struct md5_state md5;
266 struct sha1_state sha1; 260 struct sha1_state sha1;
@@ -269,56 +263,62 @@ struct n2_hash_ctx {
269 263
270 unsigned char hash_key[64]; 264 unsigned char hash_key[64];
271 unsigned char keyed_zero_hash[32]; 265 unsigned char keyed_zero_hash[32];
266
267 struct ahash_request fallback_req;
272}; 268};
273 269
274static int n2_hash_async_init(struct ahash_request *req) 270static int n2_hash_async_init(struct ahash_request *req)
275{ 271{
272 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
276 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 273 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
277 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); 274 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
278 275
279 ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); 276 ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
280 ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; 277 rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
281 278
282 return crypto_ahash_init(&ctx->fallback_req); 279 return crypto_ahash_init(&rctx->fallback_req);
283} 280}
284 281
285static int n2_hash_async_update(struct ahash_request *req) 282static int n2_hash_async_update(struct ahash_request *req)
286{ 283{
284 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
287 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 285 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
288 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); 286 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
289 287
290 ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); 288 ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
291 ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; 289 rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
292 ctx->fallback_req.nbytes = req->nbytes; 290 rctx->fallback_req.nbytes = req->nbytes;
293 ctx->fallback_req.src = req->src; 291 rctx->fallback_req.src = req->src;
294 292
295 return crypto_ahash_update(&ctx->fallback_req); 293 return crypto_ahash_update(&rctx->fallback_req);
296} 294}
297 295
298static int n2_hash_async_final(struct ahash_request *req) 296static int n2_hash_async_final(struct ahash_request *req)
299{ 297{
298 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
300 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 299 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
301 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); 300 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
302 301
303 ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); 302 ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
304 ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; 303 rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
305 ctx->fallback_req.result = req->result; 304 rctx->fallback_req.result = req->result;
306 305
307 return crypto_ahash_final(&ctx->fallback_req); 306 return crypto_ahash_final(&rctx->fallback_req);
308} 307}
309 308
310static int n2_hash_async_finup(struct ahash_request *req) 309static int n2_hash_async_finup(struct ahash_request *req)
311{ 310{
311 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
312 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 312 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
313 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); 313 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
314 314
315 ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); 315 ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
316 ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; 316 rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
317 ctx->fallback_req.nbytes = req->nbytes; 317 rctx->fallback_req.nbytes = req->nbytes;
318 ctx->fallback_req.src = req->src; 318 rctx->fallback_req.src = req->src;
319 ctx->fallback_req.result = req->result; 319 rctx->fallback_req.result = req->result;
320 320
321 return crypto_ahash_finup(&ctx->fallback_req); 321 return crypto_ahash_finup(&rctx->fallback_req);
322} 322}
323 323
324static int n2_hash_cra_init(struct crypto_tfm *tfm) 324static int n2_hash_cra_init(struct crypto_tfm *tfm)
@@ -338,7 +338,10 @@ static int n2_hash_cra_init(struct crypto_tfm *tfm)
338 goto out; 338 goto out;
339 } 339 }
340 340
341 ctx->fallback = fallback_tfm; 341 crypto_ahash_set_reqsize(ahash, (sizeof(struct n2_hash_req_ctx) +
342 crypto_ahash_reqsize(fallback_tfm)));
343
344 ctx->fallback_tfm = fallback_tfm;
342 return 0; 345 return 0;
343 346
344out: 347out:
@@ -350,7 +353,7 @@ static void n2_hash_cra_exit(struct crypto_tfm *tfm)
350 struct crypto_ahash *ahash = __crypto_ahash_cast(tfm); 353 struct crypto_ahash *ahash = __crypto_ahash_cast(tfm);
351 struct n2_hash_ctx *ctx = crypto_ahash_ctx(ahash); 354 struct n2_hash_ctx *ctx = crypto_ahash_ctx(ahash);
352 355
353 crypto_free_ahash(ctx->fallback); 356 crypto_free_ahash(ctx->fallback_tfm);
354} 357}
355 358
356static unsigned long wait_for_tail(struct spu_queue *qp) 359static unsigned long wait_for_tail(struct spu_queue *qp)
@@ -399,14 +402,16 @@ static int n2_hash_async_digest(struct ahash_request *req,
399 * exceed 2^16. 402 * exceed 2^16.
400 */ 403 */
401 if (unlikely(req->nbytes > (1 << 16))) { 404 if (unlikely(req->nbytes > (1 << 16))) {
402 ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); 405 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
403 ctx->fallback_req.base.flags = 406
407 ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
408 rctx->fallback_req.base.flags =
404 req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; 409 req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
405 ctx->fallback_req.nbytes = req->nbytes; 410 rctx->fallback_req.nbytes = req->nbytes;
406 ctx->fallback_req.src = req->src; 411 rctx->fallback_req.src = req->src;
407 ctx->fallback_req.result = req->result; 412 rctx->fallback_req.result = req->result;
408 413
409 return crypto_ahash_digest(&ctx->fallback_req); 414 return crypto_ahash_digest(&rctx->fallback_req);
410 } 415 }
411 416
412 n2_base_ctx_init(&ctx->base); 417 n2_base_ctx_init(&ctx->base);
@@ -472,9 +477,8 @@ out:
472 477
473static int n2_md5_async_digest(struct ahash_request *req) 478static int n2_md5_async_digest(struct ahash_request *req)
474{ 479{
475 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 480 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
476 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); 481 struct md5_state *m = &rctx->u.md5;
477 struct md5_state *m = &ctx->u.md5;
478 482
479 if (unlikely(req->nbytes == 0)) { 483 if (unlikely(req->nbytes == 0)) {
480 static const char md5_zero[MD5_DIGEST_SIZE] = { 484 static const char md5_zero[MD5_DIGEST_SIZE] = {
@@ -497,9 +501,8 @@ static int n2_md5_async_digest(struct ahash_request *req)
497 501
498static int n2_sha1_async_digest(struct ahash_request *req) 502static int n2_sha1_async_digest(struct ahash_request *req)
499{ 503{
500 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 504 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
501 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); 505 struct sha1_state *s = &rctx->u.sha1;
502 struct sha1_state *s = &ctx->u.sha1;
503 506
504 if (unlikely(req->nbytes == 0)) { 507 if (unlikely(req->nbytes == 0)) {
505 static const char sha1_zero[SHA1_DIGEST_SIZE] = { 508 static const char sha1_zero[SHA1_DIGEST_SIZE] = {
@@ -524,9 +527,8 @@ static int n2_sha1_async_digest(struct ahash_request *req)
524 527
525static int n2_sha256_async_digest(struct ahash_request *req) 528static int n2_sha256_async_digest(struct ahash_request *req)
526{ 529{
527 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 530 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
528 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); 531 struct sha256_state *s = &rctx->u.sha256;
529 struct sha256_state *s = &ctx->u.sha256;
530 532
531 if (req->nbytes == 0) { 533 if (req->nbytes == 0) {
532 static const char sha256_zero[SHA256_DIGEST_SIZE] = { 534 static const char sha256_zero[SHA256_DIGEST_SIZE] = {
@@ -555,9 +557,8 @@ static int n2_sha256_async_digest(struct ahash_request *req)
555 557
556static int n2_sha224_async_digest(struct ahash_request *req) 558static int n2_sha224_async_digest(struct ahash_request *req)
557{ 559{
558 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 560 struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
559 struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); 561 struct sha256_state *s = &rctx->u.sha256;
560 struct sha256_state *s = &ctx->u.sha256;
561 562
562 if (req->nbytes == 0) { 563 if (req->nbytes == 0) {
563 static const char sha224_zero[SHA224_DIGEST_SIZE] = { 564 static const char sha224_zero[SHA224_DIGEST_SIZE] = {
@@ -1398,7 +1399,7 @@ static int find_devino_index(struct of_device *dev, struct spu_mdesc_info *ip,
1398 1399
1399 intr = ip->ino_table[i].intr; 1400 intr = ip->ino_table[i].intr;
1400 1401
1401 dev_intrs = of_get_property(dev->node, "interrupts", NULL); 1402 dev_intrs = of_get_property(dev->dev.of_node, "interrupts", NULL);
1402 if (!dev_intrs) 1403 if (!dev_intrs)
1403 return -ENODEV; 1404 return -ENODEV;
1404 1405
@@ -1449,7 +1450,7 @@ static int queue_cache_init(void)
1449{ 1450{
1450 if (!queue_cache[HV_NCS_QTYPE_MAU - 1]) 1451 if (!queue_cache[HV_NCS_QTYPE_MAU - 1])
1451 queue_cache[HV_NCS_QTYPE_MAU - 1] = 1452 queue_cache[HV_NCS_QTYPE_MAU - 1] =
1452 kmem_cache_create("cwq_queue", 1453 kmem_cache_create("mau_queue",
1453 (MAU_NUM_ENTRIES * 1454 (MAU_NUM_ENTRIES *
1454 MAU_ENTRY_SIZE), 1455 MAU_ENTRY_SIZE),
1455 MAU_ENTRY_SIZE, 0, NULL); 1456 MAU_ENTRY_SIZE, 0, NULL);
@@ -1574,7 +1575,7 @@ static int spu_mdesc_walk_arcs(struct mdesc_handle *mdesc,
1574 id = mdesc_get_property(mdesc, tgt, "id", NULL); 1575 id = mdesc_get_property(mdesc, tgt, "id", NULL);
1575 if (table[*id] != NULL) { 1576 if (table[*id] != NULL) {
1576 dev_err(&dev->dev, "%s: SPU cpu slot already set.\n", 1577 dev_err(&dev->dev, "%s: SPU cpu slot already set.\n",
1577 dev->node->full_name); 1578 dev->dev.of_node->full_name);
1578 return -EINVAL; 1579 return -EINVAL;
1579 } 1580 }
1580 cpu_set(*id, p->sharing); 1581 cpu_set(*id, p->sharing);
@@ -1595,7 +1596,7 @@ static int handle_exec_unit(struct spu_mdesc_info *ip, struct list_head *list,
1595 p = kzalloc(sizeof(struct spu_queue), GFP_KERNEL); 1596 p = kzalloc(sizeof(struct spu_queue), GFP_KERNEL);
1596 if (!p) { 1597 if (!p) {
1597 dev_err(&dev->dev, "%s: Could not allocate SPU queue.\n", 1598 dev_err(&dev->dev, "%s: Could not allocate SPU queue.\n",
1598 dev->node->full_name); 1599 dev->dev.of_node->full_name);
1599 return -ENOMEM; 1600 return -ENOMEM;
1600 } 1601 }
1601 1602
@@ -1684,7 +1685,7 @@ static int __devinit grab_mdesc_irq_props(struct mdesc_handle *mdesc,
1684 const unsigned int *reg; 1685 const unsigned int *reg;
1685 u64 node; 1686 u64 node;
1686 1687
1687 reg = of_get_property(dev->node, "reg", NULL); 1688 reg = of_get_property(dev->dev.of_node, "reg", NULL);
1688 if (!reg) 1689 if (!reg)
1689 return -ENODEV; 1690 return -ENODEV;
1690 1691
@@ -1836,7 +1837,7 @@ static int __devinit n2_crypto_probe(struct of_device *dev,
1836 1837
1837 n2_spu_driver_version(); 1838 n2_spu_driver_version();
1838 1839
1839 full_name = dev->node->full_name; 1840 full_name = dev->dev.of_node->full_name;
1840 pr_info("Found N2CP at %s\n", full_name); 1841 pr_info("Found N2CP at %s\n", full_name);
1841 1842
1842 np = alloc_n2cp(); 1843 np = alloc_n2cp();
@@ -1948,7 +1949,7 @@ static int __devinit n2_mau_probe(struct of_device *dev,
1948 1949
1949 n2_spu_driver_version(); 1950 n2_spu_driver_version();
1950 1951
1951 full_name = dev->node->full_name; 1952 full_name = dev->dev.of_node->full_name;
1952 pr_info("Found NCP at %s\n", full_name); 1953 pr_info("Found NCP at %s\n", full_name);
1953 1954
1954 mp = alloc_ncp(); 1955 mp = alloc_ncp();
@@ -2034,8 +2035,11 @@ static struct of_device_id n2_crypto_match[] = {
2034MODULE_DEVICE_TABLE(of, n2_crypto_match); 2035MODULE_DEVICE_TABLE(of, n2_crypto_match);
2035 2036
2036static struct of_platform_driver n2_crypto_driver = { 2037static struct of_platform_driver n2_crypto_driver = {
2037 .name = "n2cp", 2038 .driver = {
2038 .match_table = n2_crypto_match, 2039 .name = "n2cp",
2040 .owner = THIS_MODULE,
2041 .of_match_table = n2_crypto_match,
2042 },
2039 .probe = n2_crypto_probe, 2043 .probe = n2_crypto_probe,
2040 .remove = __devexit_p(n2_crypto_remove), 2044 .remove = __devexit_p(n2_crypto_remove),
2041}; 2045};
@@ -2055,8 +2059,11 @@ static struct of_device_id n2_mau_match[] = {
2055MODULE_DEVICE_TABLE(of, n2_mau_match); 2059MODULE_DEVICE_TABLE(of, n2_mau_match);
2056 2060
2057static struct of_platform_driver n2_mau_driver = { 2061static struct of_platform_driver n2_mau_driver = {
2058 .name = "ncp", 2062 .driver = {
2059 .match_table = n2_mau_match, 2063 .name = "ncp",
2064 .owner = THIS_MODULE,
2065 .of_match_table = n2_mau_match,
2066 },
2060 .probe = n2_mau_probe, 2067 .probe = n2_mau_probe,
2061 .remove = __devexit_p(n2_mau_remove), 2068 .remove = __devexit_p(n2_mau_remove),
2062}; 2069};
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 201e6e19c344..14a8c0f1698e 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -630,7 +630,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
630static int __devinit mpc_dma_probe(struct of_device *op, 630static int __devinit mpc_dma_probe(struct of_device *op,
631 const struct of_device_id *match) 631 const struct of_device_id *match)
632{ 632{
633 struct device_node *dn = op->node; 633 struct device_node *dn = op->dev.of_node;
634 struct device *dev = &op->dev; 634 struct device *dev = &op->dev;
635 struct dma_device *dma; 635 struct dma_device *dma;
636 struct mpc_dma *mdma; 636 struct mpc_dma *mdma;
@@ -771,12 +771,12 @@ static struct of_device_id mpc_dma_match[] = {
771}; 771};
772 772
773static struct of_platform_driver mpc_dma_driver = { 773static struct of_platform_driver mpc_dma_driver = {
774 .match_table = mpc_dma_match,
775 .probe = mpc_dma_probe, 774 .probe = mpc_dma_probe,
776 .remove = __devexit_p(mpc_dma_remove), 775 .remove = __devexit_p(mpc_dma_remove),
777 .driver = { 776 .driver = {
778 .name = DRV_NAME, 777 .name = DRV_NAME,
779 .owner = THIS_MODULE, 778 .owner = THIS_MODULE,
779 .of_match_table = mpc_dma_match,
780 }, 780 },
781}; 781};
782 782
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index fa98abe4686f..5a22ca6927e5 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -4394,7 +4394,7 @@ static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev,
4394static int __devinit ppc440spe_adma_probe(struct of_device *ofdev, 4394static int __devinit ppc440spe_adma_probe(struct of_device *ofdev,
4395 const struct of_device_id *match) 4395 const struct of_device_id *match)
4396{ 4396{
4397 struct device_node *np = ofdev->node; 4397 struct device_node *np = ofdev->dev.of_node;
4398 struct resource res; 4398 struct resource res;
4399 struct ppc440spe_adma_device *adev; 4399 struct ppc440spe_adma_device *adev;
4400 struct ppc440spe_adma_chan *chan; 4400 struct ppc440spe_adma_chan *chan;
@@ -4626,7 +4626,7 @@ out:
4626static int __devexit ppc440spe_adma_remove(struct of_device *ofdev) 4626static int __devexit ppc440spe_adma_remove(struct of_device *ofdev)
4627{ 4627{
4628 struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev); 4628 struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev);
4629 struct device_node *np = ofdev->node; 4629 struct device_node *np = ofdev->dev.of_node;
4630 struct resource res; 4630 struct resource res;
4631 struct dma_chan *chan, *_chan; 4631 struct dma_chan *chan, *_chan;
4632 struct ppc_dma_chan_ref *ref, *_ref; 4632 struct ppc_dma_chan_ref *ref, *_ref;
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 55c9c59b3f71..aedef7941b22 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -69,6 +69,9 @@ config EDAC_MM_EDAC
69 occurred so that a particular failing memory module can be 69 occurred so that a particular failing memory module can be
70 replaced. If unsure, select 'Y'. 70 replaced. If unsure, select 'Y'.
71 71
72config EDAC_MCE
73 bool
74
72config EDAC_AMD64 75config EDAC_AMD64
73 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h" 76 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
74 depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE 77 depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
@@ -166,6 +169,16 @@ config EDAC_I5400
166 Support for error detection and correction the Intel 169 Support for error detection and correction the Intel
167 i5400 MCH chipset (Seaburg). 170 i5400 MCH chipset (Seaburg).
168 171
172config EDAC_I7CORE
173 tristate "Intel i7 Core (Nehalem) processors"
174 depends on EDAC_MM_EDAC && PCI && X86
175 select EDAC_MCE
176 help
177 Support for error detection and correction the Intel
178 i7 Core (Nehalem) Integrated Memory Controller that exists on
179 newer processors like i7 Core, i7 Core Extreme, Xeon 35xx
180 and Xeon 55xx processors.
181
169config EDAC_I82860 182config EDAC_I82860
170 tristate "Intel 82860" 183 tristate "Intel 82860"
171 depends on EDAC_MM_EDAC && PCI && X86_32 184 depends on EDAC_MM_EDAC && PCI && X86_32
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index bc5dc232a0fb..ca6b1bb24ccc 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -8,6 +8,7 @@
8 8
9obj-$(CONFIG_EDAC) := edac_stub.o 9obj-$(CONFIG_EDAC) := edac_stub.o
10obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o 10obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
11obj-$(CONFIG_EDAC_MCE) += edac_mce.o
11 12
12edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o 13edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
13edac_core-objs += edac_module.o edac_device_sysfs.o 14edac_core-objs += edac_module.o edac_device_sysfs.o
@@ -23,6 +24,7 @@ obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o
23obj-$(CONFIG_EDAC_I5000) += i5000_edac.o 24obj-$(CONFIG_EDAC_I5000) += i5000_edac.o
24obj-$(CONFIG_EDAC_I5100) += i5100_edac.o 25obj-$(CONFIG_EDAC_I5100) += i5100_edac.o
25obj-$(CONFIG_EDAC_I5400) += i5400_edac.o 26obj-$(CONFIG_EDAC_I5400) += i5400_edac.o
27obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o
26obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o 28obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o
27obj-$(CONFIG_EDAC_E752X) += e752x_edac.o 29obj-$(CONFIG_EDAC_E752X) += e752x_edac.o
28obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o 30obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 001b2e797fb3..efca9343d26a 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -341,12 +341,30 @@ struct csrow_info {
341 struct channel_info *channels; 341 struct channel_info *channels;
342}; 342};
343 343
344struct mcidev_sysfs_group {
345 const char *name; /* group name */
346 struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */
347};
348
349struct mcidev_sysfs_group_kobj {
350 struct list_head list; /* list for all instances within a mc */
351
352 struct kobject kobj; /* kobj for the group */
353
354 struct mcidev_sysfs_group *grp; /* group description table */
355 struct mem_ctl_info *mci; /* the parent */
356};
357
344/* mcidev_sysfs_attribute structure 358/* mcidev_sysfs_attribute structure
345 * used for driver sysfs attributes and in mem_ctl_info 359 * used for driver sysfs attributes and in mem_ctl_info
346 * sysfs top level entries 360 * sysfs top level entries
347 */ 361 */
348struct mcidev_sysfs_attribute { 362struct mcidev_sysfs_attribute {
349 struct attribute attr; 363 /* It should use either attr or grp */
364 struct attribute attr;
365 struct mcidev_sysfs_group *grp; /* Points to a group of attributes */
366
367 /* Ops for show/store values at the attribute - not used on group */
350 ssize_t (*show)(struct mem_ctl_info *,char *); 368 ssize_t (*show)(struct mem_ctl_info *,char *);
351 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); 369 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
352}; 370};
@@ -424,6 +442,9 @@ struct mem_ctl_info {
424 /* edac sysfs device control */ 442 /* edac sysfs device control */
425 struct kobject edac_mci_kobj; 443 struct kobject edac_mci_kobj;
426 444
445 /* list for all grp instances within a mc */
446 struct list_head grp_kobj_list;
447
427 /* Additional top controller level attributes, but specified 448 /* Additional top controller level attributes, but specified
428 * by the low level driver. 449 * by the low level driver.
429 * 450 *
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 418b65f1a1da..c200c2fd43ea 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -557,6 +557,8 @@ static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr,
557 struct mem_ctl_info *mem_ctl_info = to_mci(kobj); 557 struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
558 struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); 558 struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
559 559
560 debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info);
561
560 if (mcidev_attr->show) 562 if (mcidev_attr->show)
561 return mcidev_attr->show(mem_ctl_info, buffer); 563 return mcidev_attr->show(mem_ctl_info, buffer);
562 564
@@ -569,6 +571,8 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
569 struct mem_ctl_info *mem_ctl_info = to_mci(kobj); 571 struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
570 struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); 572 struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
571 573
574 debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info);
575
572 if (mcidev_attr->store) 576 if (mcidev_attr->store)
573 return mcidev_attr->store(mem_ctl_info, buffer, count); 577 return mcidev_attr->store(mem_ctl_info, buffer, count);
574 578
@@ -726,28 +730,118 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
726 730
727#define EDAC_DEVICE_SYMLINK "device" 731#define EDAC_DEVICE_SYMLINK "device"
728 732
733#define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group_kobj, kobj)->mci)
734
735/* MCI show/store functions for top most object */
736static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr,
737 char *buffer)
738{
739 struct mem_ctl_info *mem_ctl_info = grp_to_mci(kobj);
740 struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
741
742 debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info);
743
744 if (mcidev_attr->show)
745 return mcidev_attr->show(mem_ctl_info, buffer);
746
747 return -EIO;
748}
749
750static ssize_t inst_grp_store(struct kobject *kobj, struct attribute *attr,
751 const char *buffer, size_t count)
752{
753 struct mem_ctl_info *mem_ctl_info = grp_to_mci(kobj);
754 struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
755
756 debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info);
757
758 if (mcidev_attr->store)
759 return mcidev_attr->store(mem_ctl_info, buffer, count);
760
761 return -EIO;
762}
763
764/* No memory to release for this kobj */
765static void edac_inst_grp_release(struct kobject *kobj)
766{
767 struct mcidev_sysfs_group_kobj *grp;
768 struct mem_ctl_info *mci;
769
770 debugf1("%s()\n", __func__);
771
772 grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj);
773 mci = grp->mci;
774
775 kobject_put(&mci->edac_mci_kobj);
776}
777
778/* Intermediate show/store table */
779static struct sysfs_ops inst_grp_ops = {
780 .show = inst_grp_show,
781 .store = inst_grp_store
782};
783
784/* the kobj_type instance for a instance group */
785static struct kobj_type ktype_inst_grp = {
786 .release = edac_inst_grp_release,
787 .sysfs_ops = &inst_grp_ops,
788};
789
790
729/* 791/*
730 * edac_create_mci_instance_attributes 792 * edac_create_mci_instance_attributes
731 * create MC driver specific attributes at the topmost level 793 * create MC driver specific attributes bellow an specified kobj
732 * directory of this mci instance. 794 * This routine calls itself recursively, in order to create an entire
795 * object tree.
733 */ 796 */
734static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci) 797static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
798 struct mcidev_sysfs_attribute *sysfs_attrib,
799 struct kobject *kobj)
735{ 800{
736 int err; 801 int err;
737 struct mcidev_sysfs_attribute *sysfs_attrib;
738 802
739 /* point to the start of the array and iterate over it 803 debugf1("%s()\n", __func__);
740 * adding each attribute listed to this mci instance's kobject 804
741 */ 805 while (sysfs_attrib) {
742 sysfs_attrib = mci->mc_driver_sysfs_attributes; 806 if (sysfs_attrib->grp) {
807 struct mcidev_sysfs_group_kobj *grp_kobj;
808
809 grp_kobj = kzalloc(sizeof(*grp_kobj), GFP_KERNEL);
810 if (!grp_kobj)
811 return -ENOMEM;
812
813 list_add_tail(&grp_kobj->list, &mci->grp_kobj_list);
814
815 grp_kobj->grp = sysfs_attrib->grp;
816 grp_kobj->mci = mci;
817
818 debugf0("%s() grp %s, mci %p\n", __func__,
819 sysfs_attrib->grp->name, mci);
820
821 err = kobject_init_and_add(&grp_kobj->kobj,
822 &ktype_inst_grp,
823 &mci->edac_mci_kobj,
824 sysfs_attrib->grp->name);
825 if (err)
826 return err;
827
828 err = edac_create_mci_instance_attributes(mci,
829 grp_kobj->grp->mcidev_attr,
830 &grp_kobj->kobj);
831
832 if (err)
833 return err;
834 } else if (sysfs_attrib->attr.name) {
835 debugf0("%s() file %s\n", __func__,
836 sysfs_attrib->attr.name);
837
838 err = sysfs_create_file(kobj, &sysfs_attrib->attr);
839 } else
840 break;
743 841
744 while (sysfs_attrib && sysfs_attrib->attr.name) {
745 err = sysfs_create_file(&mci->edac_mci_kobj,
746 (struct attribute*) sysfs_attrib);
747 if (err) { 842 if (err) {
748 return err; 843 return err;
749 } 844 }
750
751 sysfs_attrib++; 845 sysfs_attrib++;
752 } 846 }
753 847
@@ -759,21 +853,44 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci)
759 * remove MC driver specific attributes at the topmost level 853 * remove MC driver specific attributes at the topmost level
760 * directory of this mci instance. 854 * directory of this mci instance.
761 */ 855 */
762static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci) 856static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci,
857 struct mcidev_sysfs_attribute *sysfs_attrib,
858 struct kobject *kobj, int count)
763{ 859{
764 struct mcidev_sysfs_attribute *sysfs_attrib; 860 struct mcidev_sysfs_group_kobj *grp_kobj, *tmp;
765 861
766 /* point to the start of the array and iterate over it 862 debugf1("%s()\n", __func__);
767 * adding each attribute listed to this mci instance's kobject
768 */
769 sysfs_attrib = mci->mc_driver_sysfs_attributes;
770 863
771 /* loop if there are attributes and until we hit a NULL entry */ 864 /*
772 while (sysfs_attrib && sysfs_attrib->attr.name) { 865 * loop if there are attributes and until we hit a NULL entry
773 sysfs_remove_file(&mci->edac_mci_kobj, 866 * Remove first all the atributes
774 (struct attribute *) sysfs_attrib); 867 */
868 while (sysfs_attrib) {
869 if (sysfs_attrib->grp) {
870 list_for_each_entry(grp_kobj, &mci->grp_kobj_list,
871 list)
872 if (grp_kobj->grp == sysfs_attrib->grp)
873 edac_remove_mci_instance_attributes(mci,
874 grp_kobj->grp->mcidev_attr,
875 &grp_kobj->kobj, count + 1);
876 } else if (sysfs_attrib->attr.name) {
877 debugf0("%s() file %s\n", __func__,
878 sysfs_attrib->attr.name);
879 sysfs_remove_file(kobj, &sysfs_attrib->attr);
880 } else
881 break;
775 sysfs_attrib++; 882 sysfs_attrib++;
776 } 883 }
884
885 /*
886 * Now that all attributes got removed, it is save to remove all groups
887 */
888 if (!count)
889 list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list,
890 list) {
891 debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name);
892 kobject_put(&grp_kobj->kobj);
893 }
777} 894}
778 895
779 896
@@ -794,6 +911,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
794 911
795 debugf0("%s() idx=%d\n", __func__, mci->mc_idx); 912 debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
796 913
914 INIT_LIST_HEAD(&mci->grp_kobj_list);
915
797 /* create a symlink for the device */ 916 /* create a symlink for the device */
798 err = sysfs_create_link(kobj_mci, &mci->dev->kobj, 917 err = sysfs_create_link(kobj_mci, &mci->dev->kobj,
799 EDAC_DEVICE_SYMLINK); 918 EDAC_DEVICE_SYMLINK);
@@ -806,7 +925,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
806 * then create them now for the driver. 925 * then create them now for the driver.
807 */ 926 */
808 if (mci->mc_driver_sysfs_attributes) { 927 if (mci->mc_driver_sysfs_attributes) {
809 err = edac_create_mci_instance_attributes(mci); 928 err = edac_create_mci_instance_attributes(mci,
929 mci->mc_driver_sysfs_attributes,
930 &mci->edac_mci_kobj);
810 if (err) { 931 if (err) {
811 debugf1("%s() failure to create mci attributes\n", 932 debugf1("%s() failure to create mci attributes\n",
812 __func__); 933 __func__);
@@ -841,7 +962,8 @@ fail1:
841 } 962 }
842 963
843 /* remove the mci instance's attributes, if any */ 964 /* remove the mci instance's attributes, if any */
844 edac_remove_mci_instance_attributes(mci); 965 edac_remove_mci_instance_attributes(mci,
966 mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj, 0);
845 967
846 /* remove the symlink */ 968 /* remove the symlink */
847 sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK); 969 sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK);
@@ -875,8 +997,9 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
875 debugf0("%s() remove_mci_instance\n", __func__); 997 debugf0("%s() remove_mci_instance\n", __func__);
876 998
877 /* remove this mci instance's attribtes */ 999 /* remove this mci instance's attribtes */
878 edac_remove_mci_instance_attributes(mci); 1000 edac_remove_mci_instance_attributes(mci,
879 1001 mci->mc_driver_sysfs_attributes,
1002 &mci->edac_mci_kobj, 0);
880 debugf0("%s() unregister this mci kobj\n", __func__); 1003 debugf0("%s() unregister this mci kobj\n", __func__);
881 1004
882 /* unregister this instance's kobject */ 1005 /* unregister this instance's kobject */
diff --git a/drivers/edac/edac_mce.c b/drivers/edac/edac_mce.c
new file mode 100644
index 000000000000..9ccdc5b140e7
--- /dev/null
+++ b/drivers/edac/edac_mce.c
@@ -0,0 +1,61 @@
1/* Provides edac interface to mcelog events
2 *
3 * This file may be distributed under the terms of the
4 * GNU General Public License version 2.
5 *
6 * Copyright (c) 2009 by:
7 * Mauro Carvalho Chehab <mchehab@redhat.com>
8 *
9 * Red Hat Inc. http://www.redhat.com
10 */
11
12#include <linux/module.h>
13#include <linux/edac_mce.h>
14#include <asm/mce.h>
15
16int edac_mce_enabled;
17EXPORT_SYMBOL_GPL(edac_mce_enabled);
18
19
20/*
21 * Extension interface
22 */
23
24static LIST_HEAD(edac_mce_list);
25static DEFINE_MUTEX(edac_mce_lock);
26
27int edac_mce_register(struct edac_mce *edac_mce)
28{
29 mutex_lock(&edac_mce_lock);
30 list_add_tail(&edac_mce->list, &edac_mce_list);
31 mutex_unlock(&edac_mce_lock);
32 return 0;
33}
34EXPORT_SYMBOL(edac_mce_register);
35
36void edac_mce_unregister(struct edac_mce *edac_mce)
37{
38 mutex_lock(&edac_mce_lock);
39 list_del(&edac_mce->list);
40 mutex_unlock(&edac_mce_lock);
41}
42EXPORT_SYMBOL(edac_mce_unregister);
43
44int edac_mce_parse(struct mce *mce)
45{
46 struct edac_mce *edac_mce;
47
48 list_for_each_entry(edac_mce, &edac_mce_list, list) {
49 if (edac_mce->check_error(edac_mce->priv, mce))
50 return 1;
51 }
52
53 /* Nobody queued the error */
54 return 0;
55}
56EXPORT_SYMBOL_GPL(edac_mce_parse);
57
58MODULE_LICENSE("GPL");
59MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
60MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
61MODULE_DESCRIPTION("EDAC Driver for mcelog captured errors");
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
new file mode 100644
index 000000000000..6b8b7b41ec5f
--- /dev/null
+++ b/drivers/edac/i7core_edac.c
@@ -0,0 +1,2078 @@
1/* Intel i7 core/Nehalem Memory Controller kernel module
2 *
3 * This driver supports yhe memory controllers found on the Intel
4 * processor families i7core, i7core 7xx/8xx, i5core, Xeon 35xx,
5 * Xeon 55xx and Xeon 56xx also known as Nehalem, Nehalem-EP, Lynnfield
6 * and Westmere-EP.
7 *
8 * This file may be distributed under the terms of the
9 * GNU General Public License version 2 only.
10 *
11 * Copyright (c) 2009-2010 by:
12 * Mauro Carvalho Chehab <mchehab@redhat.com>
13 *
14 * Red Hat Inc. http://www.redhat.com
15 *
16 * Forked and adapted from the i5400_edac driver
17 *
18 * Based on the following public Intel datasheets:
19 * Intel Core i7 Processor Extreme Edition and Intel Core i7 Processor
20 * Datasheet, Volume 2:
21 * http://download.intel.com/design/processor/datashts/320835.pdf
22 * Intel Xeon Processor 5500 Series Datasheet Volume 2
23 * http://www.intel.com/Assets/PDF/datasheet/321322.pdf
24 * also available at:
25 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
26 */
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/pci.h>
31#include <linux/pci_ids.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34#include <linux/edac.h>
35#include <linux/mmzone.h>
36#include <linux/edac_mce.h>
37#include <linux/smp.h>
38#include <asm/processor.h>
39
40#include "edac_core.h"
41
42/*
43 * This is used for Nehalem-EP and Nehalem-EX devices, where the non-core
44 * registers start at bus 255, and are not reported by BIOS.
45 * We currently find devices with only 2 sockets. In order to support more QPI
46 * Quick Path Interconnect, just increment this number.
47 */
48#define MAX_SOCKET_BUSES 2
49
50
51/*
52 * Alter this version for the module when modifications are made
53 */
54#define I7CORE_REVISION " Ver: 1.0.0 " __DATE__
55#define EDAC_MOD_STR "i7core_edac"
56
57/*
58 * Debug macros
59 */
60#define i7core_printk(level, fmt, arg...) \
61 edac_printk(level, "i7core", fmt, ##arg)
62
63#define i7core_mc_printk(mci, level, fmt, arg...) \
64 edac_mc_chipset_printk(mci, level, "i7core", fmt, ##arg)
65
66/*
67 * i7core Memory Controller Registers
68 */
69
70 /* OFFSETS for Device 0 Function 0 */
71
72#define MC_CFG_CONTROL 0x90
73
74 /* OFFSETS for Device 3 Function 0 */
75
76#define MC_CONTROL 0x48
77#define MC_STATUS 0x4c
78#define MC_MAX_DOD 0x64
79
80/*
81 * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet:
82 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
83 */
84
85#define MC_TEST_ERR_RCV1 0x60
86 #define DIMM2_COR_ERR(r) ((r) & 0x7fff)
87
88#define MC_TEST_ERR_RCV0 0x64
89 #define DIMM1_COR_ERR(r) (((r) >> 16) & 0x7fff)
90 #define DIMM0_COR_ERR(r) ((r) & 0x7fff)
91
92/* OFFSETS for Device 3 Function 2, as inicated on Xeon 5500 datasheet */
93#define MC_COR_ECC_CNT_0 0x80
94#define MC_COR_ECC_CNT_1 0x84
95#define MC_COR_ECC_CNT_2 0x88
96#define MC_COR_ECC_CNT_3 0x8c
97#define MC_COR_ECC_CNT_4 0x90
98#define MC_COR_ECC_CNT_5 0x94
99
100#define DIMM_TOP_COR_ERR(r) (((r) >> 16) & 0x7fff)
101#define DIMM_BOT_COR_ERR(r) ((r) & 0x7fff)
102
103
104 /* OFFSETS for Devices 4,5 and 6 Function 0 */
105
106#define MC_CHANNEL_DIMM_INIT_PARAMS 0x58
107 #define THREE_DIMMS_PRESENT (1 << 24)
108 #define SINGLE_QUAD_RANK_PRESENT (1 << 23)
109 #define QUAD_RANK_PRESENT (1 << 22)
110 #define REGISTERED_DIMM (1 << 15)
111
112#define MC_CHANNEL_MAPPER 0x60
113 #define RDLCH(r, ch) ((((r) >> (3 + (ch * 6))) & 0x07) - 1)
114 #define WRLCH(r, ch) ((((r) >> (ch * 6)) & 0x07) - 1)
115
116#define MC_CHANNEL_RANK_PRESENT 0x7c
117 #define RANK_PRESENT_MASK 0xffff
118
119#define MC_CHANNEL_ADDR_MATCH 0xf0
120#define MC_CHANNEL_ERROR_MASK 0xf8
121#define MC_CHANNEL_ERROR_INJECT 0xfc
122 #define INJECT_ADDR_PARITY 0x10
123 #define INJECT_ECC 0x08
124 #define MASK_CACHELINE 0x06
125 #define MASK_FULL_CACHELINE 0x06
126 #define MASK_MSB32_CACHELINE 0x04
127 #define MASK_LSB32_CACHELINE 0x02
128 #define NO_MASK_CACHELINE 0x00
129 #define REPEAT_EN 0x01
130
131 /* OFFSETS for Devices 4,5 and 6 Function 1 */
132
133#define MC_DOD_CH_DIMM0 0x48
134#define MC_DOD_CH_DIMM1 0x4c
135#define MC_DOD_CH_DIMM2 0x50
136 #define RANKOFFSET_MASK ((1 << 12) | (1 << 11) | (1 << 10))
137 #define RANKOFFSET(x) ((x & RANKOFFSET_MASK) >> 10)
138 #define DIMM_PRESENT_MASK (1 << 9)
139 #define DIMM_PRESENT(x) (((x) & DIMM_PRESENT_MASK) >> 9)
140 #define MC_DOD_NUMBANK_MASK ((1 << 8) | (1 << 7))
141 #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7)
142 #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5))
143 #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5)
144 #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3) | (1 << 2))
145 #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2)
146 #define MC_DOD_NUMCOL_MASK 3
147 #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK)
148
149#define MC_RANK_PRESENT 0x7c
150
151#define MC_SAG_CH_0 0x80
152#define MC_SAG_CH_1 0x84
153#define MC_SAG_CH_2 0x88
154#define MC_SAG_CH_3 0x8c
155#define MC_SAG_CH_4 0x90
156#define MC_SAG_CH_5 0x94
157#define MC_SAG_CH_6 0x98
158#define MC_SAG_CH_7 0x9c
159
160#define MC_RIR_LIMIT_CH_0 0x40
161#define MC_RIR_LIMIT_CH_1 0x44
162#define MC_RIR_LIMIT_CH_2 0x48
163#define MC_RIR_LIMIT_CH_3 0x4C
164#define MC_RIR_LIMIT_CH_4 0x50
165#define MC_RIR_LIMIT_CH_5 0x54
166#define MC_RIR_LIMIT_CH_6 0x58
167#define MC_RIR_LIMIT_CH_7 0x5C
168#define MC_RIR_LIMIT_MASK ((1 << 10) - 1)
169
170#define MC_RIR_WAY_CH 0x80
171 #define MC_RIR_WAY_OFFSET_MASK (((1 << 14) - 1) & ~0x7)
172 #define MC_RIR_WAY_RANK_MASK 0x7
173
174/*
175 * i7core structs
176 */
177
178#define NUM_CHANS 3
179#define MAX_DIMMS 3 /* Max DIMMS per channel */
180#define MAX_MCR_FUNC 4
181#define MAX_CHAN_FUNC 3
182
183struct i7core_info {
184 u32 mc_control;
185 u32 mc_status;
186 u32 max_dod;
187 u32 ch_map;
188};
189
190
191struct i7core_inject {
192 int enable;
193
194 u32 section;
195 u32 type;
196 u32 eccmask;
197
198 /* Error address mask */
199 int channel, dimm, rank, bank, page, col;
200};
201
202struct i7core_channel {
203 u32 ranks;
204 u32 dimms;
205};
206
207struct pci_id_descr {
208 int dev;
209 int func;
210 int dev_id;
211 int optional;
212};
213
214struct pci_id_table {
215 struct pci_id_descr *descr;
216 int n_devs;
217};
218
219struct i7core_dev {
220 struct list_head list;
221 u8 socket;
222 struct pci_dev **pdev;
223 int n_devs;
224 struct mem_ctl_info *mci;
225};
226
227struct i7core_pvt {
228 struct pci_dev *pci_noncore;
229 struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1];
230 struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1];
231
232 struct i7core_dev *i7core_dev;
233
234 struct i7core_info info;
235 struct i7core_inject inject;
236 struct i7core_channel channel[NUM_CHANS];
237
238 int channels; /* Number of active channels */
239
240 int ce_count_available;
241 int csrow_map[NUM_CHANS][MAX_DIMMS];
242
243 /* ECC corrected errors counts per udimm */
244 unsigned long udimm_ce_count[MAX_DIMMS];
245 int udimm_last_ce_count[MAX_DIMMS];
246 /* ECC corrected errors counts per rdimm */
247 unsigned long rdimm_ce_count[NUM_CHANS][MAX_DIMMS];
248 int rdimm_last_ce_count[NUM_CHANS][MAX_DIMMS];
249
250 unsigned int is_registered;
251
252 /* mcelog glue */
253 struct edac_mce edac_mce;
254
255 /* Fifo double buffers */
256 struct mce mce_entry[MCE_LOG_LEN];
257 struct mce mce_outentry[MCE_LOG_LEN];
258
259 /* Fifo in/out counters */
260 unsigned mce_in, mce_out;
261
262 /* Count indicator to show errors not got */
263 unsigned mce_overrun;
264};
265
266/* Static vars */
267static LIST_HEAD(i7core_edac_list);
268static DEFINE_MUTEX(i7core_edac_lock);
269
270#define PCI_DESCR(device, function, device_id) \
271 .dev = (device), \
272 .func = (function), \
273 .dev_id = (device_id)
274
275struct pci_id_descr pci_dev_descr_i7core_nehalem[] = {
276 /* Memory controller */
277 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) },
278 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) },
279 /* Exists only for RDIMM */
280 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS), .optional = 1 },
281 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) },
282
283 /* Channel 0 */
284 { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) },
285 { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) },
286 { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK) },
287 { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC) },
288
289 /* Channel 1 */
290 { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL) },
291 { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR) },
292 { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK) },
293 { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC) },
294
295 /* Channel 2 */
296 { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL) },
297 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) },
298 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) },
299 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC) },
300
301 /* Generic Non-core registers */
302 /*
303 * This is the PCI device on i7core and on Xeon 35xx (8086:2c41)
304 * On Xeon 55xx, however, it has a different id (8086:2c40). So,
305 * the probing code needs to test for the other address in case of
306 * failure of this one
307 */
308 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NONCORE) },
309
310};
311
312struct pci_id_descr pci_dev_descr_lynnfield[] = {
313 { PCI_DESCR( 3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR) },
314 { PCI_DESCR( 3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD) },
315 { PCI_DESCR( 3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST) },
316
317 { PCI_DESCR( 4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL) },
318 { PCI_DESCR( 4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR) },
319 { PCI_DESCR( 4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK) },
320 { PCI_DESCR( 4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC) },
321
322 { PCI_DESCR( 5, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL) },
323 { PCI_DESCR( 5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR) },
324 { PCI_DESCR( 5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) },
325 { PCI_DESCR( 5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC) },
326
327 /*
328 * This is the PCI device has an alternate address on some
329 * processors like Core i7 860
330 */
331 { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) },
332};
333
334struct pci_id_descr pci_dev_descr_i7core_westmere[] = {
335 /* Memory controller */
336 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2) },
337 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2) },
338 /* Exists only for RDIMM */
339 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2), .optional = 1 },
340 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2) },
341
342 /* Channel 0 */
343 { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2) },
344 { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2) },
345 { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2) },
346 { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2) },
347
348 /* Channel 1 */
349 { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2) },
350 { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2) },
351 { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2) },
352 { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2) },
353
354 /* Channel 2 */
355 { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2) },
356 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2) },
357 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2) },
358 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2) },
359
360 /* Generic Non-core registers */
361 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2) },
362
363};
364
365#define PCI_ID_TABLE_ENTRY(A) { A, ARRAY_SIZE(A) }
366struct pci_id_table pci_dev_table[] = {
367 PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem),
368 PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield),
369 PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere),
370};
371
372/*
373 * pci_device_id table for which devices we are looking for
374 */
375static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
376 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)},
377 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0)},
378 {0,} /* 0 terminated list. */
379};
380
381static struct edac_pci_ctl_info *i7core_pci;
382
383/****************************************************************************
384 Anciliary status routines
385 ****************************************************************************/
386
387 /* MC_CONTROL bits */
388#define CH_ACTIVE(pvt, ch) ((pvt)->info.mc_control & (1 << (8 + ch)))
389#define ECCx8(pvt) ((pvt)->info.mc_control & (1 << 1))
390
391 /* MC_STATUS bits */
392#define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 4))
393#define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch))
394
395 /* MC_MAX_DOD read functions */
396static inline int numdimms(u32 dimms)
397{
398 return (dimms & 0x3) + 1;
399}
400
401static inline int numrank(u32 rank)
402{
403 static int ranks[4] = { 1, 2, 4, -EINVAL };
404
405 return ranks[rank & 0x3];
406}
407
408static inline int numbank(u32 bank)
409{
410 static int banks[4] = { 4, 8, 16, -EINVAL };
411
412 return banks[bank & 0x3];
413}
414
415static inline int numrow(u32 row)
416{
417 static int rows[8] = {
418 1 << 12, 1 << 13, 1 << 14, 1 << 15,
419 1 << 16, -EINVAL, -EINVAL, -EINVAL,
420 };
421
422 return rows[row & 0x7];
423}
424
425static inline int numcol(u32 col)
426{
427 static int cols[8] = {
428 1 << 10, 1 << 11, 1 << 12, -EINVAL,
429 };
430 return cols[col & 0x3];
431}
432
433static struct i7core_dev *get_i7core_dev(u8 socket)
434{
435 struct i7core_dev *i7core_dev;
436
437 list_for_each_entry(i7core_dev, &i7core_edac_list, list) {
438 if (i7core_dev->socket == socket)
439 return i7core_dev;
440 }
441
442 return NULL;
443}
444
445/****************************************************************************
446 Memory check routines
447 ****************************************************************************/
448static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot,
449 unsigned func)
450{
451 struct i7core_dev *i7core_dev = get_i7core_dev(socket);
452 int i;
453
454 if (!i7core_dev)
455 return NULL;
456
457 for (i = 0; i < i7core_dev->n_devs; i++) {
458 if (!i7core_dev->pdev[i])
459 continue;
460
461 if (PCI_SLOT(i7core_dev->pdev[i]->devfn) == slot &&
462 PCI_FUNC(i7core_dev->pdev[i]->devfn) == func) {
463 return i7core_dev->pdev[i];
464 }
465 }
466
467 return NULL;
468}
469
470/**
471 * i7core_get_active_channels() - gets the number of channels and csrows
472 * @socket: Quick Path Interconnect socket
473 * @channels: Number of channels that will be returned
474 * @csrows: Number of csrows found
475 *
476 * Since EDAC core needs to know in advance the number of available channels
477 * and csrows, in order to allocate memory for csrows/channels, it is needed
478 * to run two similar steps. At the first step, implemented on this function,
479 * it checks the number of csrows/channels present at one socket.
480 * this is used in order to properly allocate the size of mci components.
481 *
482 * It should be noticed that none of the current available datasheets explain
483 * or even mention how csrows are seen by the memory controller. So, we need
484 * to add a fake description for csrows.
485 * So, this driver is attributing one DIMM memory for one csrow.
486 */
487static int i7core_get_active_channels(u8 socket, unsigned *channels,
488 unsigned *csrows)
489{
490 struct pci_dev *pdev = NULL;
491 int i, j;
492 u32 status, control;
493
494 *channels = 0;
495 *csrows = 0;
496
497 pdev = get_pdev_slot_func(socket, 3, 0);
498 if (!pdev) {
499 i7core_printk(KERN_ERR, "Couldn't find socket %d fn 3.0!!!\n",
500 socket);
501 return -ENODEV;
502 }
503
504 /* Device 3 function 0 reads */
505 pci_read_config_dword(pdev, MC_STATUS, &status);
506 pci_read_config_dword(pdev, MC_CONTROL, &control);
507
508 for (i = 0; i < NUM_CHANS; i++) {
509 u32 dimm_dod[3];
510 /* Check if the channel is active */
511 if (!(control & (1 << (8 + i))))
512 continue;
513
514 /* Check if the channel is disabled */
515 if (status & (1 << i))
516 continue;
517
518 pdev = get_pdev_slot_func(socket, i + 4, 1);
519 if (!pdev) {
520 i7core_printk(KERN_ERR, "Couldn't find socket %d "
521 "fn %d.%d!!!\n",
522 socket, i + 4, 1);
523 return -ENODEV;
524 }
525 /* Devices 4-6 function 1 */
526 pci_read_config_dword(pdev,
527 MC_DOD_CH_DIMM0, &dimm_dod[0]);
528 pci_read_config_dword(pdev,
529 MC_DOD_CH_DIMM1, &dimm_dod[1]);
530 pci_read_config_dword(pdev,
531 MC_DOD_CH_DIMM2, &dimm_dod[2]);
532
533 (*channels)++;
534
535 for (j = 0; j < 3; j++) {
536 if (!DIMM_PRESENT(dimm_dod[j]))
537 continue;
538 (*csrows)++;
539 }
540 }
541
542 debugf0("Number of active channels on socket %d: %d\n",
543 socket, *channels);
544
545 return 0;
546}
547
548static int get_dimm_config(struct mem_ctl_info *mci, int *csrow)
549{
550 struct i7core_pvt *pvt = mci->pvt_info;
551 struct csrow_info *csr;
552 struct pci_dev *pdev;
553 int i, j;
554 unsigned long last_page = 0;
555 enum edac_type mode;
556 enum mem_type mtype;
557
558 /* Get data from the MC register, function 0 */
559 pdev = pvt->pci_mcr[0];
560 if (!pdev)
561 return -ENODEV;
562
563 /* Device 3 function 0 reads */
564 pci_read_config_dword(pdev, MC_CONTROL, &pvt->info.mc_control);
565 pci_read_config_dword(pdev, MC_STATUS, &pvt->info.mc_status);
566 pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod);
567 pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map);
568
569 debugf0("QPI %d control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
570 pvt->i7core_dev->socket, pvt->info.mc_control, pvt->info.mc_status,
571 pvt->info.max_dod, pvt->info.ch_map);
572
573 if (ECC_ENABLED(pvt)) {
574 debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4);
575 if (ECCx8(pvt))
576 mode = EDAC_S8ECD8ED;
577 else
578 mode = EDAC_S4ECD4ED;
579 } else {
580 debugf0("ECC disabled\n");
581 mode = EDAC_NONE;
582 }
583
584 /* FIXME: need to handle the error codes */
585 debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked "
586 "x%x x 0x%x\n",
587 numdimms(pvt->info.max_dod),
588 numrank(pvt->info.max_dod >> 2),
589 numbank(pvt->info.max_dod >> 4),
590 numrow(pvt->info.max_dod >> 6),
591 numcol(pvt->info.max_dod >> 9));
592
593 for (i = 0; i < NUM_CHANS; i++) {
594 u32 data, dimm_dod[3], value[8];
595
596 if (!pvt->pci_ch[i][0])
597 continue;
598
599 if (!CH_ACTIVE(pvt, i)) {
600 debugf0("Channel %i is not active\n", i);
601 continue;
602 }
603 if (CH_DISABLED(pvt, i)) {
604 debugf0("Channel %i is disabled\n", i);
605 continue;
606 }
607
608 /* Devices 4-6 function 0 */
609 pci_read_config_dword(pvt->pci_ch[i][0],
610 MC_CHANNEL_DIMM_INIT_PARAMS, &data);
611
612 pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ?
613 4 : 2;
614
615 if (data & REGISTERED_DIMM)
616 mtype = MEM_RDDR3;
617 else
618 mtype = MEM_DDR3;
619#if 0
620 if (data & THREE_DIMMS_PRESENT)
621 pvt->channel[i].dimms = 3;
622 else if (data & SINGLE_QUAD_RANK_PRESENT)
623 pvt->channel[i].dimms = 1;
624 else
625 pvt->channel[i].dimms = 2;
626#endif
627
628 /* Devices 4-6 function 1 */
629 pci_read_config_dword(pvt->pci_ch[i][1],
630 MC_DOD_CH_DIMM0, &dimm_dod[0]);
631 pci_read_config_dword(pvt->pci_ch[i][1],
632 MC_DOD_CH_DIMM1, &dimm_dod[1]);
633 pci_read_config_dword(pvt->pci_ch[i][1],
634 MC_DOD_CH_DIMM2, &dimm_dod[2]);
635
636 debugf0("Ch%d phy rd%d, wr%d (0x%08x): "
637 "%d ranks, %cDIMMs\n",
638 i,
639 RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i),
640 data,
641 pvt->channel[i].ranks,
642 (data & REGISTERED_DIMM) ? 'R' : 'U');
643
644 for (j = 0; j < 3; j++) {
645 u32 banks, ranks, rows, cols;
646 u32 size, npages;
647
648 if (!DIMM_PRESENT(dimm_dod[j]))
649 continue;
650
651 banks = numbank(MC_DOD_NUMBANK(dimm_dod[j]));
652 ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j]));
653 rows = numrow(MC_DOD_NUMROW(dimm_dod[j]));
654 cols = numcol(MC_DOD_NUMCOL(dimm_dod[j]));
655
656 /* DDR3 has 8 I/O banks */
657 size = (rows * cols * banks * ranks) >> (20 - 3);
658
659 pvt->channel[i].dimms++;
660
661 debugf0("\tdimm %d %d Mb offset: %x, "
662 "bank: %d, rank: %d, row: %#x, col: %#x\n",
663 j, size,
664 RANKOFFSET(dimm_dod[j]),
665 banks, ranks, rows, cols);
666
667#if PAGE_SHIFT > 20
668 npages = size >> (PAGE_SHIFT - 20);
669#else
670 npages = size << (20 - PAGE_SHIFT);
671#endif
672
673 csr = &mci->csrows[*csrow];
674 csr->first_page = last_page + 1;
675 last_page += npages;
676 csr->last_page = last_page;
677 csr->nr_pages = npages;
678
679 csr->page_mask = 0;
680 csr->grain = 8;
681 csr->csrow_idx = *csrow;
682 csr->nr_channels = 1;
683
684 csr->channels[0].chan_idx = i;
685 csr->channels[0].ce_count = 0;
686
687 pvt->csrow_map[i][j] = *csrow;
688
689 switch (banks) {
690 case 4:
691 csr->dtype = DEV_X4;
692 break;
693 case 8:
694 csr->dtype = DEV_X8;
695 break;
696 case 16:
697 csr->dtype = DEV_X16;
698 break;
699 default:
700 csr->dtype = DEV_UNKNOWN;
701 }
702
703 csr->edac_mode = mode;
704 csr->mtype = mtype;
705
706 (*csrow)++;
707 }
708
709 pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]);
710 pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]);
711 pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]);
712 pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]);
713 pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]);
714 pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]);
715 pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]);
716 pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]);
717 debugf1("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i);
718 for (j = 0; j < 8; j++)
719 debugf1("\t\t%#x\t%#x\t%#x\n",
720 (value[j] >> 27) & 0x1,
721 (value[j] >> 24) & 0x7,
722 (value[j] && ((1 << 24) - 1)));
723 }
724
725 return 0;
726}
727
728/****************************************************************************
729 Error insertion routines
730 ****************************************************************************/
731
732/* The i7core has independent error injection features per channel.
733 However, to have a simpler code, we don't allow enabling error injection
734 on more than one channel.
735 Also, since a change at an inject parameter will be applied only at enable,
736 we're disabling error injection on all write calls to the sysfs nodes that
737 controls the error code injection.
738 */
739static int disable_inject(struct mem_ctl_info *mci)
740{
741 struct i7core_pvt *pvt = mci->pvt_info;
742
743 pvt->inject.enable = 0;
744
745 if (!pvt->pci_ch[pvt->inject.channel][0])
746 return -ENODEV;
747
748 pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
749 MC_CHANNEL_ERROR_INJECT, 0);
750
751 return 0;
752}
753
754/*
755 * i7core inject inject.section
756 *
757 * accept and store error injection inject.section value
758 * bit 0 - refers to the lower 32-byte half cacheline
759 * bit 1 - refers to the upper 32-byte half cacheline
760 */
761static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci,
762 const char *data, size_t count)
763{
764 struct i7core_pvt *pvt = mci->pvt_info;
765 unsigned long value;
766 int rc;
767
768 if (pvt->inject.enable)
769 disable_inject(mci);
770
771 rc = strict_strtoul(data, 10, &value);
772 if ((rc < 0) || (value > 3))
773 return -EIO;
774
775 pvt->inject.section = (u32) value;
776 return count;
777}
778
779static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci,
780 char *data)
781{
782 struct i7core_pvt *pvt = mci->pvt_info;
783 return sprintf(data, "0x%08x\n", pvt->inject.section);
784}
785
786/*
787 * i7core inject.type
788 *
789 * accept and store error injection inject.section value
790 * bit 0 - repeat enable - Enable error repetition
791 * bit 1 - inject ECC error
792 * bit 2 - inject parity error
793 */
794static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci,
795 const char *data, size_t count)
796{
797 struct i7core_pvt *pvt = mci->pvt_info;
798 unsigned long value;
799 int rc;
800
801 if (pvt->inject.enable)
802 disable_inject(mci);
803
804 rc = strict_strtoul(data, 10, &value);
805 if ((rc < 0) || (value > 7))
806 return -EIO;
807
808 pvt->inject.type = (u32) value;
809 return count;
810}
811
812static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci,
813 char *data)
814{
815 struct i7core_pvt *pvt = mci->pvt_info;
816 return sprintf(data, "0x%08x\n", pvt->inject.type);
817}
818
819/*
820 * i7core_inject_inject.eccmask_store
821 *
822 * The type of error (UE/CE) will depend on the inject.eccmask value:
823 * Any bits set to a 1 will flip the corresponding ECC bit
824 * Correctable errors can be injected by flipping 1 bit or the bits within
825 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
826 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
827 * uncorrectable error to be injected.
828 */
829static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci,
830 const char *data, size_t count)
831{
832 struct i7core_pvt *pvt = mci->pvt_info;
833 unsigned long value;
834 int rc;
835
836 if (pvt->inject.enable)
837 disable_inject(mci);
838
839 rc = strict_strtoul(data, 10, &value);
840 if (rc < 0)
841 return -EIO;
842
843 pvt->inject.eccmask = (u32) value;
844 return count;
845}
846
847static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
848 char *data)
849{
850 struct i7core_pvt *pvt = mci->pvt_info;
851 return sprintf(data, "0x%08x\n", pvt->inject.eccmask);
852}
853
854/*
855 * i7core_addrmatch
856 *
857 * The type of error (UE/CE) will depend on the inject.eccmask value:
858 * Any bits set to a 1 will flip the corresponding ECC bit
859 * Correctable errors can be injected by flipping 1 bit or the bits within
860 * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
861 * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
862 * uncorrectable error to be injected.
863 */
864
865#define DECLARE_ADDR_MATCH(param, limit) \
866static ssize_t i7core_inject_store_##param( \
867 struct mem_ctl_info *mci, \
868 const char *data, size_t count) \
869{ \
870 struct i7core_pvt *pvt; \
871 long value; \
872 int rc; \
873 \
874 debugf1("%s()\n", __func__); \
875 pvt = mci->pvt_info; \
876 \
877 if (pvt->inject.enable) \
878 disable_inject(mci); \
879 \
880 if (!strcasecmp(data, "any") || !strcasecmp(data, "any\n"))\
881 value = -1; \
882 else { \
883 rc = strict_strtoul(data, 10, &value); \
884 if ((rc < 0) || (value >= limit)) \
885 return -EIO; \
886 } \
887 \
888 pvt->inject.param = value; \
889 \
890 return count; \
891} \
892 \
893static ssize_t i7core_inject_show_##param( \
894 struct mem_ctl_info *mci, \
895 char *data) \
896{ \
897 struct i7core_pvt *pvt; \
898 \
899 pvt = mci->pvt_info; \
900 debugf1("%s() pvt=%p\n", __func__, pvt); \
901 if (pvt->inject.param < 0) \
902 return sprintf(data, "any\n"); \
903 else \
904 return sprintf(data, "%d\n", pvt->inject.param);\
905}
906
907#define ATTR_ADDR_MATCH(param) \
908 { \
909 .attr = { \
910 .name = #param, \
911 .mode = (S_IRUGO | S_IWUSR) \
912 }, \
913 .show = i7core_inject_show_##param, \
914 .store = i7core_inject_store_##param, \
915 }
916
917DECLARE_ADDR_MATCH(channel, 3);
918DECLARE_ADDR_MATCH(dimm, 3);
919DECLARE_ADDR_MATCH(rank, 4);
920DECLARE_ADDR_MATCH(bank, 32);
921DECLARE_ADDR_MATCH(page, 0x10000);
922DECLARE_ADDR_MATCH(col, 0x4000);
923
924static int write_and_test(struct pci_dev *dev, int where, u32 val)
925{
926 u32 read;
927 int count;
928
929 debugf0("setting pci %02x:%02x.%x reg=%02x value=%08x\n",
930 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
931 where, val);
932
933 for (count = 0; count < 10; count++) {
934 if (count)
935 msleep(100);
936 pci_write_config_dword(dev, where, val);
937 pci_read_config_dword(dev, where, &read);
938
939 if (read == val)
940 return 0;
941 }
942
943 i7core_printk(KERN_ERR, "Error during set pci %02x:%02x.%x reg=%02x "
944 "write=%08x. Read=%08x\n",
945 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
946 where, val, read);
947
948 return -EINVAL;
949}
950
951/*
952 * This routine prepares the Memory Controller for error injection.
953 * The error will be injected when some process tries to write to the
954 * memory that matches the given criteria.
955 * The criteria can be set in terms of a mask where dimm, rank, bank, page
956 * and col can be specified.
957 * A -1 value for any of the mask items will make the MCU to ignore
958 * that matching criteria for error injection.
959 *
960 * It should be noticed that the error will only happen after a write operation
961 * on a memory that matches the condition. if REPEAT_EN is not enabled at
962 * inject mask, then it will produce just one error. Otherwise, it will repeat
963 * until the injectmask would be cleaned.
964 *
965 * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD
966 * is reliable enough to check if the MC is using the
967 * three channels. However, this is not clear at the datasheet.
968 */
969static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
970 const char *data, size_t count)
971{
972 struct i7core_pvt *pvt = mci->pvt_info;
973 u32 injectmask;
974 u64 mask = 0;
975 int rc;
976 long enable;
977
978 if (!pvt->pci_ch[pvt->inject.channel][0])
979 return 0;
980
981 rc = strict_strtoul(data, 10, &enable);
982 if ((rc < 0))
983 return 0;
984
985 if (enable) {
986 pvt->inject.enable = 1;
987 } else {
988 disable_inject(mci);
989 return count;
990 }
991
992 /* Sets pvt->inject.dimm mask */
993 if (pvt->inject.dimm < 0)
994 mask |= 1LL << 41;
995 else {
996 if (pvt->channel[pvt->inject.channel].dimms > 2)
997 mask |= (pvt->inject.dimm & 0x3LL) << 35;
998 else
999 mask |= (pvt->inject.dimm & 0x1LL) << 36;
1000 }
1001
1002 /* Sets pvt->inject.rank mask */
1003 if (pvt->inject.rank < 0)
1004 mask |= 1LL << 40;
1005 else {
1006 if (pvt->channel[pvt->inject.channel].dimms > 2)
1007 mask |= (pvt->inject.rank & 0x1LL) << 34;
1008 else
1009 mask |= (pvt->inject.rank & 0x3LL) << 34;
1010 }
1011
1012 /* Sets pvt->inject.bank mask */
1013 if (pvt->inject.bank < 0)
1014 mask |= 1LL << 39;
1015 else
1016 mask |= (pvt->inject.bank & 0x15LL) << 30;
1017
1018 /* Sets pvt->inject.page mask */
1019 if (pvt->inject.page < 0)
1020 mask |= 1LL << 38;
1021 else
1022 mask |= (pvt->inject.page & 0xffff) << 14;
1023
1024 /* Sets pvt->inject.column mask */
1025 if (pvt->inject.col < 0)
1026 mask |= 1LL << 37;
1027 else
1028 mask |= (pvt->inject.col & 0x3fff);
1029
1030 /*
1031 * bit 0: REPEAT_EN
1032 * bits 1-2: MASK_HALF_CACHELINE
1033 * bit 3: INJECT_ECC
1034 * bit 4: INJECT_ADDR_PARITY
1035 */
1036
1037 injectmask = (pvt->inject.type & 1) |
1038 (pvt->inject.section & 0x3) << 1 |
1039 (pvt->inject.type & 0x6) << (3 - 1);
1040
1041 /* Unlock writes to registers - this register is write only */
1042 pci_write_config_dword(pvt->pci_noncore,
1043 MC_CFG_CONTROL, 0x2);
1044
1045 write_and_test(pvt->pci_ch[pvt->inject.channel][0],
1046 MC_CHANNEL_ADDR_MATCH, mask);
1047 write_and_test(pvt->pci_ch[pvt->inject.channel][0],
1048 MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L);
1049
1050 write_and_test(pvt->pci_ch[pvt->inject.channel][0],
1051 MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask);
1052
1053 write_and_test(pvt->pci_ch[pvt->inject.channel][0],
1054 MC_CHANNEL_ERROR_INJECT, injectmask);
1055
1056 /*
1057 * This is something undocumented, based on my tests
1058 * Without writing 8 to this register, errors aren't injected. Not sure
1059 * why.
1060 */
1061 pci_write_config_dword(pvt->pci_noncore,
1062 MC_CFG_CONTROL, 8);
1063
1064 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
1065 " inject 0x%08x\n",
1066 mask, pvt->inject.eccmask, injectmask);
1067
1068
1069 return count;
1070}
1071
1072static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
1073 char *data)
1074{
1075 struct i7core_pvt *pvt = mci->pvt_info;
1076 u32 injectmask;
1077
1078 if (!pvt->pci_ch[pvt->inject.channel][0])
1079 return 0;
1080
1081 pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
1082 MC_CHANNEL_ERROR_INJECT, &injectmask);
1083
1084 debugf0("Inject error read: 0x%018x\n", injectmask);
1085
1086 if (injectmask & 0x0c)
1087 pvt->inject.enable = 1;
1088
1089 return sprintf(data, "%d\n", pvt->inject.enable);
1090}
1091
1092#define DECLARE_COUNTER(param) \
1093static ssize_t i7core_show_counter_##param( \
1094 struct mem_ctl_info *mci, \
1095 char *data) \
1096{ \
1097 struct i7core_pvt *pvt = mci->pvt_info; \
1098 \
1099 debugf1("%s() \n", __func__); \
1100 if (!pvt->ce_count_available || (pvt->is_registered)) \
1101 return sprintf(data, "data unavailable\n"); \
1102 return sprintf(data, "%lu\n", \
1103 pvt->udimm_ce_count[param]); \
1104}
1105
1106#define ATTR_COUNTER(param) \
1107 { \
1108 .attr = { \
1109 .name = __stringify(udimm##param), \
1110 .mode = (S_IRUGO | S_IWUSR) \
1111 }, \
1112 .show = i7core_show_counter_##param \
1113 }
1114
1115DECLARE_COUNTER(0);
1116DECLARE_COUNTER(1);
1117DECLARE_COUNTER(2);
1118
1119/*
1120 * Sysfs struct
1121 */
1122
1123
1124static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = {
1125 ATTR_ADDR_MATCH(channel),
1126 ATTR_ADDR_MATCH(dimm),
1127 ATTR_ADDR_MATCH(rank),
1128 ATTR_ADDR_MATCH(bank),
1129 ATTR_ADDR_MATCH(page),
1130 ATTR_ADDR_MATCH(col),
1131 { .attr = { .name = NULL } }
1132};
1133
1134static struct mcidev_sysfs_group i7core_inject_addrmatch = {
1135 .name = "inject_addrmatch",
1136 .mcidev_attr = i7core_addrmatch_attrs,
1137};
1138
1139static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = {
1140 ATTR_COUNTER(0),
1141 ATTR_COUNTER(1),
1142 ATTR_COUNTER(2),
1143};
1144
1145static struct mcidev_sysfs_group i7core_udimm_counters = {
1146 .name = "all_channel_counts",
1147 .mcidev_attr = i7core_udimm_counters_attrs,
1148};
1149
1150static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = {
1151 {
1152 .attr = {
1153 .name = "inject_section",
1154 .mode = (S_IRUGO | S_IWUSR)
1155 },
1156 .show = i7core_inject_section_show,
1157 .store = i7core_inject_section_store,
1158 }, {
1159 .attr = {
1160 .name = "inject_type",
1161 .mode = (S_IRUGO | S_IWUSR)
1162 },
1163 .show = i7core_inject_type_show,
1164 .store = i7core_inject_type_store,
1165 }, {
1166 .attr = {
1167 .name = "inject_eccmask",
1168 .mode = (S_IRUGO | S_IWUSR)
1169 },
1170 .show = i7core_inject_eccmask_show,
1171 .store = i7core_inject_eccmask_store,
1172 }, {
1173 .grp = &i7core_inject_addrmatch,
1174 }, {
1175 .attr = {
1176 .name = "inject_enable",
1177 .mode = (S_IRUGO | S_IWUSR)
1178 },
1179 .show = i7core_inject_enable_show,
1180 .store = i7core_inject_enable_store,
1181 },
1182 { .attr = { .name = NULL } }, /* Reserved for udimm counters */
1183 { .attr = { .name = NULL } }
1184};
1185
1186/****************************************************************************
1187 Device initialization routines: put/get, init/exit
1188 ****************************************************************************/
1189
1190/*
1191 * i7core_put_devices 'put' all the devices that we have
1192 * reserved via 'get'
1193 */
1194static void i7core_put_devices(struct i7core_dev *i7core_dev)
1195{
1196 int i;
1197
1198 debugf0(__FILE__ ": %s()\n", __func__);
1199 for (i = 0; i < i7core_dev->n_devs; i++) {
1200 struct pci_dev *pdev = i7core_dev->pdev[i];
1201 if (!pdev)
1202 continue;
1203 debugf0("Removing dev %02x:%02x.%d\n",
1204 pdev->bus->number,
1205 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1206 pci_dev_put(pdev);
1207 }
1208 kfree(i7core_dev->pdev);
1209 list_del(&i7core_dev->list);
1210 kfree(i7core_dev);
1211}
1212
1213static void i7core_put_all_devices(void)
1214{
1215 struct i7core_dev *i7core_dev, *tmp;
1216
1217 list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list)
1218 i7core_put_devices(i7core_dev);
1219}
1220
1221static void __init i7core_xeon_pci_fixup(struct pci_id_table *table)
1222{
1223 struct pci_dev *pdev = NULL;
1224 int i;
1225 /*
1226 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses
1227 * aren't announced by acpi. So, we need to use a legacy scan probing
1228 * to detect them
1229 */
1230 while (table && table->descr) {
1231 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, table->descr[0].dev_id, NULL);
1232 if (unlikely(!pdev)) {
1233 for (i = 0; i < MAX_SOCKET_BUSES; i++)
1234 pcibios_scan_specific_bus(255-i);
1235 }
1236 table++;
1237 }
1238}
1239
1240/*
1241 * i7core_get_devices Find and perform 'get' operation on the MCH's
1242 * device/functions we want to reference for this driver
1243 *
1244 * Need to 'get' device 16 func 1 and func 2
1245 */
1246int i7core_get_onedevice(struct pci_dev **prev, int devno,
1247 struct pci_id_descr *dev_descr, unsigned n_devs)
1248{
1249 struct i7core_dev *i7core_dev;
1250
1251 struct pci_dev *pdev = NULL;
1252 u8 bus = 0;
1253 u8 socket = 0;
1254
1255 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1256 dev_descr->dev_id, *prev);
1257
1258 /*
1259 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs
1260 * is at addr 8086:2c40, instead of 8086:2c41. So, we need
1261 * to probe for the alternate address in case of failure
1262 */
1263 if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev)
1264 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1265 PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev);
1266
1267 if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev)
1268 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1269 PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT,
1270 *prev);
1271
1272 if (!pdev) {
1273 if (*prev) {
1274 *prev = pdev;
1275 return 0;
1276 }
1277
1278 if (dev_descr->optional)
1279 return 0;
1280
1281 if (devno == 0)
1282 return -ENODEV;
1283
1284 i7core_printk(KERN_ERR,
1285 "Device not found: dev %02x.%d PCI ID %04x:%04x\n",
1286 dev_descr->dev, dev_descr->func,
1287 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1288
1289 /* End of list, leave */
1290 return -ENODEV;
1291 }
1292 bus = pdev->bus->number;
1293
1294 if (bus == 0x3f)
1295 socket = 0;
1296 else
1297 socket = 255 - bus;
1298
1299 i7core_dev = get_i7core_dev(socket);
1300 if (!i7core_dev) {
1301 i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL);
1302 if (!i7core_dev)
1303 return -ENOMEM;
1304 i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * n_devs,
1305 GFP_KERNEL);
1306 if (!i7core_dev->pdev) {
1307 kfree(i7core_dev);
1308 return -ENOMEM;
1309 }
1310 i7core_dev->socket = socket;
1311 i7core_dev->n_devs = n_devs;
1312 list_add_tail(&i7core_dev->list, &i7core_edac_list);
1313 }
1314
1315 if (i7core_dev->pdev[devno]) {
1316 i7core_printk(KERN_ERR,
1317 "Duplicated device for "
1318 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1319 bus, dev_descr->dev, dev_descr->func,
1320 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1321 pci_dev_put(pdev);
1322 return -ENODEV;
1323 }
1324
1325 i7core_dev->pdev[devno] = pdev;
1326
1327 /* Sanity check */
1328 if (unlikely(PCI_SLOT(pdev->devfn) != dev_descr->dev ||
1329 PCI_FUNC(pdev->devfn) != dev_descr->func)) {
1330 i7core_printk(KERN_ERR,
1331 "Device PCI ID %04x:%04x "
1332 "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n",
1333 PCI_VENDOR_ID_INTEL, dev_descr->dev_id,
1334 bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1335 bus, dev_descr->dev, dev_descr->func);
1336 return -ENODEV;
1337 }
1338
1339 /* Be sure that the device is enabled */
1340 if (unlikely(pci_enable_device(pdev) < 0)) {
1341 i7core_printk(KERN_ERR,
1342 "Couldn't enable "
1343 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1344 bus, dev_descr->dev, dev_descr->func,
1345 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1346 return -ENODEV;
1347 }
1348
1349 debugf0("Detected socket %d dev %02x:%02x.%d PCI ID %04x:%04x\n",
1350 socket, bus, dev_descr->dev,
1351 dev_descr->func,
1352 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1353
1354 *prev = pdev;
1355
1356 return 0;
1357}
1358
1359static int i7core_get_devices(struct pci_id_table *table)
1360{
1361 int i, rc;
1362 struct pci_dev *pdev = NULL;
1363 struct pci_id_descr *dev_descr;
1364
1365 while (table && table->descr) {
1366 dev_descr = table->descr;
1367 for (i = 0; i < table->n_devs; i++) {
1368 pdev = NULL;
1369 do {
1370 rc = i7core_get_onedevice(&pdev, i, &dev_descr[i],
1371 table->n_devs);
1372 if (rc < 0) {
1373 if (i == 0) {
1374 i = table->n_devs;
1375 break;
1376 }
1377 i7core_put_all_devices();
1378 return -ENODEV;
1379 }
1380 } while (pdev);
1381 }
1382 table++;
1383 }
1384
1385 return 0;
1386 return 0;
1387}
1388
1389static int mci_bind_devs(struct mem_ctl_info *mci,
1390 struct i7core_dev *i7core_dev)
1391{
1392 struct i7core_pvt *pvt = mci->pvt_info;
1393 struct pci_dev *pdev;
1394 int i, func, slot;
1395
1396 /* Associates i7core_dev and mci for future usage */
1397 pvt->i7core_dev = i7core_dev;
1398 i7core_dev->mci = mci;
1399
1400 pvt->is_registered = 0;
1401 for (i = 0; i < i7core_dev->n_devs; i++) {
1402 pdev = i7core_dev->pdev[i];
1403 if (!pdev)
1404 continue;
1405
1406 func = PCI_FUNC(pdev->devfn);
1407 slot = PCI_SLOT(pdev->devfn);
1408 if (slot == 3) {
1409 if (unlikely(func > MAX_MCR_FUNC))
1410 goto error;
1411 pvt->pci_mcr[func] = pdev;
1412 } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) {
1413 if (unlikely(func > MAX_CHAN_FUNC))
1414 goto error;
1415 pvt->pci_ch[slot - 4][func] = pdev;
1416 } else if (!slot && !func)
1417 pvt->pci_noncore = pdev;
1418 else
1419 goto error;
1420
1421 debugf0("Associated fn %d.%d, dev = %p, socket %d\n",
1422 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1423 pdev, i7core_dev->socket);
1424
1425 if (PCI_SLOT(pdev->devfn) == 3 &&
1426 PCI_FUNC(pdev->devfn) == 2)
1427 pvt->is_registered = 1;
1428 }
1429
1430 /*
1431 * Add extra nodes to count errors on udimm
1432 * For registered memory, this is not needed, since the counters
1433 * are already displayed at the standard locations
1434 */
1435 if (!pvt->is_registered)
1436 i7core_sysfs_attrs[ARRAY_SIZE(i7core_sysfs_attrs)-2].grp =
1437 &i7core_udimm_counters;
1438
1439 return 0;
1440
1441error:
1442 i7core_printk(KERN_ERR, "Device %d, function %d "
1443 "is out of the expected range\n",
1444 slot, func);
1445 return -EINVAL;
1446}
1447
1448/****************************************************************************
1449 Error check routines
1450 ****************************************************************************/
1451static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci,
1452 int chan, int dimm, int add)
1453{
1454 char *msg;
1455 struct i7core_pvt *pvt = mci->pvt_info;
1456 int row = pvt->csrow_map[chan][dimm], i;
1457
1458 for (i = 0; i < add; i++) {
1459 msg = kasprintf(GFP_KERNEL, "Corrected error "
1460 "(Socket=%d channel=%d dimm=%d)",
1461 pvt->i7core_dev->socket, chan, dimm);
1462
1463 edac_mc_handle_fbd_ce(mci, row, 0, msg);
1464 kfree (msg);
1465 }
1466}
1467
1468static void i7core_rdimm_update_ce_count(struct mem_ctl_info *mci,
1469 int chan, int new0, int new1, int new2)
1470{
1471 struct i7core_pvt *pvt = mci->pvt_info;
1472 int add0 = 0, add1 = 0, add2 = 0;
1473 /* Updates CE counters if it is not the first time here */
1474 if (pvt->ce_count_available) {
1475 /* Updates CE counters */
1476
1477 add2 = new2 - pvt->rdimm_last_ce_count[chan][2];
1478 add1 = new1 - pvt->rdimm_last_ce_count[chan][1];
1479 add0 = new0 - pvt->rdimm_last_ce_count[chan][0];
1480
1481 if (add2 < 0)
1482 add2 += 0x7fff;
1483 pvt->rdimm_ce_count[chan][2] += add2;
1484
1485 if (add1 < 0)
1486 add1 += 0x7fff;
1487 pvt->rdimm_ce_count[chan][1] += add1;
1488
1489 if (add0 < 0)
1490 add0 += 0x7fff;
1491 pvt->rdimm_ce_count[chan][0] += add0;
1492 } else
1493 pvt->ce_count_available = 1;
1494
1495 /* Store the new values */
1496 pvt->rdimm_last_ce_count[chan][2] = new2;
1497 pvt->rdimm_last_ce_count[chan][1] = new1;
1498 pvt->rdimm_last_ce_count[chan][0] = new0;
1499
1500 /*updated the edac core */
1501 if (add0 != 0)
1502 i7core_rdimm_update_csrow(mci, chan, 0, add0);
1503 if (add1 != 0)
1504 i7core_rdimm_update_csrow(mci, chan, 1, add1);
1505 if (add2 != 0)
1506 i7core_rdimm_update_csrow(mci, chan, 2, add2);
1507
1508}
1509
1510static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info *mci)
1511{
1512 struct i7core_pvt *pvt = mci->pvt_info;
1513 u32 rcv[3][2];
1514 int i, new0, new1, new2;
1515
1516 /*Read DEV 3: FUN 2: MC_COR_ECC_CNT regs directly*/
1517 pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_0,
1518 &rcv[0][0]);
1519 pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_1,
1520 &rcv[0][1]);
1521 pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_2,
1522 &rcv[1][0]);
1523 pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_3,
1524 &rcv[1][1]);
1525 pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_4,
1526 &rcv[2][0]);
1527 pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_5,
1528 &rcv[2][1]);
1529 for (i = 0 ; i < 3; i++) {
1530 debugf3("MC_COR_ECC_CNT%d = 0x%x; MC_COR_ECC_CNT%d = 0x%x\n",
1531 (i * 2), rcv[i][0], (i * 2) + 1, rcv[i][1]);
1532 /*if the channel has 3 dimms*/
1533 if (pvt->channel[i].dimms > 2) {
1534 new0 = DIMM_BOT_COR_ERR(rcv[i][0]);
1535 new1 = DIMM_TOP_COR_ERR(rcv[i][0]);
1536 new2 = DIMM_BOT_COR_ERR(rcv[i][1]);
1537 } else {
1538 new0 = DIMM_TOP_COR_ERR(rcv[i][0]) +
1539 DIMM_BOT_COR_ERR(rcv[i][0]);
1540 new1 = DIMM_TOP_COR_ERR(rcv[i][1]) +
1541 DIMM_BOT_COR_ERR(rcv[i][1]);
1542 new2 = 0;
1543 }
1544
1545 i7core_rdimm_update_ce_count(mci, i, new0, new1, new2);
1546 }
1547}
1548
1549/* This function is based on the device 3 function 4 registers as described on:
1550 * Intel Xeon Processor 5500 Series Datasheet Volume 2
1551 * http://www.intel.com/Assets/PDF/datasheet/321322.pdf
1552 * also available at:
1553 * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
1554 */
1555static void i7core_udimm_check_mc_ecc_err(struct mem_ctl_info *mci)
1556{
1557 struct i7core_pvt *pvt = mci->pvt_info;
1558 u32 rcv1, rcv0;
1559 int new0, new1, new2;
1560
1561 if (!pvt->pci_mcr[4]) {
1562 debugf0("%s MCR registers not found\n", __func__);
1563 return;
1564 }
1565
1566 /* Corrected test errors */
1567 pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1);
1568 pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0);
1569
1570 /* Store the new values */
1571 new2 = DIMM2_COR_ERR(rcv1);
1572 new1 = DIMM1_COR_ERR(rcv0);
1573 new0 = DIMM0_COR_ERR(rcv0);
1574
1575 /* Updates CE counters if it is not the first time here */
1576 if (pvt->ce_count_available) {
1577 /* Updates CE counters */
1578 int add0, add1, add2;
1579
1580 add2 = new2 - pvt->udimm_last_ce_count[2];
1581 add1 = new1 - pvt->udimm_last_ce_count[1];
1582 add0 = new0 - pvt->udimm_last_ce_count[0];
1583
1584 if (add2 < 0)
1585 add2 += 0x7fff;
1586 pvt->udimm_ce_count[2] += add2;
1587
1588 if (add1 < 0)
1589 add1 += 0x7fff;
1590 pvt->udimm_ce_count[1] += add1;
1591
1592 if (add0 < 0)
1593 add0 += 0x7fff;
1594 pvt->udimm_ce_count[0] += add0;
1595
1596 if (add0 | add1 | add2)
1597 i7core_printk(KERN_ERR, "New Corrected error(s): "
1598 "dimm0: +%d, dimm1: +%d, dimm2 +%d\n",
1599 add0, add1, add2);
1600 } else
1601 pvt->ce_count_available = 1;
1602
1603 /* Store the new values */
1604 pvt->udimm_last_ce_count[2] = new2;
1605 pvt->udimm_last_ce_count[1] = new1;
1606 pvt->udimm_last_ce_count[0] = new0;
1607}
1608
1609/*
1610 * According with tables E-11 and E-12 of chapter E.3.3 of Intel 64 and IA-32
1611 * Architectures Software Developer’s Manual Volume 3B.
1612 * Nehalem are defined as family 0x06, model 0x1a
1613 *
1614 * The MCA registers used here are the following ones:
1615 * struct mce field MCA Register
1616 * m->status MSR_IA32_MC8_STATUS
1617 * m->addr MSR_IA32_MC8_ADDR
1618 * m->misc MSR_IA32_MC8_MISC
1619 * In the case of Nehalem, the error information is masked at .status and .misc
1620 * fields
1621 */
1622static void i7core_mce_output_error(struct mem_ctl_info *mci,
1623 struct mce *m)
1624{
1625 struct i7core_pvt *pvt = mci->pvt_info;
1626 char *type, *optype, *err, *msg;
1627 unsigned long error = m->status & 0x1ff0000l;
1628 u32 optypenum = (m->status >> 4) & 0x07;
1629 u32 core_err_cnt = (m->status >> 38) && 0x7fff;
1630 u32 dimm = (m->misc >> 16) & 0x3;
1631 u32 channel = (m->misc >> 18) & 0x3;
1632 u32 syndrome = m->misc >> 32;
1633 u32 errnum = find_first_bit(&error, 32);
1634 int csrow;
1635
1636 if (m->mcgstatus & 1)
1637 type = "FATAL";
1638 else
1639 type = "NON_FATAL";
1640
1641 switch (optypenum) {
1642 case 0:
1643 optype = "generic undef request";
1644 break;
1645 case 1:
1646 optype = "read error";
1647 break;
1648 case 2:
1649 optype = "write error";
1650 break;
1651 case 3:
1652 optype = "addr/cmd error";
1653 break;
1654 case 4:
1655 optype = "scrubbing error";
1656 break;
1657 default:
1658 optype = "reserved";
1659 break;
1660 }
1661
1662 switch (errnum) {
1663 case 16:
1664 err = "read ECC error";
1665 break;
1666 case 17:
1667 err = "RAS ECC error";
1668 break;
1669 case 18:
1670 err = "write parity error";
1671 break;
1672 case 19:
1673 err = "redundacy loss";
1674 break;
1675 case 20:
1676 err = "reserved";
1677 break;
1678 case 21:
1679 err = "memory range error";
1680 break;
1681 case 22:
1682 err = "RTID out of range";
1683 break;
1684 case 23:
1685 err = "address parity error";
1686 break;
1687 case 24:
1688 err = "byte enable parity error";
1689 break;
1690 default:
1691 err = "unknown";
1692 }
1693
1694 /* FIXME: should convert addr into bank and rank information */
1695 msg = kasprintf(GFP_ATOMIC,
1696 "%s (addr = 0x%08llx, cpu=%d, Dimm=%d, Channel=%d, "
1697 "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n",
1698 type, (long long) m->addr, m->cpu, dimm, channel,
1699 syndrome, core_err_cnt, (long long)m->status,
1700 (long long)m->misc, optype, err);
1701
1702 debugf0("%s", msg);
1703
1704 csrow = pvt->csrow_map[channel][dimm];
1705
1706 /* Call the helper to output message */
1707 if (m->mcgstatus & 1)
1708 edac_mc_handle_fbd_ue(mci, csrow, 0,
1709 0 /* FIXME: should be channel here */, msg);
1710 else if (!pvt->is_registered)
1711 edac_mc_handle_fbd_ce(mci, csrow,
1712 0 /* FIXME: should be channel here */, msg);
1713
1714 kfree(msg);
1715}
1716
1717/*
1718 * i7core_check_error Retrieve and process errors reported by the
1719 * hardware. Called by the Core module.
1720 */
1721static void i7core_check_error(struct mem_ctl_info *mci)
1722{
1723 struct i7core_pvt *pvt = mci->pvt_info;
1724 int i;
1725 unsigned count = 0;
1726 struct mce *m;
1727
1728 /*
1729 * MCE first step: Copy all mce errors into a temporary buffer
1730 * We use a double buffering here, to reduce the risk of
1731 * loosing an error.
1732 */
1733 smp_rmb();
1734 count = (pvt->mce_out + MCE_LOG_LEN - pvt->mce_in)
1735 % MCE_LOG_LEN;
1736 if (!count)
1737 goto check_ce_error;
1738
1739 m = pvt->mce_outentry;
1740 if (pvt->mce_in + count > MCE_LOG_LEN) {
1741 unsigned l = MCE_LOG_LEN - pvt->mce_in;
1742
1743 memcpy(m, &pvt->mce_entry[pvt->mce_in], sizeof(*m) * l);
1744 smp_wmb();
1745 pvt->mce_in = 0;
1746 count -= l;
1747 m += l;
1748 }
1749 memcpy(m, &pvt->mce_entry[pvt->mce_in], sizeof(*m) * count);
1750 smp_wmb();
1751 pvt->mce_in += count;
1752
1753 smp_rmb();
1754 if (pvt->mce_overrun) {
1755 i7core_printk(KERN_ERR, "Lost %d memory errors\n",
1756 pvt->mce_overrun);
1757 smp_wmb();
1758 pvt->mce_overrun = 0;
1759 }
1760
1761 /*
1762 * MCE second step: parse errors and display
1763 */
1764 for (i = 0; i < count; i++)
1765 i7core_mce_output_error(mci, &pvt->mce_outentry[i]);
1766
1767 /*
1768 * Now, let's increment CE error counts
1769 */
1770check_ce_error:
1771 if (!pvt->is_registered)
1772 i7core_udimm_check_mc_ecc_err(mci);
1773 else
1774 i7core_rdimm_check_mc_ecc_err(mci);
1775}
1776
1777/*
1778 * i7core_mce_check_error Replicates mcelog routine to get errors
1779 * This routine simply queues mcelog errors, and
1780 * return. The error itself should be handled later
1781 * by i7core_check_error.
1782 * WARNING: As this routine should be called at NMI time, extra care should
1783 * be taken to avoid deadlocks, and to be as fast as possible.
1784 */
1785static int i7core_mce_check_error(void *priv, struct mce *mce)
1786{
1787 struct mem_ctl_info *mci = priv;
1788 struct i7core_pvt *pvt = mci->pvt_info;
1789
1790 /*
1791 * Just let mcelog handle it if the error is
1792 * outside the memory controller
1793 */
1794 if (((mce->status & 0xffff) >> 7) != 1)
1795 return 0;
1796
1797 /* Bank 8 registers are the only ones that we know how to handle */
1798 if (mce->bank != 8)
1799 return 0;
1800
1801#ifdef CONFIG_SMP
1802 /* Only handle if it is the right mc controller */
1803 if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket)
1804 return 0;
1805#endif
1806
1807 smp_rmb();
1808 if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
1809 smp_wmb();
1810 pvt->mce_overrun++;
1811 return 0;
1812 }
1813
1814 /* Copy memory error at the ringbuffer */
1815 memcpy(&pvt->mce_entry[pvt->mce_out], mce, sizeof(*mce));
1816 smp_wmb();
1817 pvt->mce_out = (pvt->mce_out + 1) % MCE_LOG_LEN;
1818
1819 /* Handle fatal errors immediately */
1820 if (mce->mcgstatus & 1)
1821 i7core_check_error(mci);
1822
1823 /* Advice mcelog that the error were handled */
1824 return 1;
1825}
1826
1827static int i7core_register_mci(struct i7core_dev *i7core_dev,
1828 int num_channels, int num_csrows)
1829{
1830 struct mem_ctl_info *mci;
1831 struct i7core_pvt *pvt;
1832 int csrow = 0;
1833 int rc;
1834
1835 /* allocate a new MC control structure */
1836 mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels,
1837 i7core_dev->socket);
1838 if (unlikely(!mci))
1839 return -ENOMEM;
1840
1841 debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
1842
1843 /* record ptr to the generic device */
1844 mci->dev = &i7core_dev->pdev[0]->dev;
1845
1846 pvt = mci->pvt_info;
1847 memset(pvt, 0, sizeof(*pvt));
1848
1849 /*
1850 * FIXME: how to handle RDDR3 at MCI level? It is possible to have
1851 * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different
1852 * memory channels
1853 */
1854 mci->mtype_cap = MEM_FLAG_DDR3;
1855 mci->edac_ctl_cap = EDAC_FLAG_NONE;
1856 mci->edac_cap = EDAC_FLAG_NONE;
1857 mci->mod_name = "i7core_edac.c";
1858 mci->mod_ver = I7CORE_REVISION;
1859 mci->ctl_name = kasprintf(GFP_KERNEL, "i7 core #%d",
1860 i7core_dev->socket);
1861 mci->dev_name = pci_name(i7core_dev->pdev[0]);
1862 mci->ctl_page_to_phys = NULL;
1863 mci->mc_driver_sysfs_attributes = i7core_sysfs_attrs;
1864 /* Set the function pointer to an actual operation function */
1865 mci->edac_check = i7core_check_error;
1866
1867 /* Store pci devices at mci for faster access */
1868 rc = mci_bind_devs(mci, i7core_dev);
1869 if (unlikely(rc < 0))
1870 goto fail;
1871
1872 /* Get dimm basic config */
1873 get_dimm_config(mci, &csrow);
1874
1875 /* add this new MC control structure to EDAC's list of MCs */
1876 if (unlikely(edac_mc_add_mc(mci))) {
1877 debugf0("MC: " __FILE__
1878 ": %s(): failed edac_mc_add_mc()\n", __func__);
1879 /* FIXME: perhaps some code should go here that disables error
1880 * reporting if we just enabled it
1881 */
1882
1883 rc = -EINVAL;
1884 goto fail;
1885 }
1886
1887 /* allocating generic PCI control info */
1888 i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev,
1889 EDAC_MOD_STR);
1890 if (unlikely(!i7core_pci)) {
1891 printk(KERN_WARNING
1892 "%s(): Unable to create PCI control\n",
1893 __func__);
1894 printk(KERN_WARNING
1895 "%s(): PCI error report via EDAC not setup\n",
1896 __func__);
1897 }
1898
1899 /* Default error mask is any memory */
1900 pvt->inject.channel = 0;
1901 pvt->inject.dimm = -1;
1902 pvt->inject.rank = -1;
1903 pvt->inject.bank = -1;
1904 pvt->inject.page = -1;
1905 pvt->inject.col = -1;
1906
1907 /* Registers on edac_mce in order to receive memory errors */
1908 pvt->edac_mce.priv = mci;
1909 pvt->edac_mce.check_error = i7core_mce_check_error;
1910
1911 rc = edac_mce_register(&pvt->edac_mce);
1912 if (unlikely(rc < 0)) {
1913 debugf0("MC: " __FILE__
1914 ": %s(): failed edac_mce_register()\n", __func__);
1915 }
1916
1917fail:
1918 if (rc < 0)
1919 edac_mc_free(mci);
1920 return rc;
1921}
1922
1923/*
1924 * i7core_probe Probe for ONE instance of device to see if it is
1925 * present.
1926 * return:
1927 * 0 for FOUND a device
1928 * < 0 for error code
1929 */
1930static int __devinit i7core_probe(struct pci_dev *pdev,
1931 const struct pci_device_id *id)
1932{
1933 int dev_idx = id->driver_data;
1934 int rc;
1935 struct i7core_dev *i7core_dev;
1936
1937 /*
1938 * All memory controllers are allocated at the first pass.
1939 */
1940 if (unlikely(dev_idx >= 1))
1941 return -EINVAL;
1942
1943 /* get the pci devices we want to reserve for our use */
1944 mutex_lock(&i7core_edac_lock);
1945
1946 rc = i7core_get_devices(pci_dev_table);
1947 if (unlikely(rc < 0))
1948 goto fail0;
1949
1950 list_for_each_entry(i7core_dev, &i7core_edac_list, list) {
1951 int channels;
1952 int csrows;
1953
1954 /* Check the number of active and not disabled channels */
1955 rc = i7core_get_active_channels(i7core_dev->socket,
1956 &channels, &csrows);
1957 if (unlikely(rc < 0))
1958 goto fail1;
1959
1960 rc = i7core_register_mci(i7core_dev, channels, csrows);
1961 if (unlikely(rc < 0))
1962 goto fail1;
1963 }
1964
1965 i7core_printk(KERN_INFO, "Driver loaded.\n");
1966
1967 mutex_unlock(&i7core_edac_lock);
1968 return 0;
1969
1970fail1:
1971 i7core_put_all_devices();
1972fail0:
1973 mutex_unlock(&i7core_edac_lock);
1974 return rc;
1975}
1976
1977/*
1978 * i7core_remove destructor for one instance of device
1979 *
1980 */
1981static void __devexit i7core_remove(struct pci_dev *pdev)
1982{
1983 struct mem_ctl_info *mci;
1984 struct i7core_dev *i7core_dev, *tmp;
1985
1986 debugf0(__FILE__ ": %s()\n", __func__);
1987
1988 if (i7core_pci)
1989 edac_pci_release_generic_ctl(i7core_pci);
1990
1991 /*
1992 * we have a trouble here: pdev value for removal will be wrong, since
1993 * it will point to the X58 register used to detect that the machine
1994 * is a Nehalem or upper design. However, due to the way several PCI
1995 * devices are grouped together to provide MC functionality, we need
1996 * to use a different method for releasing the devices
1997 */
1998
1999 mutex_lock(&i7core_edac_lock);
2000 list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) {
2001 mci = edac_mc_del_mc(&i7core_dev->pdev[0]->dev);
2002 if (mci) {
2003 struct i7core_pvt *pvt = mci->pvt_info;
2004
2005 i7core_dev = pvt->i7core_dev;
2006 edac_mce_unregister(&pvt->edac_mce);
2007 kfree(mci->ctl_name);
2008 edac_mc_free(mci);
2009 i7core_put_devices(i7core_dev);
2010 } else {
2011 i7core_printk(KERN_ERR,
2012 "Couldn't find mci for socket %d\n",
2013 i7core_dev->socket);
2014 }
2015 }
2016 mutex_unlock(&i7core_edac_lock);
2017}
2018
2019MODULE_DEVICE_TABLE(pci, i7core_pci_tbl);
2020
2021/*
2022 * i7core_driver pci_driver structure for this module
2023 *
2024 */
2025static struct pci_driver i7core_driver = {
2026 .name = "i7core_edac",
2027 .probe = i7core_probe,
2028 .remove = __devexit_p(i7core_remove),
2029 .id_table = i7core_pci_tbl,
2030};
2031
2032/*
2033 * i7core_init Module entry function
2034 * Try to initialize this module for its devices
2035 */
2036static int __init i7core_init(void)
2037{
2038 int pci_rc;
2039
2040 debugf2("MC: " __FILE__ ": %s()\n", __func__);
2041
2042 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
2043 opstate_init();
2044
2045 i7core_xeon_pci_fixup(pci_dev_table);
2046
2047 pci_rc = pci_register_driver(&i7core_driver);
2048
2049 if (pci_rc >= 0)
2050 return 0;
2051
2052 i7core_printk(KERN_ERR, "Failed to register device with error %d.\n",
2053 pci_rc);
2054
2055 return pci_rc;
2056}
2057
2058/*
2059 * i7core_exit() Module exit function
2060 * Unregister the driver
2061 */
2062static void __exit i7core_exit(void)
2063{
2064 debugf2("MC: " __FILE__ ": %s()\n", __func__);
2065 pci_unregister_driver(&i7core_driver);
2066}
2067
2068module_init(i7core_init);
2069module_exit(i7core_exit);
2070
2071MODULE_LICENSE("GPL");
2072MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
2073MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
2074MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
2075 I7CORE_REVISION);
2076
2077module_param(edac_op_state, int, 0444);
2078MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 6c1886b497ff..52ca09bf4726 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -229,7 +229,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
229 229
230 pdata->edac_idx = edac_pci_idx++; 230 pdata->edac_idx = edac_pci_idx++;
231 231
232 res = of_address_to_resource(op->node, 0, &r); 232 res = of_address_to_resource(op->dev.of_node, 0, &r);
233 if (res) { 233 if (res) {
234 printk(KERN_ERR "%s: Unable to get resource for " 234 printk(KERN_ERR "%s: Unable to get resource for "
235 "PCI err regs\n", __func__); 235 "PCI err regs\n", __func__);
@@ -274,7 +274,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
274 } 274 }
275 275
276 if (edac_op_state == EDAC_OPSTATE_INT) { 276 if (edac_op_state == EDAC_OPSTATE_INT) {
277 pdata->irq = irq_of_parse_and_map(op->node, 0); 277 pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
278 res = devm_request_irq(&op->dev, pdata->irq, 278 res = devm_request_irq(&op->dev, pdata->irq,
279 mpc85xx_pci_isr, IRQF_DISABLED, 279 mpc85xx_pci_isr, IRQF_DISABLED,
280 "[EDAC] PCI err", pci); 280 "[EDAC] PCI err", pci);
@@ -529,7 +529,7 @@ static int __devinit mpc85xx_l2_err_probe(struct of_device *op,
529 edac_dev->ctl_name = pdata->name; 529 edac_dev->ctl_name = pdata->name;
530 edac_dev->dev_name = pdata->name; 530 edac_dev->dev_name = pdata->name;
531 531
532 res = of_address_to_resource(op->node, 0, &r); 532 res = of_address_to_resource(op->dev.of_node, 0, &r);
533 if (res) { 533 if (res) {
534 printk(KERN_ERR "%s: Unable to get resource for " 534 printk(KERN_ERR "%s: Unable to get resource for "
535 "L2 err regs\n", __func__); 535 "L2 err regs\n", __func__);
@@ -576,7 +576,7 @@ static int __devinit mpc85xx_l2_err_probe(struct of_device *op,
576 } 576 }
577 577
578 if (edac_op_state == EDAC_OPSTATE_INT) { 578 if (edac_op_state == EDAC_OPSTATE_INT) {
579 pdata->irq = irq_of_parse_and_map(op->node, 0); 579 pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
580 res = devm_request_irq(&op->dev, pdata->irq, 580 res = devm_request_irq(&op->dev, pdata->irq,
581 mpc85xx_l2_isr, IRQF_DISABLED, 581 mpc85xx_l2_isr, IRQF_DISABLED,
582 "[EDAC] L2 err", edac_dev); 582 "[EDAC] L2 err", edac_dev);
@@ -978,7 +978,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
978 mci->ctl_name = pdata->name; 978 mci->ctl_name = pdata->name;
979 mci->dev_name = pdata->name; 979 mci->dev_name = pdata->name;
980 980
981 res = of_address_to_resource(op->node, 0, &r); 981 res = of_address_to_resource(op->dev.of_node, 0, &r);
982 if (res) { 982 if (res) {
983 printk(KERN_ERR "%s: Unable to get resource for MC err regs\n", 983 printk(KERN_ERR "%s: Unable to get resource for MC err regs\n",
984 __func__); 984 __func__);
@@ -1052,7 +1052,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
1052 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, 0x10000); 1052 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, 0x10000);
1053 1053
1054 /* register interrupts */ 1054 /* register interrupts */
1055 pdata->irq = irq_of_parse_and_map(op->node, 0); 1055 pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
1056 res = devm_request_irq(&op->dev, pdata->irq, 1056 res = devm_request_irq(&op->dev, pdata->irq,
1057 mpc85xx_mc_isr, 1057 mpc85xx_mc_isr,
1058 IRQF_DISABLED | IRQF_SHARED, 1058 IRQF_DISABLED | IRQF_SHARED,
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c
index 9d6f6783328c..e78839e89a06 100644
--- a/drivers/edac/ppc4xx_edac.c
+++ b/drivers/edac/ppc4xx_edac.c
@@ -1022,7 +1022,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci,
1022 int status = 0; 1022 int status = 0;
1023 const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK); 1023 const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK);
1024 struct ppc4xx_edac_pdata *pdata = NULL; 1024 struct ppc4xx_edac_pdata *pdata = NULL;
1025 const struct device_node *np = op->node; 1025 const struct device_node *np = op->dev.of_node;
1026 1026
1027 if (match == NULL) 1027 if (match == NULL)
1028 return -EINVAL; 1028 return -EINVAL;
@@ -1113,7 +1113,7 @@ ppc4xx_edac_register_irq(struct of_device *op, struct mem_ctl_info *mci)
1113 int status = 0; 1113 int status = 0;
1114 int ded_irq, sec_irq; 1114 int ded_irq, sec_irq;
1115 struct ppc4xx_edac_pdata *pdata = mci->pvt_info; 1115 struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
1116 struct device_node *np = op->node; 1116 struct device_node *np = op->dev.of_node;
1117 1117
1118 ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX); 1118 ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX);
1119 sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX); 1119 sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX);
@@ -1243,7 +1243,7 @@ ppc4xx_edac_probe(struct of_device *op, const struct of_device_id *match)
1243 int status = 0; 1243 int status = 0;
1244 u32 mcopt1, memcheck; 1244 u32 mcopt1, memcheck;
1245 dcr_host_t dcr_host; 1245 dcr_host_t dcr_host;
1246 const struct device_node *np = op->node; 1246 const struct device_node *np = op->dev.of_node;
1247 struct mem_ctl_info *mci = NULL; 1247 struct mem_ctl_info *mci = NULL;
1248 static int ppc4xx_edac_instance; 1248 static int ppc4xx_edac_instance;
1249 1249
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 764401951041..9b2a54117c91 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -860,19 +860,24 @@ static void output_poll_execute(struct slow_work *work)
860 } 860 }
861} 861}
862 862
863void drm_kms_helper_poll_init(struct drm_device *dev) 863void drm_kms_helper_poll_disable(struct drm_device *dev)
864{
865 if (!dev->mode_config.poll_enabled)
866 return;
867 delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
868}
869EXPORT_SYMBOL(drm_kms_helper_poll_disable);
870
871void drm_kms_helper_poll_enable(struct drm_device *dev)
864{ 872{
865 struct drm_connector *connector;
866 bool poll = false; 873 bool poll = false;
874 struct drm_connector *connector;
867 int ret; 875 int ret;
868 876
869 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 877 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
870 if (connector->polled) 878 if (connector->polled)
871 poll = true; 879 poll = true;
872 } 880 }
873 slow_work_register_user(THIS_MODULE);
874 delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
875 &output_poll_ops);
876 881
877 if (poll) { 882 if (poll) {
878 ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD); 883 ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD);
@@ -880,11 +885,22 @@ void drm_kms_helper_poll_init(struct drm_device *dev)
880 DRM_ERROR("delayed enqueue failed %d\n", ret); 885 DRM_ERROR("delayed enqueue failed %d\n", ret);
881 } 886 }
882} 887}
888EXPORT_SYMBOL(drm_kms_helper_poll_enable);
889
890void drm_kms_helper_poll_init(struct drm_device *dev)
891{
892 slow_work_register_user(THIS_MODULE);
893 delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
894 &output_poll_ops);
895 dev->mode_config.poll_enabled = true;
896
897 drm_kms_helper_poll_enable(dev);
898}
883EXPORT_SYMBOL(drm_kms_helper_poll_init); 899EXPORT_SYMBOL(drm_kms_helper_poll_init);
884 900
885void drm_kms_helper_poll_fini(struct drm_device *dev) 901void drm_kms_helper_poll_fini(struct drm_device *dev)
886{ 902{
887 delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); 903 drm_kms_helper_poll_disable(dev);
888 slow_work_unregister_user(THIS_MODULE); 904 slow_work_unregister_user(THIS_MODULE);
889} 905}
890EXPORT_SYMBOL(drm_kms_helper_poll_fini); 906EXPORT_SYMBOL(drm_kms_helper_poll_fini);
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 95639017bdbe..da78f2c0d909 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -22,6 +22,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
22 intel_fb.o \ 22 intel_fb.o \
23 intel_tv.o \ 23 intel_tv.o \
24 intel_dvo.o \ 24 intel_dvo.o \
25 intel_ringbuffer.o \
25 intel_overlay.o \ 26 intel_overlay.o \
26 dvo_ch7xxx.o \ 27 dvo_ch7xxx.o \
27 dvo_ch7017.o \ 28 dvo_ch7017.o \
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 322070c0c631..52510ad8b25d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -77,7 +77,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
77 case ACTIVE_LIST: 77 case ACTIVE_LIST:
78 seq_printf(m, "Active:\n"); 78 seq_printf(m, "Active:\n");
79 lock = &dev_priv->mm.active_list_lock; 79 lock = &dev_priv->mm.active_list_lock;
80 head = &dev_priv->mm.active_list; 80 head = &dev_priv->render_ring.active_list;
81 break; 81 break;
82 case INACTIVE_LIST: 82 case INACTIVE_LIST:
83 seq_printf(m, "Inactive:\n"); 83 seq_printf(m, "Inactive:\n");
@@ -129,7 +129,8 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
129 struct drm_i915_gem_request *gem_request; 129 struct drm_i915_gem_request *gem_request;
130 130
131 seq_printf(m, "Request:\n"); 131 seq_printf(m, "Request:\n");
132 list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) { 132 list_for_each_entry(gem_request, &dev_priv->render_ring.request_list,
133 list) {
133 seq_printf(m, " %d @ %d\n", 134 seq_printf(m, " %d @ %d\n",
134 gem_request->seqno, 135 gem_request->seqno,
135 (int) (jiffies - gem_request->emitted_jiffies)); 136 (int) (jiffies - gem_request->emitted_jiffies));
@@ -143,9 +144,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data)
143 struct drm_device *dev = node->minor->dev; 144 struct drm_device *dev = node->minor->dev;
144 drm_i915_private_t *dev_priv = dev->dev_private; 145 drm_i915_private_t *dev_priv = dev->dev_private;
145 146
146 if (dev_priv->hw_status_page != NULL) { 147 if (dev_priv->render_ring.status_page.page_addr != NULL) {
147 seq_printf(m, "Current sequence: %d\n", 148 seq_printf(m, "Current sequence: %d\n",
148 i915_get_gem_seqno(dev)); 149 i915_get_gem_seqno(dev, &dev_priv->render_ring));
149 } else { 150 } else {
150 seq_printf(m, "Current sequence: hws uninitialized\n"); 151 seq_printf(m, "Current sequence: hws uninitialized\n");
151 } 152 }
@@ -195,9 +196,9 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
195 } 196 }
196 seq_printf(m, "Interrupts received: %d\n", 197 seq_printf(m, "Interrupts received: %d\n",
197 atomic_read(&dev_priv->irq_received)); 198 atomic_read(&dev_priv->irq_received));
198 if (dev_priv->hw_status_page != NULL) { 199 if (dev_priv->render_ring.status_page.page_addr != NULL) {
199 seq_printf(m, "Current sequence: %d\n", 200 seq_printf(m, "Current sequence: %d\n",
200 i915_get_gem_seqno(dev)); 201 i915_get_gem_seqno(dev, &dev_priv->render_ring));
201 } else { 202 } else {
202 seq_printf(m, "Current sequence: hws uninitialized\n"); 203 seq_printf(m, "Current sequence: hws uninitialized\n");
203 } 204 }
@@ -251,7 +252,7 @@ static int i915_hws_info(struct seq_file *m, void *data)
251 int i; 252 int i;
252 volatile u32 *hws; 253 volatile u32 *hws;
253 254
254 hws = (volatile u32 *)dev_priv->hw_status_page; 255 hws = (volatile u32 *)dev_priv->render_ring.status_page.page_addr;
255 if (hws == NULL) 256 if (hws == NULL)
256 return 0; 257 return 0;
257 258
@@ -287,7 +288,8 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data)
287 288
288 spin_lock(&dev_priv->mm.active_list_lock); 289 spin_lock(&dev_priv->mm.active_list_lock);
289 290
290 list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { 291 list_for_each_entry(obj_priv, &dev_priv->render_ring.active_list,
292 list) {
291 obj = &obj_priv->base; 293 obj = &obj_priv->base;
292 if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { 294 if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
293 ret = i915_gem_object_get_pages(obj, 0); 295 ret = i915_gem_object_get_pages(obj, 0);
@@ -317,14 +319,14 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data)
317 u8 *virt; 319 u8 *virt;
318 uint32_t *ptr, off; 320 uint32_t *ptr, off;
319 321
320 if (!dev_priv->ring.ring_obj) { 322 if (!dev_priv->render_ring.gem_object) {
321 seq_printf(m, "No ringbuffer setup\n"); 323 seq_printf(m, "No ringbuffer setup\n");
322 return 0; 324 return 0;
323 } 325 }
324 326
325 virt = dev_priv->ring.virtual_start; 327 virt = dev_priv->render_ring.virtual_start;
326 328
327 for (off = 0; off < dev_priv->ring.Size; off += 4) { 329 for (off = 0; off < dev_priv->render_ring.size; off += 4) {
328 ptr = (uint32_t *)(virt + off); 330 ptr = (uint32_t *)(virt + off);
329 seq_printf(m, "%08x : %08x\n", off, *ptr); 331 seq_printf(m, "%08x : %08x\n", off, *ptr);
330 } 332 }
@@ -344,7 +346,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
344 346
345 seq_printf(m, "RingHead : %08x\n", head); 347 seq_printf(m, "RingHead : %08x\n", head);
346 seq_printf(m, "RingTail : %08x\n", tail); 348 seq_printf(m, "RingTail : %08x\n", tail);
347 seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); 349 seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.size);
348 seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); 350 seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
349 351
350 return 0; 352 return 0;
@@ -489,11 +491,14 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
489 struct drm_device *dev = node->minor->dev; 491 struct drm_device *dev = node->minor->dev;
490 drm_i915_private_t *dev_priv = dev->dev_private; 492 drm_i915_private_t *dev_priv = dev->dev_private;
491 u16 rgvswctl = I915_READ16(MEMSWCTL); 493 u16 rgvswctl = I915_READ16(MEMSWCTL);
494 u16 rgvstat = I915_READ16(MEMSTAT_ILK);
492 495
493 seq_printf(m, "Last command: 0x%01x\n", (rgvswctl >> 13) & 0x3); 496 seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf);
494 seq_printf(m, "Command status: %d\n", (rgvswctl >> 12) & 1); 497 seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f);
495 seq_printf(m, "P%d DELAY 0x%02x\n", (rgvswctl >> 8) & 0xf, 498 seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >>
496 rgvswctl & 0x3f); 499 MEMSTAT_VID_SHIFT);
500 seq_printf(m, "Current P-state: %d\n",
501 (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT);
497 502
498 return 0; 503 return 0;
499} 504}
@@ -508,7 +513,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)
508 513
509 for (i = 0; i < 16; i++) { 514 for (i = 0; i < 16; i++) {
510 delayfreq = I915_READ(PXVFREQ_BASE + i * 4); 515 delayfreq = I915_READ(PXVFREQ_BASE + i * 4);
511 seq_printf(m, "P%02dVIDFREQ: 0x%08x\n", i, delayfreq); 516 seq_printf(m, "P%02dVIDFREQ: 0x%08x (VID: %d)\n", i, delayfreq,
517 (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT);
512 } 518 }
513 519
514 return 0; 520 return 0;
@@ -541,6 +547,8 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
541 struct drm_device *dev = node->minor->dev; 547 struct drm_device *dev = node->minor->dev;
542 drm_i915_private_t *dev_priv = dev->dev_private; 548 drm_i915_private_t *dev_priv = dev->dev_private;
543 u32 rgvmodectl = I915_READ(MEMMODECTL); 549 u32 rgvmodectl = I915_READ(MEMMODECTL);
550 u32 rstdbyctl = I915_READ(MCHBAR_RENDER_STANDBY);
551 u16 crstandvid = I915_READ16(CRSTANDVID);
544 552
545 seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? 553 seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
546 "yes" : "no"); 554 "yes" : "no");
@@ -555,9 +563,13 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
555 rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no"); 563 rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no");
556 seq_printf(m, "Starting frequency: P%d\n", 564 seq_printf(m, "Starting frequency: P%d\n",
557 (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT); 565 (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT);
558 seq_printf(m, "Max frequency: P%d\n", 566 seq_printf(m, "Max P-state: P%d\n",
559 (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT); 567 (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT);
560 seq_printf(m, "Min frequency: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); 568 seq_printf(m, "Min P-state: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK));
569 seq_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f));
570 seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f));
571 seq_printf(m, "Render standby enabled: %s\n",
572 (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes");
561 573
562 return 0; 574 return 0;
563} 575}
@@ -621,6 +633,36 @@ static int i915_sr_status(struct seq_file *m, void *unused)
621 return 0; 633 return 0;
622} 634}
623 635
636static int i915_emon_status(struct seq_file *m, void *unused)
637{
638 struct drm_info_node *node = (struct drm_info_node *) m->private;
639 struct drm_device *dev = node->minor->dev;
640 drm_i915_private_t *dev_priv = dev->dev_private;
641 unsigned long temp, chipset, gfx;
642
643 temp = i915_mch_val(dev_priv);
644 chipset = i915_chipset_val(dev_priv);
645 gfx = i915_gfx_val(dev_priv);
646
647 seq_printf(m, "GMCH temp: %ld\n", temp);
648 seq_printf(m, "Chipset power: %ld\n", chipset);
649 seq_printf(m, "GFX power: %ld\n", gfx);
650 seq_printf(m, "Total power: %ld\n", chipset + gfx);
651
652 return 0;
653}
654
655static int i915_gfxec(struct seq_file *m, void *unused)
656{
657 struct drm_info_node *node = (struct drm_info_node *) m->private;
658 struct drm_device *dev = node->minor->dev;
659 drm_i915_private_t *dev_priv = dev->dev_private;
660
661 seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4));
662
663 return 0;
664}
665
624static int 666static int
625i915_wedged_open(struct inode *inode, 667i915_wedged_open(struct inode *inode,
626 struct file *filp) 668 struct file *filp)
@@ -743,6 +785,8 @@ static struct drm_info_list i915_debugfs_list[] = {
743 {"i915_delayfreq_table", i915_delayfreq_table, 0}, 785 {"i915_delayfreq_table", i915_delayfreq_table, 0},
744 {"i915_inttoext_table", i915_inttoext_table, 0}, 786 {"i915_inttoext_table", i915_inttoext_table, 0},
745 {"i915_drpc_info", i915_drpc_info, 0}, 787 {"i915_drpc_info", i915_drpc_info, 0},
788 {"i915_emon_status", i915_emon_status, 0},
789 {"i915_gfxec", i915_gfxec, 0},
746 {"i915_fbc_status", i915_fbc_status, 0}, 790 {"i915_fbc_status", i915_fbc_status, 0},
747 {"i915_sr_status", i915_sr_status, 0}, 791 {"i915_sr_status", i915_sr_status, 0},
748}; 792};
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 2a6b5de5ae5d..b2ebf02e4f8a 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -40,84 +40,6 @@
40#include <linux/vga_switcheroo.h> 40#include <linux/vga_switcheroo.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42 42
43/* Really want an OS-independent resettable timer. Would like to have
44 * this loop run for (eg) 3 sec, but have the timer reset every time
45 * the head pointer changes, so that EBUSY only happens if the ring
46 * actually stalls for (eg) 3 seconds.
47 */
48int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
49{
50 drm_i915_private_t *dev_priv = dev->dev_private;
51 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
52 u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
53 u32 last_acthd = I915_READ(acthd_reg);
54 u32 acthd;
55 u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
56 int i;
57
58 trace_i915_ring_wait_begin (dev);
59
60 for (i = 0; i < 100000; i++) {
61 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
62 acthd = I915_READ(acthd_reg);
63 ring->space = ring->head - (ring->tail + 8);
64 if (ring->space < 0)
65 ring->space += ring->Size;
66 if (ring->space >= n) {
67 trace_i915_ring_wait_end (dev);
68 return 0;
69 }
70
71 if (dev->primary->master) {
72 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
73 if (master_priv->sarea_priv)
74 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
75 }
76
77
78 if (ring->head != last_head)
79 i = 0;
80 if (acthd != last_acthd)
81 i = 0;
82
83 last_head = ring->head;
84 last_acthd = acthd;
85 msleep_interruptible(10);
86
87 }
88
89 trace_i915_ring_wait_end (dev);
90 return -EBUSY;
91}
92
93/* As a ringbuffer is only allowed to wrap between instructions, fill
94 * the tail with NOOPs.
95 */
96int i915_wrap_ring(struct drm_device *dev)
97{
98 drm_i915_private_t *dev_priv = dev->dev_private;
99 volatile unsigned int *virt;
100 int rem;
101
102 rem = dev_priv->ring.Size - dev_priv->ring.tail;
103 if (dev_priv->ring.space < rem) {
104 int ret = i915_wait_ring(dev, rem, __func__);
105 if (ret)
106 return ret;
107 }
108 dev_priv->ring.space -= rem;
109
110 virt = (unsigned int *)
111 (dev_priv->ring.virtual_start + dev_priv->ring.tail);
112 rem /= 4;
113 while (rem--)
114 *virt++ = MI_NOOP;
115
116 dev_priv->ring.tail = 0;
117
118 return 0;
119}
120
121/** 43/**
122 * Sets up the hardware status page for devices that need a physical address 44 * Sets up the hardware status page for devices that need a physical address
123 * in the register. 45 * in the register.
@@ -133,10 +55,11 @@ static int i915_init_phys_hws(struct drm_device *dev)
133 DRM_ERROR("Can not allocate hardware status page\n"); 55 DRM_ERROR("Can not allocate hardware status page\n");
134 return -ENOMEM; 56 return -ENOMEM;
135 } 57 }
136 dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; 58 dev_priv->render_ring.status_page.page_addr
59 = dev_priv->status_page_dmah->vaddr;
137 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; 60 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
138 61
139 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 62 memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE);
140 63
141 if (IS_I965G(dev)) 64 if (IS_I965G(dev))
142 dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & 65 dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) &
@@ -159,8 +82,8 @@ static void i915_free_hws(struct drm_device *dev)
159 dev_priv->status_page_dmah = NULL; 82 dev_priv->status_page_dmah = NULL;
160 } 83 }
161 84
162 if (dev_priv->status_gfx_addr) { 85 if (dev_priv->render_ring.status_page.gfx_addr) {
163 dev_priv->status_gfx_addr = 0; 86 dev_priv->render_ring.status_page.gfx_addr = 0;
164 drm_core_ioremapfree(&dev_priv->hws_map, dev); 87 drm_core_ioremapfree(&dev_priv->hws_map, dev);
165 } 88 }
166 89
@@ -172,7 +95,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
172{ 95{
173 drm_i915_private_t *dev_priv = dev->dev_private; 96 drm_i915_private_t *dev_priv = dev->dev_private;
174 struct drm_i915_master_private *master_priv; 97 struct drm_i915_master_private *master_priv;
175 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 98 struct intel_ring_buffer *ring = &dev_priv->render_ring;
176 99
177 /* 100 /*
178 * We should never lose context on the ring with modesetting 101 * We should never lose context on the ring with modesetting
@@ -185,7 +108,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
185 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; 108 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
186 ring->space = ring->head - (ring->tail + 8); 109 ring->space = ring->head - (ring->tail + 8);
187 if (ring->space < 0) 110 if (ring->space < 0)
188 ring->space += ring->Size; 111 ring->space += ring->size;
189 112
190 if (!dev->primary->master) 113 if (!dev->primary->master)
191 return; 114 return;
@@ -205,12 +128,9 @@ static int i915_dma_cleanup(struct drm_device * dev)
205 if (dev->irq_enabled) 128 if (dev->irq_enabled)
206 drm_irq_uninstall(dev); 129 drm_irq_uninstall(dev);
207 130
208 if (dev_priv->ring.virtual_start) { 131 intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
209 drm_core_ioremapfree(&dev_priv->ring.map, dev); 132 if (HAS_BSD(dev))
210 dev_priv->ring.virtual_start = NULL; 133 intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
211 dev_priv->ring.map.handle = NULL;
212 dev_priv->ring.map.size = 0;
213 }
214 134
215 /* Clear the HWS virtual address at teardown */ 135 /* Clear the HWS virtual address at teardown */
216 if (I915_NEED_GFX_HWS(dev)) 136 if (I915_NEED_GFX_HWS(dev))
@@ -233,24 +153,24 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
233 } 153 }
234 154
235 if (init->ring_size != 0) { 155 if (init->ring_size != 0) {
236 if (dev_priv->ring.ring_obj != NULL) { 156 if (dev_priv->render_ring.gem_object != NULL) {
237 i915_dma_cleanup(dev); 157 i915_dma_cleanup(dev);
238 DRM_ERROR("Client tried to initialize ringbuffer in " 158 DRM_ERROR("Client tried to initialize ringbuffer in "
239 "GEM mode\n"); 159 "GEM mode\n");
240 return -EINVAL; 160 return -EINVAL;
241 } 161 }
242 162
243 dev_priv->ring.Size = init->ring_size; 163 dev_priv->render_ring.size = init->ring_size;
244 164
245 dev_priv->ring.map.offset = init->ring_start; 165 dev_priv->render_ring.map.offset = init->ring_start;
246 dev_priv->ring.map.size = init->ring_size; 166 dev_priv->render_ring.map.size = init->ring_size;
247 dev_priv->ring.map.type = 0; 167 dev_priv->render_ring.map.type = 0;
248 dev_priv->ring.map.flags = 0; 168 dev_priv->render_ring.map.flags = 0;
249 dev_priv->ring.map.mtrr = 0; 169 dev_priv->render_ring.map.mtrr = 0;
250 170
251 drm_core_ioremap_wc(&dev_priv->ring.map, dev); 171 drm_core_ioremap_wc(&dev_priv->render_ring.map, dev);
252 172
253 if (dev_priv->ring.map.handle == NULL) { 173 if (dev_priv->render_ring.map.handle == NULL) {
254 i915_dma_cleanup(dev); 174 i915_dma_cleanup(dev);
255 DRM_ERROR("can not ioremap virtual address for" 175 DRM_ERROR("can not ioremap virtual address for"
256 " ring buffer\n"); 176 " ring buffer\n");
@@ -258,7 +178,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
258 } 178 }
259 } 179 }
260 180
261 dev_priv->ring.virtual_start = dev_priv->ring.map.handle; 181 dev_priv->render_ring.virtual_start = dev_priv->render_ring.map.handle;
262 182
263 dev_priv->cpp = init->cpp; 183 dev_priv->cpp = init->cpp;
264 dev_priv->back_offset = init->back_offset; 184 dev_priv->back_offset = init->back_offset;
@@ -278,26 +198,29 @@ static int i915_dma_resume(struct drm_device * dev)
278{ 198{
279 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 199 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
280 200
201 struct intel_ring_buffer *ring;
281 DRM_DEBUG_DRIVER("%s\n", __func__); 202 DRM_DEBUG_DRIVER("%s\n", __func__);
282 203
283 if (dev_priv->ring.map.handle == NULL) { 204 ring = &dev_priv->render_ring;
205
206 if (ring->map.handle == NULL) {
284 DRM_ERROR("can not ioremap virtual address for" 207 DRM_ERROR("can not ioremap virtual address for"
285 " ring buffer\n"); 208 " ring buffer\n");
286 return -ENOMEM; 209 return -ENOMEM;
287 } 210 }
288 211
289 /* Program Hardware Status Page */ 212 /* Program Hardware Status Page */
290 if (!dev_priv->hw_status_page) { 213 if (!ring->status_page.page_addr) {
291 DRM_ERROR("Can not find hardware status page\n"); 214 DRM_ERROR("Can not find hardware status page\n");
292 return -EINVAL; 215 return -EINVAL;
293 } 216 }
294 DRM_DEBUG_DRIVER("hw status page @ %p\n", 217 DRM_DEBUG_DRIVER("hw status page @ %p\n",
295 dev_priv->hw_status_page); 218 ring->status_page.page_addr);
296 219 if (ring->status_page.gfx_addr != 0)
297 if (dev_priv->status_gfx_addr != 0) 220 ring->setup_status_page(dev, ring);
298 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
299 else 221 else
300 I915_WRITE(HWS_PGA, dev_priv->dma_status_page); 222 I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
223
301 DRM_DEBUG_DRIVER("Enabled hardware status page\n"); 224 DRM_DEBUG_DRIVER("Enabled hardware status page\n");
302 225
303 return 0; 226 return 0;
@@ -407,9 +330,8 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
407{ 330{
408 drm_i915_private_t *dev_priv = dev->dev_private; 331 drm_i915_private_t *dev_priv = dev->dev_private;
409 int i; 332 int i;
410 RING_LOCALS;
411 333
412 if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) 334 if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8)
413 return -EINVAL; 335 return -EINVAL;
414 336
415 BEGIN_LP_RING((dwords+1)&~1); 337 BEGIN_LP_RING((dwords+1)&~1);
@@ -442,9 +364,7 @@ i915_emit_box(struct drm_device *dev,
442 struct drm_clip_rect *boxes, 364 struct drm_clip_rect *boxes,
443 int i, int DR1, int DR4) 365 int i, int DR1, int DR4)
444{ 366{
445 drm_i915_private_t *dev_priv = dev->dev_private;
446 struct drm_clip_rect box = boxes[i]; 367 struct drm_clip_rect box = boxes[i];
447 RING_LOCALS;
448 368
449 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { 369 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
450 DRM_ERROR("Bad box %d,%d..%d,%d\n", 370 DRM_ERROR("Bad box %d,%d..%d,%d\n",
@@ -481,7 +401,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
481{ 401{
482 drm_i915_private_t *dev_priv = dev->dev_private; 402 drm_i915_private_t *dev_priv = dev->dev_private;
483 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 403 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
484 RING_LOCALS;
485 404
486 dev_priv->counter++; 405 dev_priv->counter++;
487 if (dev_priv->counter > 0x7FFFFFFFUL) 406 if (dev_priv->counter > 0x7FFFFFFFUL)
@@ -535,10 +454,8 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
535 drm_i915_batchbuffer_t * batch, 454 drm_i915_batchbuffer_t * batch,
536 struct drm_clip_rect *cliprects) 455 struct drm_clip_rect *cliprects)
537{ 456{
538 drm_i915_private_t *dev_priv = dev->dev_private;
539 int nbox = batch->num_cliprects; 457 int nbox = batch->num_cliprects;
540 int i = 0, count; 458 int i = 0, count;
541 RING_LOCALS;
542 459
543 if ((batch->start | batch->used) & 0x7) { 460 if ((batch->start | batch->used) & 0x7) {
544 DRM_ERROR("alignment"); 461 DRM_ERROR("alignment");
@@ -587,7 +504,6 @@ static int i915_dispatch_flip(struct drm_device * dev)
587 drm_i915_private_t *dev_priv = dev->dev_private; 504 drm_i915_private_t *dev_priv = dev->dev_private;
588 struct drm_i915_master_private *master_priv = 505 struct drm_i915_master_private *master_priv =
589 dev->primary->master->driver_priv; 506 dev->primary->master->driver_priv;
590 RING_LOCALS;
591 507
592 if (!master_priv->sarea_priv) 508 if (!master_priv->sarea_priv)
593 return -EINVAL; 509 return -EINVAL;
@@ -640,7 +556,8 @@ static int i915_quiescent(struct drm_device * dev)
640 drm_i915_private_t *dev_priv = dev->dev_private; 556 drm_i915_private_t *dev_priv = dev->dev_private;
641 557
642 i915_kernel_lost_context(dev); 558 i915_kernel_lost_context(dev);
643 return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); 559 return intel_wait_ring_buffer(dev, &dev_priv->render_ring,
560 dev_priv->render_ring.size - 8);
644} 561}
645 562
646static int i915_flush_ioctl(struct drm_device *dev, void *data, 563static int i915_flush_ioctl(struct drm_device *dev, void *data,
@@ -827,6 +744,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
827 /* depends on GEM */ 744 /* depends on GEM */
828 value = dev_priv->has_gem; 745 value = dev_priv->has_gem;
829 break; 746 break;
747 case I915_PARAM_HAS_BSD:
748 value = HAS_BSD(dev);
749 break;
830 default: 750 default:
831 DRM_DEBUG_DRIVER("Unknown parameter %d\n", 751 DRM_DEBUG_DRIVER("Unknown parameter %d\n",
832 param->param); 752 param->param);
@@ -882,6 +802,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
882{ 802{
883 drm_i915_private_t *dev_priv = dev->dev_private; 803 drm_i915_private_t *dev_priv = dev->dev_private;
884 drm_i915_hws_addr_t *hws = data; 804 drm_i915_hws_addr_t *hws = data;
805 struct intel_ring_buffer *ring = &dev_priv->render_ring;
885 806
886 if (!I915_NEED_GFX_HWS(dev)) 807 if (!I915_NEED_GFX_HWS(dev))
887 return -EINVAL; 808 return -EINVAL;
@@ -898,7 +819,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
898 819
899 DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); 820 DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr);
900 821
901 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); 822 ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12);
902 823
903 dev_priv->hws_map.offset = dev->agp->base + hws->addr; 824 dev_priv->hws_map.offset = dev->agp->base + hws->addr;
904 dev_priv->hws_map.size = 4*1024; 825 dev_priv->hws_map.size = 4*1024;
@@ -909,19 +830,19 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
909 drm_core_ioremap_wc(&dev_priv->hws_map, dev); 830 drm_core_ioremap_wc(&dev_priv->hws_map, dev);
910 if (dev_priv->hws_map.handle == NULL) { 831 if (dev_priv->hws_map.handle == NULL) {
911 i915_dma_cleanup(dev); 832 i915_dma_cleanup(dev);
912 dev_priv->status_gfx_addr = 0; 833 ring->status_page.gfx_addr = 0;
913 DRM_ERROR("can not ioremap virtual address for" 834 DRM_ERROR("can not ioremap virtual address for"
914 " G33 hw status page\n"); 835 " G33 hw status page\n");
915 return -ENOMEM; 836 return -ENOMEM;
916 } 837 }
917 dev_priv->hw_status_page = dev_priv->hws_map.handle; 838 ring->status_page.page_addr = dev_priv->hws_map.handle;
839 memset(ring->status_page.page_addr, 0, PAGE_SIZE);
840 I915_WRITE(HWS_PGA, ring->status_page.gfx_addr);
918 841
919 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
920 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
921 DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", 842 DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n",
922 dev_priv->status_gfx_addr); 843 ring->status_page.gfx_addr);
923 DRM_DEBUG_DRIVER("load hws at %p\n", 844 DRM_DEBUG_DRIVER("load hws at %p\n",
924 dev_priv->hw_status_page); 845 ring->status_page.page_addr);
925 return 0; 846 return 0;
926} 847}
927 848
@@ -1399,12 +1320,14 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
1399 struct drm_device *dev = pci_get_drvdata(pdev); 1320 struct drm_device *dev = pci_get_drvdata(pdev);
1400 pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; 1321 pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
1401 if (state == VGA_SWITCHEROO_ON) { 1322 if (state == VGA_SWITCHEROO_ON) {
1402 printk(KERN_INFO "i915: switched off\n"); 1323 printk(KERN_INFO "i915: switched on\n");
1403 /* i915 resume handler doesn't set to D0 */ 1324 /* i915 resume handler doesn't set to D0 */
1404 pci_set_power_state(dev->pdev, PCI_D0); 1325 pci_set_power_state(dev->pdev, PCI_D0);
1405 i915_resume(dev); 1326 i915_resume(dev);
1327 drm_kms_helper_poll_enable(dev);
1406 } else { 1328 } else {
1407 printk(KERN_ERR "i915: switched off\n"); 1329 printk(KERN_ERR "i915: switched off\n");
1330 drm_kms_helper_poll_disable(dev);
1408 i915_suspend(dev, pmm); 1331 i915_suspend(dev, pmm);
1409 } 1332 }
1410} 1333}
@@ -1539,14 +1462,11 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
1539 master->driver_priv = NULL; 1462 master->driver_priv = NULL;
1540} 1463}
1541 1464
1542static void i915_get_mem_freq(struct drm_device *dev) 1465static void i915_pineview_get_mem_freq(struct drm_device *dev)
1543{ 1466{
1544 drm_i915_private_t *dev_priv = dev->dev_private; 1467 drm_i915_private_t *dev_priv = dev->dev_private;
1545 u32 tmp; 1468 u32 tmp;
1546 1469
1547 if (!IS_PINEVIEW(dev))
1548 return;
1549
1550 tmp = I915_READ(CLKCFG); 1470 tmp = I915_READ(CLKCFG);
1551 1471
1552 switch (tmp & CLKCFG_FSB_MASK) { 1472 switch (tmp & CLKCFG_FSB_MASK) {
@@ -1575,8 +1495,525 @@ static void i915_get_mem_freq(struct drm_device *dev)
1575 dev_priv->mem_freq = 800; 1495 dev_priv->mem_freq = 800;
1576 break; 1496 break;
1577 } 1497 }
1498
1499 /* detect pineview DDR3 setting */
1500 tmp = I915_READ(CSHRDDR3CTL);
1501 dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0;
1502}
1503
1504static void i915_ironlake_get_mem_freq(struct drm_device *dev)
1505{
1506 drm_i915_private_t *dev_priv = dev->dev_private;
1507 u16 ddrpll, csipll;
1508
1509 ddrpll = I915_READ16(DDRMPLL1);
1510 csipll = I915_READ16(CSIPLL0);
1511
1512 switch (ddrpll & 0xff) {
1513 case 0xc:
1514 dev_priv->mem_freq = 800;
1515 break;
1516 case 0x10:
1517 dev_priv->mem_freq = 1066;
1518 break;
1519 case 0x14:
1520 dev_priv->mem_freq = 1333;
1521 break;
1522 case 0x18:
1523 dev_priv->mem_freq = 1600;
1524 break;
1525 default:
1526 DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n",
1527 ddrpll & 0xff);
1528 dev_priv->mem_freq = 0;
1529 break;
1530 }
1531
1532 dev_priv->r_t = dev_priv->mem_freq;
1533
1534 switch (csipll & 0x3ff) {
1535 case 0x00c:
1536 dev_priv->fsb_freq = 3200;
1537 break;
1538 case 0x00e:
1539 dev_priv->fsb_freq = 3733;
1540 break;
1541 case 0x010:
1542 dev_priv->fsb_freq = 4266;
1543 break;
1544 case 0x012:
1545 dev_priv->fsb_freq = 4800;
1546 break;
1547 case 0x014:
1548 dev_priv->fsb_freq = 5333;
1549 break;
1550 case 0x016:
1551 dev_priv->fsb_freq = 5866;
1552 break;
1553 case 0x018:
1554 dev_priv->fsb_freq = 6400;
1555 break;
1556 default:
1557 DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n",
1558 csipll & 0x3ff);
1559 dev_priv->fsb_freq = 0;
1560 break;
1561 }
1562
1563 if (dev_priv->fsb_freq == 3200) {
1564 dev_priv->c_m = 0;
1565 } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) {
1566 dev_priv->c_m = 1;
1567 } else {
1568 dev_priv->c_m = 2;
1569 }
1570}
1571
1572struct v_table {
1573 u8 vid;
1574 unsigned long vd; /* in .1 mil */
1575 unsigned long vm; /* in .1 mil */
1576 u8 pvid;
1577};
1578
1579static struct v_table v_table[] = {
1580 { 0, 16125, 15000, 0x7f, },
1581 { 1, 16000, 14875, 0x7e, },
1582 { 2, 15875, 14750, 0x7d, },
1583 { 3, 15750, 14625, 0x7c, },
1584 { 4, 15625, 14500, 0x7b, },
1585 { 5, 15500, 14375, 0x7a, },
1586 { 6, 15375, 14250, 0x79, },
1587 { 7, 15250, 14125, 0x78, },
1588 { 8, 15125, 14000, 0x77, },
1589 { 9, 15000, 13875, 0x76, },
1590 { 10, 14875, 13750, 0x75, },
1591 { 11, 14750, 13625, 0x74, },
1592 { 12, 14625, 13500, 0x73, },
1593 { 13, 14500, 13375, 0x72, },
1594 { 14, 14375, 13250, 0x71, },
1595 { 15, 14250, 13125, 0x70, },
1596 { 16, 14125, 13000, 0x6f, },
1597 { 17, 14000, 12875, 0x6e, },
1598 { 18, 13875, 12750, 0x6d, },
1599 { 19, 13750, 12625, 0x6c, },
1600 { 20, 13625, 12500, 0x6b, },
1601 { 21, 13500, 12375, 0x6a, },
1602 { 22, 13375, 12250, 0x69, },
1603 { 23, 13250, 12125, 0x68, },
1604 { 24, 13125, 12000, 0x67, },
1605 { 25, 13000, 11875, 0x66, },
1606 { 26, 12875, 11750, 0x65, },
1607 { 27, 12750, 11625, 0x64, },
1608 { 28, 12625, 11500, 0x63, },
1609 { 29, 12500, 11375, 0x62, },
1610 { 30, 12375, 11250, 0x61, },
1611 { 31, 12250, 11125, 0x60, },
1612 { 32, 12125, 11000, 0x5f, },
1613 { 33, 12000, 10875, 0x5e, },
1614 { 34, 11875, 10750, 0x5d, },
1615 { 35, 11750, 10625, 0x5c, },
1616 { 36, 11625, 10500, 0x5b, },
1617 { 37, 11500, 10375, 0x5a, },
1618 { 38, 11375, 10250, 0x59, },
1619 { 39, 11250, 10125, 0x58, },
1620 { 40, 11125, 10000, 0x57, },
1621 { 41, 11000, 9875, 0x56, },
1622 { 42, 10875, 9750, 0x55, },
1623 { 43, 10750, 9625, 0x54, },
1624 { 44, 10625, 9500, 0x53, },
1625 { 45, 10500, 9375, 0x52, },
1626 { 46, 10375, 9250, 0x51, },
1627 { 47, 10250, 9125, 0x50, },
1628 { 48, 10125, 9000, 0x4f, },
1629 { 49, 10000, 8875, 0x4e, },
1630 { 50, 9875, 8750, 0x4d, },
1631 { 51, 9750, 8625, 0x4c, },
1632 { 52, 9625, 8500, 0x4b, },
1633 { 53, 9500, 8375, 0x4a, },
1634 { 54, 9375, 8250, 0x49, },
1635 { 55, 9250, 8125, 0x48, },
1636 { 56, 9125, 8000, 0x47, },
1637 { 57, 9000, 7875, 0x46, },
1638 { 58, 8875, 7750, 0x45, },
1639 { 59, 8750, 7625, 0x44, },
1640 { 60, 8625, 7500, 0x43, },
1641 { 61, 8500, 7375, 0x42, },
1642 { 62, 8375, 7250, 0x41, },
1643 { 63, 8250, 7125, 0x40, },
1644 { 64, 8125, 7000, 0x3f, },
1645 { 65, 8000, 6875, 0x3e, },
1646 { 66, 7875, 6750, 0x3d, },
1647 { 67, 7750, 6625, 0x3c, },
1648 { 68, 7625, 6500, 0x3b, },
1649 { 69, 7500, 6375, 0x3a, },
1650 { 70, 7375, 6250, 0x39, },
1651 { 71, 7250, 6125, 0x38, },
1652 { 72, 7125, 6000, 0x37, },
1653 { 73, 7000, 5875, 0x36, },
1654 { 74, 6875, 5750, 0x35, },
1655 { 75, 6750, 5625, 0x34, },
1656 { 76, 6625, 5500, 0x33, },
1657 { 77, 6500, 5375, 0x32, },
1658 { 78, 6375, 5250, 0x31, },
1659 { 79, 6250, 5125, 0x30, },
1660 { 80, 6125, 5000, 0x2f, },
1661 { 81, 6000, 4875, 0x2e, },
1662 { 82, 5875, 4750, 0x2d, },
1663 { 83, 5750, 4625, 0x2c, },
1664 { 84, 5625, 4500, 0x2b, },
1665 { 85, 5500, 4375, 0x2a, },
1666 { 86, 5375, 4250, 0x29, },
1667 { 87, 5250, 4125, 0x28, },
1668 { 88, 5125, 4000, 0x27, },
1669 { 89, 5000, 3875, 0x26, },
1670 { 90, 4875, 3750, 0x25, },
1671 { 91, 4750, 3625, 0x24, },
1672 { 92, 4625, 3500, 0x23, },
1673 { 93, 4500, 3375, 0x22, },
1674 { 94, 4375, 3250, 0x21, },
1675 { 95, 4250, 3125, 0x20, },
1676 { 96, 4125, 3000, 0x1f, },
1677 { 97, 4125, 3000, 0x1e, },
1678 { 98, 4125, 3000, 0x1d, },
1679 { 99, 4125, 3000, 0x1c, },
1680 { 100, 4125, 3000, 0x1b, },
1681 { 101, 4125, 3000, 0x1a, },
1682 { 102, 4125, 3000, 0x19, },
1683 { 103, 4125, 3000, 0x18, },
1684 { 104, 4125, 3000, 0x17, },
1685 { 105, 4125, 3000, 0x16, },
1686 { 106, 4125, 3000, 0x15, },
1687 { 107, 4125, 3000, 0x14, },
1688 { 108, 4125, 3000, 0x13, },
1689 { 109, 4125, 3000, 0x12, },
1690 { 110, 4125, 3000, 0x11, },
1691 { 111, 4125, 3000, 0x10, },
1692 { 112, 4125, 3000, 0x0f, },
1693 { 113, 4125, 3000, 0x0e, },
1694 { 114, 4125, 3000, 0x0d, },
1695 { 115, 4125, 3000, 0x0c, },
1696 { 116, 4125, 3000, 0x0b, },
1697 { 117, 4125, 3000, 0x0a, },
1698 { 118, 4125, 3000, 0x09, },
1699 { 119, 4125, 3000, 0x08, },
1700 { 120, 1125, 0, 0x07, },
1701 { 121, 1000, 0, 0x06, },
1702 { 122, 875, 0, 0x05, },
1703 { 123, 750, 0, 0x04, },
1704 { 124, 625, 0, 0x03, },
1705 { 125, 500, 0, 0x02, },
1706 { 126, 375, 0, 0x01, },
1707 { 127, 0, 0, 0x00, },
1708};
1709
1710struct cparams {
1711 int i;
1712 int t;
1713 int m;
1714 int c;
1715};
1716
1717static struct cparams cparams[] = {
1718 { 1, 1333, 301, 28664 },
1719 { 1, 1066, 294, 24460 },
1720 { 1, 800, 294, 25192 },
1721 { 0, 1333, 276, 27605 },
1722 { 0, 1066, 276, 27605 },
1723 { 0, 800, 231, 23784 },
1724};
1725
1726unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
1727{
1728 u64 total_count, diff, ret;
1729 u32 count1, count2, count3, m = 0, c = 0;
1730 unsigned long now = jiffies_to_msecs(jiffies), diff1;
1731 int i;
1732
1733 diff1 = now - dev_priv->last_time1;
1734
1735 count1 = I915_READ(DMIEC);
1736 count2 = I915_READ(DDREC);
1737 count3 = I915_READ(CSIEC);
1738
1739 total_count = count1 + count2 + count3;
1740
1741 /* FIXME: handle per-counter overflow */
1742 if (total_count < dev_priv->last_count1) {
1743 diff = ~0UL - dev_priv->last_count1;
1744 diff += total_count;
1745 } else {
1746 diff = total_count - dev_priv->last_count1;
1747 }
1748
1749 for (i = 0; i < ARRAY_SIZE(cparams); i++) {
1750 if (cparams[i].i == dev_priv->c_m &&
1751 cparams[i].t == dev_priv->r_t) {
1752 m = cparams[i].m;
1753 c = cparams[i].c;
1754 break;
1755 }
1756 }
1757
1758 div_u64(diff, diff1);
1759 ret = ((m * diff) + c);
1760 div_u64(ret, 10);
1761
1762 dev_priv->last_count1 = total_count;
1763 dev_priv->last_time1 = now;
1764
1765 return ret;
1766}
1767
1768unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
1769{
1770 unsigned long m, x, b;
1771 u32 tsfs;
1772
1773 tsfs = I915_READ(TSFS);
1774
1775 m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT);
1776 x = I915_READ8(TR1);
1777
1778 b = tsfs & TSFS_INTR_MASK;
1779
1780 return ((m * x) / 127) - b;
1781}
1782
1783static unsigned long pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
1784{
1785 unsigned long val = 0;
1786 int i;
1787
1788 for (i = 0; i < ARRAY_SIZE(v_table); i++) {
1789 if (v_table[i].pvid == pxvid) {
1790 if (IS_MOBILE(dev_priv->dev))
1791 val = v_table[i].vm;
1792 else
1793 val = v_table[i].vd;
1794 }
1795 }
1796
1797 return val;
1798}
1799
1800void i915_update_gfx_val(struct drm_i915_private *dev_priv)
1801{
1802 struct timespec now, diff1;
1803 u64 diff;
1804 unsigned long diffms;
1805 u32 count;
1806
1807 getrawmonotonic(&now);
1808 diff1 = timespec_sub(now, dev_priv->last_time2);
1809
1810 /* Don't divide by 0 */
1811 diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000;
1812 if (!diffms)
1813 return;
1814
1815 count = I915_READ(GFXEC);
1816
1817 if (count < dev_priv->last_count2) {
1818 diff = ~0UL - dev_priv->last_count2;
1819 diff += count;
1820 } else {
1821 diff = count - dev_priv->last_count2;
1822 }
1823
1824 dev_priv->last_count2 = count;
1825 dev_priv->last_time2 = now;
1826
1827 /* More magic constants... */
1828 diff = diff * 1181;
1829 div_u64(diff, diffms * 10);
1830 dev_priv->gfx_power = diff;
1578} 1831}
1579 1832
1833unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
1834{
1835 unsigned long t, corr, state1, corr2, state2;
1836 u32 pxvid, ext_v;
1837
1838 pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4));
1839 pxvid = (pxvid >> 24) & 0x7f;
1840 ext_v = pvid_to_extvid(dev_priv, pxvid);
1841
1842 state1 = ext_v;
1843
1844 t = i915_mch_val(dev_priv);
1845
1846 /* Revel in the empirically derived constants */
1847
1848 /* Correction factor in 1/100000 units */
1849 if (t > 80)
1850 corr = ((t * 2349) + 135940);
1851 else if (t >= 50)
1852 corr = ((t * 964) + 29317);
1853 else /* < 50 */
1854 corr = ((t * 301) + 1004);
1855
1856 corr = corr * ((150142 * state1) / 10000 - 78642);
1857 corr /= 100000;
1858 corr2 = (corr * dev_priv->corr);
1859
1860 state2 = (corr2 * state1) / 10000;
1861 state2 /= 100; /* convert to mW */
1862
1863 i915_update_gfx_val(dev_priv);
1864
1865 return dev_priv->gfx_power + state2;
1866}
1867
1868/* Global for IPS driver to get at the current i915 device */
1869static struct drm_i915_private *i915_mch_dev;
1870/*
1871 * Lock protecting IPS related data structures
1872 * - i915_mch_dev
1873 * - dev_priv->max_delay
1874 * - dev_priv->min_delay
1875 * - dev_priv->fmax
1876 * - dev_priv->gpu_busy
1877 */
1878DEFINE_SPINLOCK(mchdev_lock);
1879
1880/**
1881 * i915_read_mch_val - return value for IPS use
1882 *
1883 * Calculate and return a value for the IPS driver to use when deciding whether
1884 * we have thermal and power headroom to increase CPU or GPU power budget.
1885 */
1886unsigned long i915_read_mch_val(void)
1887{
1888 struct drm_i915_private *dev_priv;
1889 unsigned long chipset_val, graphics_val, ret = 0;
1890
1891 spin_lock(&mchdev_lock);
1892 if (!i915_mch_dev)
1893 goto out_unlock;
1894 dev_priv = i915_mch_dev;
1895
1896 chipset_val = i915_chipset_val(dev_priv);
1897 graphics_val = i915_gfx_val(dev_priv);
1898
1899 ret = chipset_val + graphics_val;
1900
1901out_unlock:
1902 spin_unlock(&mchdev_lock);
1903
1904 return ret;
1905}
1906EXPORT_SYMBOL_GPL(i915_read_mch_val);
1907
1908/**
1909 * i915_gpu_raise - raise GPU frequency limit
1910 *
1911 * Raise the limit; IPS indicates we have thermal headroom.
1912 */
1913bool i915_gpu_raise(void)
1914{
1915 struct drm_i915_private *dev_priv;
1916 bool ret = true;
1917
1918 spin_lock(&mchdev_lock);
1919 if (!i915_mch_dev) {
1920 ret = false;
1921 goto out_unlock;
1922 }
1923 dev_priv = i915_mch_dev;
1924
1925 if (dev_priv->max_delay > dev_priv->fmax)
1926 dev_priv->max_delay--;
1927
1928out_unlock:
1929 spin_unlock(&mchdev_lock);
1930
1931 return ret;
1932}
1933EXPORT_SYMBOL_GPL(i915_gpu_raise);
1934
1935/**
1936 * i915_gpu_lower - lower GPU frequency limit
1937 *
1938 * IPS indicates we're close to a thermal limit, so throttle back the GPU
1939 * frequency maximum.
1940 */
1941bool i915_gpu_lower(void)
1942{
1943 struct drm_i915_private *dev_priv;
1944 bool ret = true;
1945
1946 spin_lock(&mchdev_lock);
1947 if (!i915_mch_dev) {
1948 ret = false;
1949 goto out_unlock;
1950 }
1951 dev_priv = i915_mch_dev;
1952
1953 if (dev_priv->max_delay < dev_priv->min_delay)
1954 dev_priv->max_delay++;
1955
1956out_unlock:
1957 spin_unlock(&mchdev_lock);
1958
1959 return ret;
1960}
1961EXPORT_SYMBOL_GPL(i915_gpu_lower);
1962
1963/**
1964 * i915_gpu_busy - indicate GPU business to IPS
1965 *
1966 * Tell the IPS driver whether or not the GPU is busy.
1967 */
1968bool i915_gpu_busy(void)
1969{
1970 struct drm_i915_private *dev_priv;
1971 bool ret = false;
1972
1973 spin_lock(&mchdev_lock);
1974 if (!i915_mch_dev)
1975 goto out_unlock;
1976 dev_priv = i915_mch_dev;
1977
1978 ret = dev_priv->busy;
1979
1980out_unlock:
1981 spin_unlock(&mchdev_lock);
1982
1983 return ret;
1984}
1985EXPORT_SYMBOL_GPL(i915_gpu_busy);
1986
1987/**
1988 * i915_gpu_turbo_disable - disable graphics turbo
1989 *
1990 * Disable graphics turbo by resetting the max frequency and setting the
1991 * current frequency to the default.
1992 */
1993bool i915_gpu_turbo_disable(void)
1994{
1995 struct drm_i915_private *dev_priv;
1996 bool ret = true;
1997
1998 spin_lock(&mchdev_lock);
1999 if (!i915_mch_dev) {
2000 ret = false;
2001 goto out_unlock;
2002 }
2003 dev_priv = i915_mch_dev;
2004
2005 dev_priv->max_delay = dev_priv->fstart;
2006
2007 if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart))
2008 ret = false;
2009
2010out_unlock:
2011 spin_unlock(&mchdev_lock);
2012
2013 return ret;
2014}
2015EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
2016
1580/** 2017/**
1581 * i915_driver_load - setup chip and create an initial config 2018 * i915_driver_load - setup chip and create an initial config
1582 * @dev: DRM device 2019 * @dev: DRM device
@@ -1594,7 +2031,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1594 resource_size_t base, size; 2031 resource_size_t base, size;
1595 int ret = 0, mmio_bar; 2032 int ret = 0, mmio_bar;
1596 uint32_t agp_size, prealloc_size, prealloc_start; 2033 uint32_t agp_size, prealloc_size, prealloc_start;
1597
1598 /* i915 has 4 more counters */ 2034 /* i915 has 4 more counters */
1599 dev->counters += 4; 2035 dev->counters += 4;
1600 dev->types[6] = _DRM_STAT_IRQ; 2036 dev->types[6] = _DRM_STAT_IRQ;
@@ -1672,6 +2108,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1672 dev_priv->has_gem = 0; 2108 dev_priv->has_gem = 0;
1673 } 2109 }
1674 2110
2111 if (dev_priv->has_gem == 0 &&
2112 drm_core_check_feature(dev, DRIVER_MODESET)) {
2113 DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n");
2114 ret = -ENODEV;
2115 goto out_iomapfree;
2116 }
2117
1675 dev->driver->get_vblank_counter = i915_get_vblank_counter; 2118 dev->driver->get_vblank_counter = i915_get_vblank_counter;
1676 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 2119 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
1677 if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) { 2120 if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) {
@@ -1691,7 +2134,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1691 goto out_workqueue_free; 2134 goto out_workqueue_free;
1692 } 2135 }
1693 2136
1694 i915_get_mem_freq(dev); 2137 if (IS_PINEVIEW(dev))
2138 i915_pineview_get_mem_freq(dev);
2139 else if (IS_IRONLAKE(dev))
2140 i915_ironlake_get_mem_freq(dev);
1695 2141
1696 /* On the 945G/GM, the chipset reports the MSI capability on the 2142 /* On the 945G/GM, the chipset reports the MSI capability on the
1697 * integrated graphics even though the support isn't actually there 2143 * integrated graphics even though the support isn't actually there
@@ -1709,7 +2155,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1709 2155
1710 spin_lock_init(&dev_priv->user_irq_lock); 2156 spin_lock_init(&dev_priv->user_irq_lock);
1711 spin_lock_init(&dev_priv->error_lock); 2157 spin_lock_init(&dev_priv->error_lock);
1712 dev_priv->user_irq_refcount = 0;
1713 dev_priv->trace_irq_seqno = 0; 2158 dev_priv->trace_irq_seqno = 0;
1714 2159
1715 ret = drm_vblank_init(dev, I915_NUM_PIPE); 2160 ret = drm_vblank_init(dev, I915_NUM_PIPE);
@@ -1738,6 +2183,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1738 2183
1739 setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, 2184 setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
1740 (unsigned long) dev); 2185 (unsigned long) dev);
2186
2187 spin_lock(&mchdev_lock);
2188 i915_mch_dev = dev_priv;
2189 dev_priv->mchdev_lock = &mchdev_lock;
2190 spin_unlock(&mchdev_lock);
2191
1741 return 0; 2192 return 0;
1742 2193
1743out_workqueue_free: 2194out_workqueue_free:
@@ -1759,6 +2210,10 @@ int i915_driver_unload(struct drm_device *dev)
1759 2210
1760 i915_destroy_error_state(dev); 2211 i915_destroy_error_state(dev);
1761 2212
2213 spin_lock(&mchdev_lock);
2214 i915_mch_dev = NULL;
2215 spin_unlock(&mchdev_lock);
2216
1762 destroy_workqueue(dev_priv->wq); 2217 destroy_workqueue(dev_priv->wq);
1763 del_timer_sync(&dev_priv->hangcheck_timer); 2218 del_timer_sync(&dev_priv->hangcheck_timer);
1764 2219
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 5c51e45ab68d..423dc90c1e20 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -60,95 +60,95 @@ extern int intel_agp_enabled;
60 .subdevice = PCI_ANY_ID, \ 60 .subdevice = PCI_ANY_ID, \
61 .driver_data = (unsigned long) info } 61 .driver_data = (unsigned long) info }
62 62
63const static struct intel_device_info intel_i830_info = { 63static const struct intel_device_info intel_i830_info = {
64 .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, 64 .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
65}; 65};
66 66
67const static struct intel_device_info intel_845g_info = { 67static const struct intel_device_info intel_845g_info = {
68 .is_i8xx = 1, 68 .is_i8xx = 1,
69}; 69};
70 70
71const static struct intel_device_info intel_i85x_info = { 71static const struct intel_device_info intel_i85x_info = {
72 .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, 72 .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
73 .cursor_needs_physical = 1, 73 .cursor_needs_physical = 1,
74}; 74};
75 75
76const static struct intel_device_info intel_i865g_info = { 76static const struct intel_device_info intel_i865g_info = {
77 .is_i8xx = 1, 77 .is_i8xx = 1,
78}; 78};
79 79
80const static struct intel_device_info intel_i915g_info = { 80static const struct intel_device_info intel_i915g_info = {
81 .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, 81 .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
82}; 82};
83const static struct intel_device_info intel_i915gm_info = { 83static const struct intel_device_info intel_i915gm_info = {
84 .is_i9xx = 1, .is_mobile = 1, 84 .is_i9xx = 1, .is_mobile = 1,
85 .cursor_needs_physical = 1, 85 .cursor_needs_physical = 1,
86}; 86};
87const static struct intel_device_info intel_i945g_info = { 87static const struct intel_device_info intel_i945g_info = {
88 .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, 88 .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
89}; 89};
90const static struct intel_device_info intel_i945gm_info = { 90static const struct intel_device_info intel_i945gm_info = {
91 .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, 91 .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
92 .has_hotplug = 1, .cursor_needs_physical = 1, 92 .has_hotplug = 1, .cursor_needs_physical = 1,
93}; 93};
94 94
95const static struct intel_device_info intel_i965g_info = { 95static const struct intel_device_info intel_i965g_info = {
96 .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, 96 .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
97}; 97};
98 98
99const static struct intel_device_info intel_i965gm_info = { 99static const struct intel_device_info intel_i965gm_info = {
100 .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, 100 .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1,
101 .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, 101 .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1,
102 .has_hotplug = 1, 102 .has_hotplug = 1,
103}; 103};
104 104
105const static struct intel_device_info intel_g33_info = { 105static const struct intel_device_info intel_g33_info = {
106 .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, 106 .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1,
107 .has_hotplug = 1, 107 .has_hotplug = 1,
108}; 108};
109 109
110const static struct intel_device_info intel_g45_info = { 110static const struct intel_device_info intel_g45_info = {
111 .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, 111 .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1,
112 .has_pipe_cxsr = 1, 112 .has_pipe_cxsr = 1,
113 .has_hotplug = 1, 113 .has_hotplug = 1,
114}; 114};
115 115
116const static struct intel_device_info intel_gm45_info = { 116static const struct intel_device_info intel_gm45_info = {
117 .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, 117 .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1,
118 .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, 118 .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
119 .has_pipe_cxsr = 1, 119 .has_pipe_cxsr = 1,
120 .has_hotplug = 1, 120 .has_hotplug = 1,
121}; 121};
122 122
123const static struct intel_device_info intel_pineview_info = { 123static const struct intel_device_info intel_pineview_info = {
124 .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, 124 .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1,
125 .need_gfx_hws = 1, 125 .need_gfx_hws = 1,
126 .has_hotplug = 1, 126 .has_hotplug = 1,
127}; 127};
128 128
129const static struct intel_device_info intel_ironlake_d_info = { 129static const struct intel_device_info intel_ironlake_d_info = {
130 .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, 130 .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
131 .has_pipe_cxsr = 1, 131 .has_pipe_cxsr = 1,
132 .has_hotplug = 1, 132 .has_hotplug = 1,
133}; 133};
134 134
135const static struct intel_device_info intel_ironlake_m_info = { 135static const struct intel_device_info intel_ironlake_m_info = {
136 .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, 136 .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
137 .need_gfx_hws = 1, .has_rc6 = 1, 137 .need_gfx_hws = 1, .has_rc6 = 1,
138 .has_hotplug = 1, 138 .has_hotplug = 1,
139}; 139};
140 140
141const static struct intel_device_info intel_sandybridge_d_info = { 141static const struct intel_device_info intel_sandybridge_d_info = {
142 .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, 142 .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
143 .has_hotplug = 1, .is_gen6 = 1, 143 .has_hotplug = 1, .is_gen6 = 1,
144}; 144};
145 145
146const static struct intel_device_info intel_sandybridge_m_info = { 146static const struct intel_device_info intel_sandybridge_m_info = {
147 .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, 147 .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1,
148 .has_hotplug = 1, .is_gen6 = 1, 148 .has_hotplug = 1, .is_gen6 = 1,
149}; 149};
150 150
151const static struct pci_device_id pciidlist[] = { 151static const struct pci_device_id pciidlist[] = {
152 INTEL_VGA_DEVICE(0x3577, &intel_i830_info), 152 INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
153 INTEL_VGA_DEVICE(0x2562, &intel_845g_info), 153 INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
154 INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), 154 INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
@@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
340 /* 340 /*
341 * Clear request list 341 * Clear request list
342 */ 342 */
343 i915_gem_retire_requests(dev); 343 i915_gem_retire_requests(dev, &dev_priv->render_ring);
344 344
345 if (need_display) 345 if (need_display)
346 i915_save_display(dev); 346 i915_save_display(dev);
@@ -370,6 +370,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
370 } 370 }
371 } else { 371 } else {
372 DRM_ERROR("Error occurred. Don't know how to reset this chip.\n"); 372 DRM_ERROR("Error occurred. Don't know how to reset this chip.\n");
373 mutex_unlock(&dev->struct_mutex);
373 return -ENODEV; 374 return -ENODEV;
374 } 375 }
375 376
@@ -388,33 +389,10 @@ int i965_reset(struct drm_device *dev, u8 flags)
388 * switched away). 389 * switched away).
389 */ 390 */
390 if (drm_core_check_feature(dev, DRIVER_MODESET) || 391 if (drm_core_check_feature(dev, DRIVER_MODESET) ||
391 !dev_priv->mm.suspended) { 392 !dev_priv->mm.suspended) {
392 drm_i915_ring_buffer_t *ring = &dev_priv->ring; 393 struct intel_ring_buffer *ring = &dev_priv->render_ring;
393 struct drm_gem_object *obj = ring->ring_obj;
394 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
395 dev_priv->mm.suspended = 0; 394 dev_priv->mm.suspended = 0;
396 395 ring->init(dev, ring);
397 /* Stop the ring if it's running. */
398 I915_WRITE(PRB0_CTL, 0);
399 I915_WRITE(PRB0_TAIL, 0);
400 I915_WRITE(PRB0_HEAD, 0);
401
402 /* Initialize the ring. */
403 I915_WRITE(PRB0_START, obj_priv->gtt_offset);
404 I915_WRITE(PRB0_CTL,
405 ((obj->size - 4096) & RING_NR_PAGES) |
406 RING_NO_REPORT |
407 RING_VALID);
408 if (!drm_core_check_feature(dev, DRIVER_MODESET))
409 i915_kernel_lost_context(dev);
410 else {
411 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
412 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
413 ring->space = ring->head - (ring->tail + 8);
414 if (ring->space < 0)
415 ring->space += ring->Size;
416 }
417
418 mutex_unlock(&dev->struct_mutex); 396 mutex_unlock(&dev->struct_mutex);
419 drm_irq_uninstall(dev); 397 drm_irq_uninstall(dev);
420 drm_irq_install(dev); 398 drm_irq_install(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7f797ef1ab39..9ed8ecd95801 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -32,6 +32,7 @@
32 32
33#include "i915_reg.h" 33#include "i915_reg.h"
34#include "intel_bios.h" 34#include "intel_bios.h"
35#include "intel_ringbuffer.h"
35#include <linux/io-mapping.h> 36#include <linux/io-mapping.h>
36 37
37/* General customization: 38/* General customization:
@@ -55,6 +56,8 @@ enum plane {
55 56
56#define I915_NUM_PIPE 2 57#define I915_NUM_PIPE 2
57 58
59#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
60
58/* Interface history: 61/* Interface history:
59 * 62 *
60 * 1.1: Original. 63 * 1.1: Original.
@@ -89,16 +92,6 @@ struct drm_i915_gem_phys_object {
89 struct drm_gem_object *cur_obj; 92 struct drm_gem_object *cur_obj;
90}; 93};
91 94
92typedef struct _drm_i915_ring_buffer {
93 unsigned long Size;
94 u8 *virtual_start;
95 int head;
96 int tail;
97 int space;
98 drm_local_map_t map;
99 struct drm_gem_object *ring_obj;
100} drm_i915_ring_buffer_t;
101
102struct mem_block { 95struct mem_block {
103 struct mem_block *next; 96 struct mem_block *next;
104 struct mem_block *prev; 97 struct mem_block *prev;
@@ -241,17 +234,15 @@ typedef struct drm_i915_private {
241 void __iomem *regs; 234 void __iomem *regs;
242 235
243 struct pci_dev *bridge_dev; 236 struct pci_dev *bridge_dev;
244 drm_i915_ring_buffer_t ring; 237 struct intel_ring_buffer render_ring;
238 struct intel_ring_buffer bsd_ring;
245 239
246 drm_dma_handle_t *status_page_dmah; 240 drm_dma_handle_t *status_page_dmah;
247 void *hw_status_page;
248 void *seqno_page; 241 void *seqno_page;
249 dma_addr_t dma_status_page; 242 dma_addr_t dma_status_page;
250 uint32_t counter; 243 uint32_t counter;
251 unsigned int status_gfx_addr;
252 unsigned int seqno_gfx_addr; 244 unsigned int seqno_gfx_addr;
253 drm_local_map_t hws_map; 245 drm_local_map_t hws_map;
254 struct drm_gem_object *hws_obj;
255 struct drm_gem_object *seqno_obj; 246 struct drm_gem_object *seqno_obj;
256 struct drm_gem_object *pwrctx; 247 struct drm_gem_object *pwrctx;
257 248
@@ -267,8 +258,6 @@ typedef struct drm_i915_private {
267 atomic_t irq_received; 258 atomic_t irq_received;
268 /** Protects user_irq_refcount and irq_mask_reg */ 259 /** Protects user_irq_refcount and irq_mask_reg */
269 spinlock_t user_irq_lock; 260 spinlock_t user_irq_lock;
270 /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
271 int user_irq_refcount;
272 u32 trace_irq_seqno; 261 u32 trace_irq_seqno;
273 /** Cached value of IMR to avoid reads in updating the bitfield */ 262 /** Cached value of IMR to avoid reads in updating the bitfield */
274 u32 irq_mask_reg; 263 u32 irq_mask_reg;
@@ -334,7 +323,7 @@ typedef struct drm_i915_private {
334 int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ 323 int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
335 int num_fence_regs; /* 8 on pre-965, 16 otherwise */ 324 int num_fence_regs; /* 8 on pre-965, 16 otherwise */
336 325
337 unsigned int fsb_freq, mem_freq; 326 unsigned int fsb_freq, mem_freq, is_ddr3;
338 327
339 spinlock_t error_lock; 328 spinlock_t error_lock;
340 struct drm_i915_error_state *first_error; 329 struct drm_i915_error_state *first_error;
@@ -514,18 +503,7 @@ typedef struct drm_i915_private {
514 */ 503 */
515 struct list_head shrink_list; 504 struct list_head shrink_list;
516 505
517 /**
518 * List of objects currently involved in rendering from the
519 * ringbuffer.
520 *
521 * Includes buffers having the contents of their GPU caches
522 * flushed, not necessarily primitives. last_rendering_seqno
523 * represents when the rendering involved will be completed.
524 *
525 * A reference is held on the buffer while on this list.
526 */
527 spinlock_t active_list_lock; 506 spinlock_t active_list_lock;
528 struct list_head active_list;
529 507
530 /** 508 /**
531 * List of objects which are not in the ringbuffer but which 509 * List of objects which are not in the ringbuffer but which
@@ -563,12 +541,6 @@ typedef struct drm_i915_private {
563 struct list_head fence_list; 541 struct list_head fence_list;
564 542
565 /** 543 /**
566 * List of breadcrumbs associated with GPU requests currently
567 * outstanding.
568 */
569 struct list_head request_list;
570
571 /**
572 * We leave the user IRQ off as much as possible, 544 * We leave the user IRQ off as much as possible,
573 * but this means that requests will finish and never 545 * but this means that requests will finish and never
574 * be retired once the system goes idle. Set a timer to 546 * be retired once the system goes idle. Set a timer to
@@ -644,6 +616,18 @@ typedef struct drm_i915_private {
644 u8 cur_delay; 616 u8 cur_delay;
645 u8 min_delay; 617 u8 min_delay;
646 u8 max_delay; 618 u8 max_delay;
619 u8 fmax;
620 u8 fstart;
621
622 u64 last_count1;
623 unsigned long last_time1;
624 u64 last_count2;
625 struct timespec last_time2;
626 unsigned long gfx_power;
627 int c_m;
628 int r_t;
629 u8 corr;
630 spinlock_t *mchdev_lock;
647 631
648 enum no_fbc_reason no_fbc_reason; 632 enum no_fbc_reason no_fbc_reason;
649 633
@@ -671,19 +655,64 @@ struct drm_i915_gem_object {
671 * (has pending rendering), and is not set if it's on inactive (ready 655 * (has pending rendering), and is not set if it's on inactive (ready
672 * to be unbound). 656 * to be unbound).
673 */ 657 */
674 int active; 658 unsigned int active : 1;
675 659
676 /** 660 /**
677 * This is set if the object has been written to since last bound 661 * This is set if the object has been written to since last bound
678 * to the GTT 662 * to the GTT
679 */ 663 */
680 int dirty; 664 unsigned int dirty : 1;
665
666 /**
667 * Fence register bits (if any) for this object. Will be set
668 * as needed when mapped into the GTT.
669 * Protected by dev->struct_mutex.
670 *
671 * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)
672 */
673 int fence_reg : 5;
674
675 /**
676 * Used for checking the object doesn't appear more than once
677 * in an execbuffer object list.
678 */
679 unsigned int in_execbuffer : 1;
680
681 /**
682 * Advice: are the backing pages purgeable?
683 */
684 unsigned int madv : 2;
685
686 /**
687 * Refcount for the pages array. With the current locking scheme, there
688 * are at most two concurrent users: Binding a bo to the gtt and
689 * pwrite/pread using physical addresses. So two bits for a maximum
690 * of two users are enough.
691 */
692 unsigned int pages_refcount : 2;
693#define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3
694
695 /**
696 * Current tiling mode for the object.
697 */
698 unsigned int tiling_mode : 2;
699
700 /** How many users have pinned this object in GTT space. The following
701 * users can each hold at most one reference: pwrite/pread, pin_ioctl
702 * (via user_pin_count), execbuffer (objects are not allowed multiple
703 * times for the same batchbuffer), and the framebuffer code. When
704 * switching/pageflipping, the framebuffer code has at most two buffers
705 * pinned per crtc.
706 *
707 * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
708 * bits with absolutely no headroom. So use 4 bits. */
709 int pin_count : 4;
710#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
681 711
682 /** AGP memory structure for our GTT binding. */ 712 /** AGP memory structure for our GTT binding. */
683 DRM_AGP_MEM *agp_mem; 713 DRM_AGP_MEM *agp_mem;
684 714
685 struct page **pages; 715 struct page **pages;
686 int pages_refcount;
687 716
688 /** 717 /**
689 * Current offset of the object in GTT space. 718 * Current offset of the object in GTT space.
@@ -692,26 +721,18 @@ struct drm_i915_gem_object {
692 */ 721 */
693 uint32_t gtt_offset; 722 uint32_t gtt_offset;
694 723
724 /* Which ring is refering to is this object */
725 struct intel_ring_buffer *ring;
726
695 /** 727 /**
696 * Fake offset for use by mmap(2) 728 * Fake offset for use by mmap(2)
697 */ 729 */
698 uint64_t mmap_offset; 730 uint64_t mmap_offset;
699 731
700 /**
701 * Fence register bits (if any) for this object. Will be set
702 * as needed when mapped into the GTT.
703 * Protected by dev->struct_mutex.
704 */
705 int fence_reg;
706
707 /** How many users have pinned this object in GTT space */
708 int pin_count;
709
710 /** Breadcrumb of last rendering to the buffer. */ 732 /** Breadcrumb of last rendering to the buffer. */
711 uint32_t last_rendering_seqno; 733 uint32_t last_rendering_seqno;
712 734
713 /** Current tiling mode for the object. */ 735 /** Current tiling stride for the object, if it's tiled. */
714 uint32_t tiling_mode;
715 uint32_t stride; 736 uint32_t stride;
716 737
717 /** Record of address bit 17 of each page at last unbind. */ 738 /** Record of address bit 17 of each page at last unbind. */
@@ -734,17 +755,6 @@ struct drm_i915_gem_object {
734 struct drm_i915_gem_phys_object *phys_obj; 755 struct drm_i915_gem_phys_object *phys_obj;
735 756
736 /** 757 /**
737 * Used for checking the object doesn't appear more than once
738 * in an execbuffer object list.
739 */
740 int in_execbuffer;
741
742 /**
743 * Advice: are the backing pages purgeable?
744 */
745 int madv;
746
747 /**
748 * Number of crtcs where this object is currently the fb, but 758 * Number of crtcs where this object is currently the fb, but
749 * will be page flipped away on the next vblank. When it 759 * will be page flipped away on the next vblank. When it
750 * reaches 0, dev_priv->pending_flip_queue will be woken up. 760 * reaches 0, dev_priv->pending_flip_queue will be woken up.
@@ -765,6 +775,9 @@ struct drm_i915_gem_object {
765 * an emission time with seqnos for tracking how far ahead of the GPU we are. 775 * an emission time with seqnos for tracking how far ahead of the GPU we are.
766 */ 776 */
767struct drm_i915_gem_request { 777struct drm_i915_gem_request {
778 /** On Which ring this request was generated */
779 struct intel_ring_buffer *ring;
780
768 /** GEM sequence number associated with this request. */ 781 /** GEM sequence number associated with this request. */
769 uint32_t seqno; 782 uint32_t seqno;
770 783
@@ -821,6 +834,11 @@ extern int i915_emit_box(struct drm_device *dev,
821 struct drm_clip_rect *boxes, 834 struct drm_clip_rect *boxes,
822 int i, int DR1, int DR4); 835 int i, int DR1, int DR4);
823extern int i965_reset(struct drm_device *dev, u8 flags); 836extern int i965_reset(struct drm_device *dev, u8 flags);
837extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
838extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
839extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
840extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
841
824 842
825/* i915_irq.c */ 843/* i915_irq.c */
826void i915_hangcheck_elapsed(unsigned long data); 844void i915_hangcheck_elapsed(unsigned long data);
@@ -829,9 +847,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
829 struct drm_file *file_priv); 847 struct drm_file *file_priv);
830extern int i915_irq_wait(struct drm_device *dev, void *data, 848extern int i915_irq_wait(struct drm_device *dev, void *data,
831 struct drm_file *file_priv); 849 struct drm_file *file_priv);
832void i915_user_irq_get(struct drm_device *dev);
833void i915_trace_irq_get(struct drm_device *dev, u32 seqno); 850void i915_trace_irq_get(struct drm_device *dev, u32 seqno);
834void i915_user_irq_put(struct drm_device *dev);
835extern void i915_enable_interrupt (struct drm_device *dev); 851extern void i915_enable_interrupt (struct drm_device *dev);
836 852
837extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); 853extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
@@ -849,6 +865,11 @@ extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
849extern int i915_vblank_swap(struct drm_device *dev, void *data, 865extern int i915_vblank_swap(struct drm_device *dev, void *data,
850 struct drm_file *file_priv); 866 struct drm_file *file_priv);
851extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); 867extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
868extern void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask);
869extern void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv,
870 u32 mask);
871extern void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv,
872 u32 mask);
852 873
853void 874void
854i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); 875i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
@@ -922,11 +943,13 @@ void i915_gem_object_unpin(struct drm_gem_object *obj);
922int i915_gem_object_unbind(struct drm_gem_object *obj); 943int i915_gem_object_unbind(struct drm_gem_object *obj);
923void i915_gem_release_mmap(struct drm_gem_object *obj); 944void i915_gem_release_mmap(struct drm_gem_object *obj);
924void i915_gem_lastclose(struct drm_device *dev); 945void i915_gem_lastclose(struct drm_device *dev);
925uint32_t i915_get_gem_seqno(struct drm_device *dev); 946uint32_t i915_get_gem_seqno(struct drm_device *dev,
947 struct intel_ring_buffer *ring);
926bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); 948bool i915_seqno_passed(uint32_t seq1, uint32_t seq2);
927int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); 949int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
928int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); 950int i915_gem_object_put_fence_reg(struct drm_gem_object *obj);
929void i915_gem_retire_requests(struct drm_device *dev); 951void i915_gem_retire_requests(struct drm_device *dev,
952 struct intel_ring_buffer *ring);
930void i915_gem_retire_work_handler(struct work_struct *work); 953void i915_gem_retire_work_handler(struct work_struct *work);
931void i915_gem_clflush_object(struct drm_gem_object *obj); 954void i915_gem_clflush_object(struct drm_gem_object *obj);
932int i915_gem_object_set_domain(struct drm_gem_object *obj, 955int i915_gem_object_set_domain(struct drm_gem_object *obj,
@@ -937,9 +960,13 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
937int i915_gem_do_init(struct drm_device *dev, unsigned long start, 960int i915_gem_do_init(struct drm_device *dev, unsigned long start,
938 unsigned long end); 961 unsigned long end);
939int i915_gem_idle(struct drm_device *dev); 962int i915_gem_idle(struct drm_device *dev);
940uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, 963uint32_t i915_add_request(struct drm_device *dev,
941 uint32_t flush_domains); 964 struct drm_file *file_priv,
942int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible); 965 uint32_t flush_domains,
966 struct intel_ring_buffer *ring);
967int i915_do_wait_request(struct drm_device *dev,
968 uint32_t seqno, int interruptible,
969 struct intel_ring_buffer *ring);
943int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 970int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
944int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, 971int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
945 int write); 972 int write);
@@ -1015,7 +1042,7 @@ extern void g4x_disable_fbc(struct drm_device *dev);
1015extern void intel_disable_fbc(struct drm_device *dev); 1042extern void intel_disable_fbc(struct drm_device *dev);
1016extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); 1043extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval);
1017extern bool intel_fbc_enabled(struct drm_device *dev); 1044extern bool intel_fbc_enabled(struct drm_device *dev);
1018 1045extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
1019extern void intel_detect_pch (struct drm_device *dev); 1046extern void intel_detect_pch (struct drm_device *dev);
1020extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); 1047extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
1021 1048
@@ -1026,7 +1053,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
1026 * has access to the ring. 1053 * has access to the ring.
1027 */ 1054 */
1028#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ 1055#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \
1029 if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \ 1056 if (((drm_i915_private_t *)dev->dev_private)->render_ring.gem_object \
1057 == NULL) \
1030 LOCK_TEST_WITH_RETURN(dev, file_priv); \ 1058 LOCK_TEST_WITH_RETURN(dev, file_priv); \
1031} while (0) 1059} while (0)
1032 1060
@@ -1039,35 +1067,31 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
1039#define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg)) 1067#define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg))
1040#define I915_READ64(reg) readq(dev_priv->regs + (reg)) 1068#define I915_READ64(reg) readq(dev_priv->regs + (reg))
1041#define POSTING_READ(reg) (void)I915_READ(reg) 1069#define POSTING_READ(reg) (void)I915_READ(reg)
1070#define POSTING_READ16(reg) (void)I915_READ16(reg)
1042 1071
1043#define I915_VERBOSE 0 1072#define I915_VERBOSE 0
1044 1073
1045#define RING_LOCALS volatile unsigned int *ring_virt__; 1074#define BEGIN_LP_RING(n) do { \
1046 1075 drm_i915_private_t *dev_priv = dev->dev_private; \
1047#define BEGIN_LP_RING(n) do { \ 1076 if (I915_VERBOSE) \
1048 int bytes__ = 4*(n); \ 1077 DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \
1049 if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ 1078 intel_ring_begin(dev, &dev_priv->render_ring, 4*(n)); \
1050 /* a wrap must occur between instructions so pad beforehand */ \
1051 if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \
1052 i915_wrap_ring(dev); \
1053 if (unlikely (dev_priv->ring.space < bytes__)) \
1054 i915_wait_ring(dev, bytes__, __func__); \
1055 ring_virt__ = (unsigned int *) \
1056 (dev_priv->ring.virtual_start + dev_priv->ring.tail); \
1057 dev_priv->ring.tail += bytes__; \
1058 dev_priv->ring.tail &= dev_priv->ring.Size - 1; \
1059 dev_priv->ring.space -= bytes__; \
1060} while (0) 1079} while (0)
1061 1080
1062#define OUT_RING(n) do { \ 1081
1063 if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ 1082#define OUT_RING(x) do { \
1064 *ring_virt__++ = (n); \ 1083 drm_i915_private_t *dev_priv = dev->dev_private; \
1084 if (I915_VERBOSE) \
1085 DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \
1086 intel_ring_emit(dev, &dev_priv->render_ring, x); \
1065} while (0) 1087} while (0)
1066 1088
1067#define ADVANCE_LP_RING() do { \ 1089#define ADVANCE_LP_RING() do { \
1090 drm_i915_private_t *dev_priv = dev->dev_private; \
1068 if (I915_VERBOSE) \ 1091 if (I915_VERBOSE) \
1069 DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \ 1092 DRM_DEBUG("ADVANCE_LP_RING %x\n", \
1070 I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \ 1093 dev_priv->render_ring.tail); \
1094 intel_ring_advance(dev, &dev_priv->render_ring); \
1071} while(0) 1095} while(0)
1072 1096
1073/** 1097/**
@@ -1085,14 +1109,12 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
1085 * 1109 *
1086 * The area from dword 0x20 to 0x3ff is available for driver usage. 1110 * The area from dword 0x20 to 0x3ff is available for driver usage.
1087 */ 1111 */
1088#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) 1112#define READ_HWSP(dev_priv, reg) (((volatile u32 *)\
1113 (dev_priv->render_ring.status_page.page_addr))[reg])
1089#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) 1114#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX)
1090#define I915_GEM_HWS_INDEX 0x20 1115#define I915_GEM_HWS_INDEX 0x20
1091#define I915_BREADCRUMB_INDEX 0x21 1116#define I915_BREADCRUMB_INDEX 0x21
1092 1117
1093extern int i915_wrap_ring(struct drm_device * dev);
1094extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1095
1096#define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) 1118#define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info)
1097 1119
1098#define IS_I830(dev) ((dev)->pci_device == 0x3577) 1120#define IS_I830(dev) ((dev)->pci_device == 0x3577)
@@ -1138,6 +1160,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1138 (dev)->pci_device == 0x2A42 || \ 1160 (dev)->pci_device == 0x2A42 || \
1139 (dev)->pci_device == 0x2E42) 1161 (dev)->pci_device == 0x2E42)
1140 1162
1163#define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev))
1141#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) 1164#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
1142 1165
1143/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte 1166/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 112699f71fa4..9ded3dae6c87 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -35,8 +35,6 @@
35#include <linux/swap.h> 35#include <linux/swap.h>
36#include <linux/pci.h> 36#include <linux/pci.h>
37 37
38#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
39
40static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); 38static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
41static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); 39static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
42static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); 40static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -169,7 +167,7 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
169 obj_priv->tiling_mode != I915_TILING_NONE; 167 obj_priv->tiling_mode != I915_TILING_NONE;
170} 168}
171 169
172static inline int 170static inline void
173slow_shmem_copy(struct page *dst_page, 171slow_shmem_copy(struct page *dst_page,
174 int dst_offset, 172 int dst_offset,
175 struct page *src_page, 173 struct page *src_page,
@@ -178,25 +176,16 @@ slow_shmem_copy(struct page *dst_page,
178{ 176{
179 char *dst_vaddr, *src_vaddr; 177 char *dst_vaddr, *src_vaddr;
180 178
181 dst_vaddr = kmap_atomic(dst_page, KM_USER0); 179 dst_vaddr = kmap(dst_page);
182 if (dst_vaddr == NULL) 180 src_vaddr = kmap(src_page);
183 return -ENOMEM;
184
185 src_vaddr = kmap_atomic(src_page, KM_USER1);
186 if (src_vaddr == NULL) {
187 kunmap_atomic(dst_vaddr, KM_USER0);
188 return -ENOMEM;
189 }
190 181
191 memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); 182 memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length);
192 183
193 kunmap_atomic(src_vaddr, KM_USER1); 184 kunmap(src_page);
194 kunmap_atomic(dst_vaddr, KM_USER0); 185 kunmap(dst_page);
195
196 return 0;
197} 186}
198 187
199static inline int 188static inline void
200slow_shmem_bit17_copy(struct page *gpu_page, 189slow_shmem_bit17_copy(struct page *gpu_page,
201 int gpu_offset, 190 int gpu_offset,
202 struct page *cpu_page, 191 struct page *cpu_page,
@@ -216,15 +205,8 @@ slow_shmem_bit17_copy(struct page *gpu_page,
216 cpu_page, cpu_offset, length); 205 cpu_page, cpu_offset, length);
217 } 206 }
218 207
219 gpu_vaddr = kmap_atomic(gpu_page, KM_USER0); 208 gpu_vaddr = kmap(gpu_page);
220 if (gpu_vaddr == NULL) 209 cpu_vaddr = kmap(cpu_page);
221 return -ENOMEM;
222
223 cpu_vaddr = kmap_atomic(cpu_page, KM_USER1);
224 if (cpu_vaddr == NULL) {
225 kunmap_atomic(gpu_vaddr, KM_USER0);
226 return -ENOMEM;
227 }
228 210
229 /* Copy the data, XORing A6 with A17 (1). The user already knows he's 211 /* Copy the data, XORing A6 with A17 (1). The user already knows he's
230 * XORing with the other bits (A9 for Y, A9 and A10 for X) 212 * XORing with the other bits (A9 for Y, A9 and A10 for X)
@@ -248,10 +230,8 @@ slow_shmem_bit17_copy(struct page *gpu_page,
248 length -= this_length; 230 length -= this_length;
249 } 231 }
250 232
251 kunmap_atomic(cpu_vaddr, KM_USER1); 233 kunmap(cpu_page);
252 kunmap_atomic(gpu_vaddr, KM_USER0); 234 kunmap(gpu_page);
253
254 return 0;
255} 235}
256 236
257/** 237/**
@@ -427,21 +407,19 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
427 page_length = PAGE_SIZE - data_page_offset; 407 page_length = PAGE_SIZE - data_page_offset;
428 408
429 if (do_bit17_swizzling) { 409 if (do_bit17_swizzling) {
430 ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], 410 slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
431 shmem_page_offset,
432 user_pages[data_page_index],
433 data_page_offset,
434 page_length,
435 1);
436 } else {
437 ret = slow_shmem_copy(user_pages[data_page_index],
438 data_page_offset,
439 obj_priv->pages[shmem_page_index],
440 shmem_page_offset, 411 shmem_page_offset,
441 page_length); 412 user_pages[data_page_index],
413 data_page_offset,
414 page_length,
415 1);
416 } else {
417 slow_shmem_copy(user_pages[data_page_index],
418 data_page_offset,
419 obj_priv->pages[shmem_page_index],
420 shmem_page_offset,
421 page_length);
442 } 422 }
443 if (ret)
444 goto fail_put_pages;
445 423
446 remain -= page_length; 424 remain -= page_length;
447 data_ptr += page_length; 425 data_ptr += page_length;
@@ -531,25 +509,24 @@ fast_user_write(struct io_mapping *mapping,
531 * page faults 509 * page faults
532 */ 510 */
533 511
534static inline int 512static inline void
535slow_kernel_write(struct io_mapping *mapping, 513slow_kernel_write(struct io_mapping *mapping,
536 loff_t gtt_base, int gtt_offset, 514 loff_t gtt_base, int gtt_offset,
537 struct page *user_page, int user_offset, 515 struct page *user_page, int user_offset,
538 int length) 516 int length)
539{ 517{
540 char *src_vaddr, *dst_vaddr; 518 char __iomem *dst_vaddr;
541 unsigned long unwritten; 519 char *src_vaddr;
542 520
543 dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base); 521 dst_vaddr = io_mapping_map_wc(mapping, gtt_base);
544 src_vaddr = kmap_atomic(user_page, KM_USER1); 522 src_vaddr = kmap(user_page);
545 unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset, 523
546 src_vaddr + user_offset, 524 memcpy_toio(dst_vaddr + gtt_offset,
547 length); 525 src_vaddr + user_offset,
548 kunmap_atomic(src_vaddr, KM_USER1); 526 length);
549 io_mapping_unmap_atomic(dst_vaddr); 527
550 if (unwritten) 528 kunmap(user_page);
551 return -EFAULT; 529 io_mapping_unmap(dst_vaddr);
552 return 0;
553} 530}
554 531
555static inline int 532static inline int
@@ -722,18 +699,11 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
722 if ((data_page_offset + page_length) > PAGE_SIZE) 699 if ((data_page_offset + page_length) > PAGE_SIZE)
723 page_length = PAGE_SIZE - data_page_offset; 700 page_length = PAGE_SIZE - data_page_offset;
724 701
725 ret = slow_kernel_write(dev_priv->mm.gtt_mapping, 702 slow_kernel_write(dev_priv->mm.gtt_mapping,
726 gtt_page_base, gtt_page_offset, 703 gtt_page_base, gtt_page_offset,
727 user_pages[data_page_index], 704 user_pages[data_page_index],
728 data_page_offset, 705 data_page_offset,
729 page_length); 706 page_length);
730
731 /* If we get a fault while copying data, then (presumably) our
732 * source page isn't available. Return the error and we'll
733 * retry in the slow path.
734 */
735 if (ret)
736 goto out_unpin_object;
737 707
738 remain -= page_length; 708 remain -= page_length;
739 offset += page_length; 709 offset += page_length;
@@ -902,21 +872,19 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
902 page_length = PAGE_SIZE - data_page_offset; 872 page_length = PAGE_SIZE - data_page_offset;
903 873
904 if (do_bit17_swizzling) { 874 if (do_bit17_swizzling) {
905 ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], 875 slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
906 shmem_page_offset,
907 user_pages[data_page_index],
908 data_page_offset,
909 page_length,
910 0);
911 } else {
912 ret = slow_shmem_copy(obj_priv->pages[shmem_page_index],
913 shmem_page_offset, 876 shmem_page_offset,
914 user_pages[data_page_index], 877 user_pages[data_page_index],
915 data_page_offset, 878 data_page_offset,
916 page_length); 879 page_length,
880 0);
881 } else {
882 slow_shmem_copy(obj_priv->pages[shmem_page_index],
883 shmem_page_offset,
884 user_pages[data_page_index],
885 data_page_offset,
886 page_length);
917 } 887 }
918 if (ret)
919 goto fail_put_pages;
920 888
921 remain -= page_length; 889 remain -= page_length;
922 data_ptr += page_length; 890 data_ptr += page_length;
@@ -973,7 +941,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
973 if (obj_priv->phys_obj) 941 if (obj_priv->phys_obj)
974 ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); 942 ret = i915_gem_phys_pwrite(dev, obj, args, file_priv);
975 else if (obj_priv->tiling_mode == I915_TILING_NONE && 943 else if (obj_priv->tiling_mode == I915_TILING_NONE &&
976 dev->gtt_total != 0) { 944 dev->gtt_total != 0 &&
945 obj->write_domain != I915_GEM_DOMAIN_CPU) {
977 ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv); 946 ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv);
978 if (ret == -EFAULT) { 947 if (ret == -EFAULT) {
979 ret = i915_gem_gtt_pwrite_slow(dev, obj, args, 948 ret = i915_gem_gtt_pwrite_slow(dev, obj, args,
@@ -1484,11 +1453,14 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
1484} 1453}
1485 1454
1486static void 1455static void
1487i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) 1456i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno,
1457 struct intel_ring_buffer *ring)
1488{ 1458{
1489 struct drm_device *dev = obj->dev; 1459 struct drm_device *dev = obj->dev;
1490 drm_i915_private_t *dev_priv = dev->dev_private; 1460 drm_i915_private_t *dev_priv = dev->dev_private;
1491 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 1461 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
1462 BUG_ON(ring == NULL);
1463 obj_priv->ring = ring;
1492 1464
1493 /* Add a reference if we're newly entering the active list. */ 1465 /* Add a reference if we're newly entering the active list. */
1494 if (!obj_priv->active) { 1466 if (!obj_priv->active) {
@@ -1497,8 +1469,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
1497 } 1469 }
1498 /* Move from whatever list we were on to the tail of execution. */ 1470 /* Move from whatever list we were on to the tail of execution. */
1499 spin_lock(&dev_priv->mm.active_list_lock); 1471 spin_lock(&dev_priv->mm.active_list_lock);
1500 list_move_tail(&obj_priv->list, 1472 list_move_tail(&obj_priv->list, &ring->active_list);
1501 &dev_priv->mm.active_list);
1502 spin_unlock(&dev_priv->mm.active_list_lock); 1473 spin_unlock(&dev_priv->mm.active_list_lock);
1503 obj_priv->last_rendering_seqno = seqno; 1474 obj_priv->last_rendering_seqno = seqno;
1504} 1475}
@@ -1551,6 +1522,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
1551 BUG_ON(!list_empty(&obj_priv->gpu_write_list)); 1522 BUG_ON(!list_empty(&obj_priv->gpu_write_list));
1552 1523
1553 obj_priv->last_rendering_seqno = 0; 1524 obj_priv->last_rendering_seqno = 0;
1525 obj_priv->ring = NULL;
1554 if (obj_priv->active) { 1526 if (obj_priv->active) {
1555 obj_priv->active = 0; 1527 obj_priv->active = 0;
1556 drm_gem_object_unreference(obj); 1528 drm_gem_object_unreference(obj);
@@ -1560,7 +1532,8 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
1560 1532
1561static void 1533static void
1562i915_gem_process_flushing_list(struct drm_device *dev, 1534i915_gem_process_flushing_list(struct drm_device *dev,
1563 uint32_t flush_domains, uint32_t seqno) 1535 uint32_t flush_domains, uint32_t seqno,
1536 struct intel_ring_buffer *ring)
1564{ 1537{
1565 drm_i915_private_t *dev_priv = dev->dev_private; 1538 drm_i915_private_t *dev_priv = dev->dev_private;
1566 struct drm_i915_gem_object *obj_priv, *next; 1539 struct drm_i915_gem_object *obj_priv, *next;
@@ -1571,12 +1544,13 @@ i915_gem_process_flushing_list(struct drm_device *dev,
1571 struct drm_gem_object *obj = &obj_priv->base; 1544 struct drm_gem_object *obj = &obj_priv->base;
1572 1545
1573 if ((obj->write_domain & flush_domains) == 1546 if ((obj->write_domain & flush_domains) ==
1574 obj->write_domain) { 1547 obj->write_domain &&
1548 obj_priv->ring->ring_flag == ring->ring_flag) {
1575 uint32_t old_write_domain = obj->write_domain; 1549 uint32_t old_write_domain = obj->write_domain;
1576 1550
1577 obj->write_domain = 0; 1551 obj->write_domain = 0;
1578 list_del_init(&obj_priv->gpu_write_list); 1552 list_del_init(&obj_priv->gpu_write_list);
1579 i915_gem_object_move_to_active(obj, seqno); 1553 i915_gem_object_move_to_active(obj, seqno, ring);
1580 1554
1581 /* update the fence lru list */ 1555 /* update the fence lru list */
1582 if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { 1556 if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
@@ -1593,31 +1567,15 @@ i915_gem_process_flushing_list(struct drm_device *dev,
1593 } 1567 }
1594} 1568}
1595 1569
1596#define PIPE_CONTROL_FLUSH(addr) \
1597 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \
1598 PIPE_CONTROL_DEPTH_STALL); \
1599 OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \
1600 OUT_RING(0); \
1601 OUT_RING(0); \
1602
1603/**
1604 * Creates a new sequence number, emitting a write of it to the status page
1605 * plus an interrupt, which will trigger i915_user_interrupt_handler.
1606 *
1607 * Must be called with struct_lock held.
1608 *
1609 * Returned sequence numbers are nonzero on success.
1610 */
1611uint32_t 1570uint32_t
1612i915_add_request(struct drm_device *dev, struct drm_file *file_priv, 1571i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1613 uint32_t flush_domains) 1572 uint32_t flush_domains, struct intel_ring_buffer *ring)
1614{ 1573{
1615 drm_i915_private_t *dev_priv = dev->dev_private; 1574 drm_i915_private_t *dev_priv = dev->dev_private;
1616 struct drm_i915_file_private *i915_file_priv = NULL; 1575 struct drm_i915_file_private *i915_file_priv = NULL;
1617 struct drm_i915_gem_request *request; 1576 struct drm_i915_gem_request *request;
1618 uint32_t seqno; 1577 uint32_t seqno;
1619 int was_empty; 1578 int was_empty;
1620 RING_LOCALS;
1621 1579
1622 if (file_priv != NULL) 1580 if (file_priv != NULL)
1623 i915_file_priv = file_priv->driver_priv; 1581 i915_file_priv = file_priv->driver_priv;
@@ -1626,62 +1584,14 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1626 if (request == NULL) 1584 if (request == NULL)
1627 return 0; 1585 return 0;
1628 1586
1629 /* Grab the seqno we're going to make this request be, and bump the 1587 seqno = ring->add_request(dev, ring, file_priv, flush_domains);
1630 * next (skipping 0 so it can be the reserved no-seqno value).
1631 */
1632 seqno = dev_priv->mm.next_gem_seqno;
1633 dev_priv->mm.next_gem_seqno++;
1634 if (dev_priv->mm.next_gem_seqno == 0)
1635 dev_priv->mm.next_gem_seqno++;
1636
1637 if (HAS_PIPE_CONTROL(dev)) {
1638 u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
1639
1640 /*
1641 * Workaround qword write incoherence by flushing the
1642 * PIPE_NOTIFY buffers out to memory before requesting
1643 * an interrupt.
1644 */
1645 BEGIN_LP_RING(32);
1646 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
1647 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
1648 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
1649 OUT_RING(seqno);
1650 OUT_RING(0);
1651 PIPE_CONTROL_FLUSH(scratch_addr);
1652 scratch_addr += 128; /* write to separate cachelines */
1653 PIPE_CONTROL_FLUSH(scratch_addr);
1654 scratch_addr += 128;
1655 PIPE_CONTROL_FLUSH(scratch_addr);
1656 scratch_addr += 128;
1657 PIPE_CONTROL_FLUSH(scratch_addr);
1658 scratch_addr += 128;
1659 PIPE_CONTROL_FLUSH(scratch_addr);
1660 scratch_addr += 128;
1661 PIPE_CONTROL_FLUSH(scratch_addr);
1662 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
1663 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
1664 PIPE_CONTROL_NOTIFY);
1665 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
1666 OUT_RING(seqno);
1667 OUT_RING(0);
1668 ADVANCE_LP_RING();
1669 } else {
1670 BEGIN_LP_RING(4);
1671 OUT_RING(MI_STORE_DWORD_INDEX);
1672 OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
1673 OUT_RING(seqno);
1674
1675 OUT_RING(MI_USER_INTERRUPT);
1676 ADVANCE_LP_RING();
1677 }
1678
1679 DRM_DEBUG_DRIVER("%d\n", seqno);
1680 1588
1681 request->seqno = seqno; 1589 request->seqno = seqno;
1590 request->ring = ring;
1682 request->emitted_jiffies = jiffies; 1591 request->emitted_jiffies = jiffies;
1683 was_empty = list_empty(&dev_priv->mm.request_list); 1592 was_empty = list_empty(&ring->request_list);
1684 list_add_tail(&request->list, &dev_priv->mm.request_list); 1593 list_add_tail(&request->list, &ring->request_list);
1594
1685 if (i915_file_priv) { 1595 if (i915_file_priv) {
1686 list_add_tail(&request->client_list, 1596 list_add_tail(&request->client_list,
1687 &i915_file_priv->mm.request_list); 1597 &i915_file_priv->mm.request_list);
@@ -1693,7 +1603,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1693 * domain we're flushing with our flush. 1603 * domain we're flushing with our flush.
1694 */ 1604 */
1695 if (flush_domains != 0) 1605 if (flush_domains != 0)
1696 i915_gem_process_flushing_list(dev, flush_domains, seqno); 1606 i915_gem_process_flushing_list(dev, flush_domains, seqno, ring);
1697 1607
1698 if (!dev_priv->mm.suspended) { 1608 if (!dev_priv->mm.suspended) {
1699 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); 1609 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
@@ -1710,20 +1620,16 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1710 * before signalling the CPU 1620 * before signalling the CPU
1711 */ 1621 */
1712static uint32_t 1622static uint32_t
1713i915_retire_commands(struct drm_device *dev) 1623i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring)
1714{ 1624{
1715 drm_i915_private_t *dev_priv = dev->dev_private;
1716 uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
1717 uint32_t flush_domains = 0; 1625 uint32_t flush_domains = 0;
1718 RING_LOCALS;
1719 1626
1720 /* The sampler always gets flushed on i965 (sigh) */ 1627 /* The sampler always gets flushed on i965 (sigh) */
1721 if (IS_I965G(dev)) 1628 if (IS_I965G(dev))
1722 flush_domains |= I915_GEM_DOMAIN_SAMPLER; 1629 flush_domains |= I915_GEM_DOMAIN_SAMPLER;
1723 BEGIN_LP_RING(2); 1630
1724 OUT_RING(cmd); 1631 ring->flush(dev, ring,
1725 OUT_RING(0); /* noop */ 1632 I915_GEM_DOMAIN_COMMAND, flush_domains);
1726 ADVANCE_LP_RING();
1727 return flush_domains; 1633 return flush_domains;
1728} 1634}
1729 1635
@@ -1743,11 +1649,11 @@ i915_gem_retire_request(struct drm_device *dev,
1743 * by the ringbuffer to the flushing/inactive lists as appropriate. 1649 * by the ringbuffer to the flushing/inactive lists as appropriate.
1744 */ 1650 */
1745 spin_lock(&dev_priv->mm.active_list_lock); 1651 spin_lock(&dev_priv->mm.active_list_lock);
1746 while (!list_empty(&dev_priv->mm.active_list)) { 1652 while (!list_empty(&request->ring->active_list)) {
1747 struct drm_gem_object *obj; 1653 struct drm_gem_object *obj;
1748 struct drm_i915_gem_object *obj_priv; 1654 struct drm_i915_gem_object *obj_priv;
1749 1655
1750 obj_priv = list_first_entry(&dev_priv->mm.active_list, 1656 obj_priv = list_first_entry(&request->ring->active_list,
1751 struct drm_i915_gem_object, 1657 struct drm_i915_gem_object,
1752 list); 1658 list);
1753 obj = &obj_priv->base; 1659 obj = &obj_priv->base;
@@ -1794,35 +1700,33 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
1794} 1700}
1795 1701
1796uint32_t 1702uint32_t
1797i915_get_gem_seqno(struct drm_device *dev) 1703i915_get_gem_seqno(struct drm_device *dev,
1704 struct intel_ring_buffer *ring)
1798{ 1705{
1799 drm_i915_private_t *dev_priv = dev->dev_private; 1706 return ring->get_gem_seqno(dev, ring);
1800
1801 if (HAS_PIPE_CONTROL(dev))
1802 return ((volatile u32 *)(dev_priv->seqno_page))[0];
1803 else
1804 return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
1805} 1707}
1806 1708
1807/** 1709/**
1808 * This function clears the request list as sequence numbers are passed. 1710 * This function clears the request list as sequence numbers are passed.
1809 */ 1711 */
1810void 1712void
1811i915_gem_retire_requests(struct drm_device *dev) 1713i915_gem_retire_requests(struct drm_device *dev,
1714 struct intel_ring_buffer *ring)
1812{ 1715{
1813 drm_i915_private_t *dev_priv = dev->dev_private; 1716 drm_i915_private_t *dev_priv = dev->dev_private;
1814 uint32_t seqno; 1717 uint32_t seqno;
1815 1718
1816 if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list)) 1719 if (!ring->status_page.page_addr
1720 || list_empty(&ring->request_list))
1817 return; 1721 return;
1818 1722
1819 seqno = i915_get_gem_seqno(dev); 1723 seqno = i915_get_gem_seqno(dev, ring);
1820 1724
1821 while (!list_empty(&dev_priv->mm.request_list)) { 1725 while (!list_empty(&ring->request_list)) {
1822 struct drm_i915_gem_request *request; 1726 struct drm_i915_gem_request *request;
1823 uint32_t retiring_seqno; 1727 uint32_t retiring_seqno;
1824 1728
1825 request = list_first_entry(&dev_priv->mm.request_list, 1729 request = list_first_entry(&ring->request_list,
1826 struct drm_i915_gem_request, 1730 struct drm_i915_gem_request,
1827 list); 1731 list);
1828 retiring_seqno = request->seqno; 1732 retiring_seqno = request->seqno;
@@ -1840,7 +1744,8 @@ i915_gem_retire_requests(struct drm_device *dev)
1840 1744
1841 if (unlikely (dev_priv->trace_irq_seqno && 1745 if (unlikely (dev_priv->trace_irq_seqno &&
1842 i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { 1746 i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) {
1843 i915_user_irq_put(dev); 1747
1748 ring->user_irq_put(dev, ring);
1844 dev_priv->trace_irq_seqno = 0; 1749 dev_priv->trace_irq_seqno = 0;
1845 } 1750 }
1846} 1751}
@@ -1856,15 +1761,22 @@ i915_gem_retire_work_handler(struct work_struct *work)
1856 dev = dev_priv->dev; 1761 dev = dev_priv->dev;
1857 1762
1858 mutex_lock(&dev->struct_mutex); 1763 mutex_lock(&dev->struct_mutex);
1859 i915_gem_retire_requests(dev); 1764 i915_gem_retire_requests(dev, &dev_priv->render_ring);
1765
1766 if (HAS_BSD(dev))
1767 i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
1768
1860 if (!dev_priv->mm.suspended && 1769 if (!dev_priv->mm.suspended &&
1861 !list_empty(&dev_priv->mm.request_list)) 1770 (!list_empty(&dev_priv->render_ring.request_list) ||
1771 (HAS_BSD(dev) &&
1772 !list_empty(&dev_priv->bsd_ring.request_list))))
1862 queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); 1773 queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
1863 mutex_unlock(&dev->struct_mutex); 1774 mutex_unlock(&dev->struct_mutex);
1864} 1775}
1865 1776
1866int 1777int
1867i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) 1778i915_do_wait_request(struct drm_device *dev, uint32_t seqno,
1779 int interruptible, struct intel_ring_buffer *ring)
1868{ 1780{
1869 drm_i915_private_t *dev_priv = dev->dev_private; 1781 drm_i915_private_t *dev_priv = dev->dev_private;
1870 u32 ier; 1782 u32 ier;
@@ -1875,7 +1787,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
1875 if (atomic_read(&dev_priv->mm.wedged)) 1787 if (atomic_read(&dev_priv->mm.wedged))
1876 return -EIO; 1788 return -EIO;
1877 1789
1878 if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { 1790 if (!i915_seqno_passed(ring->get_gem_seqno(dev, ring), seqno)) {
1879 if (HAS_PCH_SPLIT(dev)) 1791 if (HAS_PCH_SPLIT(dev))
1880 ier = I915_READ(DEIER) | I915_READ(GTIER); 1792 ier = I915_READ(DEIER) | I915_READ(GTIER);
1881 else 1793 else
@@ -1889,19 +1801,21 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
1889 1801
1890 trace_i915_gem_request_wait_begin(dev, seqno); 1802 trace_i915_gem_request_wait_begin(dev, seqno);
1891 1803
1892 dev_priv->mm.waiting_gem_seqno = seqno; 1804 ring->waiting_gem_seqno = seqno;
1893 i915_user_irq_get(dev); 1805 ring->user_irq_get(dev, ring);
1894 if (interruptible) 1806 if (interruptible)
1895 ret = wait_event_interruptible(dev_priv->irq_queue, 1807 ret = wait_event_interruptible(ring->irq_queue,
1896 i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || 1808 i915_seqno_passed(
1897 atomic_read(&dev_priv->mm.wedged)); 1809 ring->get_gem_seqno(dev, ring), seqno)
1810 || atomic_read(&dev_priv->mm.wedged));
1898 else 1811 else
1899 wait_event(dev_priv->irq_queue, 1812 wait_event(ring->irq_queue,
1900 i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || 1813 i915_seqno_passed(
1901 atomic_read(&dev_priv->mm.wedged)); 1814 ring->get_gem_seqno(dev, ring), seqno)
1815 || atomic_read(&dev_priv->mm.wedged));
1902 1816
1903 i915_user_irq_put(dev); 1817 ring->user_irq_put(dev, ring);
1904 dev_priv->mm.waiting_gem_seqno = 0; 1818 ring->waiting_gem_seqno = 0;
1905 1819
1906 trace_i915_gem_request_wait_end(dev, seqno); 1820 trace_i915_gem_request_wait_end(dev, seqno);
1907 } 1821 }
@@ -1910,7 +1824,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
1910 1824
1911 if (ret && ret != -ERESTARTSYS) 1825 if (ret && ret != -ERESTARTSYS)
1912 DRM_ERROR("%s returns %d (awaiting %d at %d)\n", 1826 DRM_ERROR("%s returns %d (awaiting %d at %d)\n",
1913 __func__, ret, seqno, i915_get_gem_seqno(dev)); 1827 __func__, ret, seqno, ring->get_gem_seqno(dev, ring));
1914 1828
1915 /* Directly dispatch request retiring. While we have the work queue 1829 /* Directly dispatch request retiring. While we have the work queue
1916 * to handle this, the waiter on a request often wants an associated 1830 * to handle this, the waiter on a request often wants an associated
@@ -1918,7 +1832,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
1918 * a separate wait queue to handle that. 1832 * a separate wait queue to handle that.
1919 */ 1833 */
1920 if (ret == 0) 1834 if (ret == 0)
1921 i915_gem_retire_requests(dev); 1835 i915_gem_retire_requests(dev, ring);
1922 1836
1923 return ret; 1837 return ret;
1924} 1838}
@@ -1928,9 +1842,10 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
1928 * request and object lists appropriately for that event. 1842 * request and object lists appropriately for that event.
1929 */ 1843 */
1930static int 1844static int
1931i915_wait_request(struct drm_device *dev, uint32_t seqno) 1845i915_wait_request(struct drm_device *dev, uint32_t seqno,
1846 struct intel_ring_buffer *ring)
1932{ 1847{
1933 return i915_do_wait_request(dev, seqno, 1); 1848 return i915_do_wait_request(dev, seqno, 1, ring);
1934} 1849}
1935 1850
1936static void 1851static void
@@ -1939,71 +1854,29 @@ i915_gem_flush(struct drm_device *dev,
1939 uint32_t flush_domains) 1854 uint32_t flush_domains)
1940{ 1855{
1941 drm_i915_private_t *dev_priv = dev->dev_private; 1856 drm_i915_private_t *dev_priv = dev->dev_private;
1942 uint32_t cmd;
1943 RING_LOCALS;
1944
1945#if WATCH_EXEC
1946 DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
1947 invalidate_domains, flush_domains);
1948#endif
1949 trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno,
1950 invalidate_domains, flush_domains);
1951
1952 if (flush_domains & I915_GEM_DOMAIN_CPU) 1857 if (flush_domains & I915_GEM_DOMAIN_CPU)
1953 drm_agp_chipset_flush(dev); 1858 drm_agp_chipset_flush(dev);
1859 dev_priv->render_ring.flush(dev, &dev_priv->render_ring,
1860 invalidate_domains,
1861 flush_domains);
1862
1863 if (HAS_BSD(dev))
1864 dev_priv->bsd_ring.flush(dev, &dev_priv->bsd_ring,
1865 invalidate_domains,
1866 flush_domains);
1867}
1954 1868
1955 if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { 1869static void
1956 /* 1870i915_gem_flush_ring(struct drm_device *dev,
1957 * read/write caches: 1871 uint32_t invalidate_domains,
1958 * 1872 uint32_t flush_domains,
1959 * I915_GEM_DOMAIN_RENDER is always invalidated, but is 1873 struct intel_ring_buffer *ring)
1960 * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is 1874{
1961 * also flushed at 2d versus 3d pipeline switches. 1875 if (flush_domains & I915_GEM_DOMAIN_CPU)
1962 * 1876 drm_agp_chipset_flush(dev);
1963 * read-only caches: 1877 ring->flush(dev, ring,
1964 * 1878 invalidate_domains,
1965 * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if 1879 flush_domains);
1966 * MI_READ_FLUSH is set, and is always flushed on 965.
1967 *
1968 * I915_GEM_DOMAIN_COMMAND may not exist?
1969 *
1970 * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
1971 * invalidated when MI_EXE_FLUSH is set.
1972 *
1973 * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
1974 * invalidated with every MI_FLUSH.
1975 *
1976 * TLBs:
1977 *
1978 * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
1979 * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
1980 * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
1981 * are flushed at any MI_FLUSH.
1982 */
1983
1984 cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
1985 if ((invalidate_domains|flush_domains) &
1986 I915_GEM_DOMAIN_RENDER)
1987 cmd &= ~MI_NO_WRITE_FLUSH;
1988 if (!IS_I965G(dev)) {
1989 /*
1990 * On the 965, the sampler cache always gets flushed
1991 * and this bit is reserved.
1992 */
1993 if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
1994 cmd |= MI_READ_FLUSH;
1995 }
1996 if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
1997 cmd |= MI_EXE_FLUSH;
1998
1999#if WATCH_EXEC
2000 DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
2001#endif
2002 BEGIN_LP_RING(2);
2003 OUT_RING(cmd);
2004 OUT_RING(MI_NOOP);
2005 ADVANCE_LP_RING();
2006 }
2007} 1880}
2008 1881
2009/** 1882/**
@@ -2030,7 +1903,8 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj)
2030 DRM_INFO("%s: object %p wait for seqno %08x\n", 1903 DRM_INFO("%s: object %p wait for seqno %08x\n",
2031 __func__, obj, obj_priv->last_rendering_seqno); 1904 __func__, obj, obj_priv->last_rendering_seqno);
2032#endif 1905#endif
2033 ret = i915_wait_request(dev, obj_priv->last_rendering_seqno); 1906 ret = i915_wait_request(dev,
1907 obj_priv->last_rendering_seqno, obj_priv->ring);
2034 if (ret != 0) 1908 if (ret != 0)
2035 return ret; 1909 return ret;
2036 } 1910 }
@@ -2146,11 +2020,14 @@ i915_gpu_idle(struct drm_device *dev)
2146{ 2020{
2147 drm_i915_private_t *dev_priv = dev->dev_private; 2021 drm_i915_private_t *dev_priv = dev->dev_private;
2148 bool lists_empty; 2022 bool lists_empty;
2149 uint32_t seqno; 2023 uint32_t seqno1, seqno2;
2024 int ret;
2150 2025
2151 spin_lock(&dev_priv->mm.active_list_lock); 2026 spin_lock(&dev_priv->mm.active_list_lock);
2152 lists_empty = list_empty(&dev_priv->mm.flushing_list) && 2027 lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
2153 list_empty(&dev_priv->mm.active_list); 2028 list_empty(&dev_priv->render_ring.active_list) &&
2029 (!HAS_BSD(dev) ||
2030 list_empty(&dev_priv->bsd_ring.active_list)));
2154 spin_unlock(&dev_priv->mm.active_list_lock); 2031 spin_unlock(&dev_priv->mm.active_list_lock);
2155 2032
2156 if (lists_empty) 2033 if (lists_empty)
@@ -2158,11 +2035,25 @@ i915_gpu_idle(struct drm_device *dev)
2158 2035
2159 /* Flush everything onto the inactive list. */ 2036 /* Flush everything onto the inactive list. */
2160 i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); 2037 i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
2161 seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS); 2038 seqno1 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS,
2162 if (seqno == 0) 2039 &dev_priv->render_ring);
2040 if (seqno1 == 0)
2163 return -ENOMEM; 2041 return -ENOMEM;
2042 ret = i915_wait_request(dev, seqno1, &dev_priv->render_ring);
2043
2044 if (HAS_BSD(dev)) {
2045 seqno2 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS,
2046 &dev_priv->bsd_ring);
2047 if (seqno2 == 0)
2048 return -ENOMEM;
2049
2050 ret = i915_wait_request(dev, seqno2, &dev_priv->bsd_ring);
2051 if (ret)
2052 return ret;
2053 }
2054
2164 2055
2165 return i915_wait_request(dev, seqno); 2056 return ret;
2166} 2057}
2167 2058
2168static int 2059static int
@@ -2175,7 +2066,9 @@ i915_gem_evict_everything(struct drm_device *dev)
2175 spin_lock(&dev_priv->mm.active_list_lock); 2066 spin_lock(&dev_priv->mm.active_list_lock);
2176 lists_empty = (list_empty(&dev_priv->mm.inactive_list) && 2067 lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
2177 list_empty(&dev_priv->mm.flushing_list) && 2068 list_empty(&dev_priv->mm.flushing_list) &&
2178 list_empty(&dev_priv->mm.active_list)); 2069 list_empty(&dev_priv->render_ring.active_list) &&
2070 (!HAS_BSD(dev)
2071 || list_empty(&dev_priv->bsd_ring.active_list)));
2179 spin_unlock(&dev_priv->mm.active_list_lock); 2072 spin_unlock(&dev_priv->mm.active_list_lock);
2180 2073
2181 if (lists_empty) 2074 if (lists_empty)
@@ -2195,7 +2088,9 @@ i915_gem_evict_everything(struct drm_device *dev)
2195 spin_lock(&dev_priv->mm.active_list_lock); 2088 spin_lock(&dev_priv->mm.active_list_lock);
2196 lists_empty = (list_empty(&dev_priv->mm.inactive_list) && 2089 lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
2197 list_empty(&dev_priv->mm.flushing_list) && 2090 list_empty(&dev_priv->mm.flushing_list) &&
2198 list_empty(&dev_priv->mm.active_list)); 2091 list_empty(&dev_priv->render_ring.active_list) &&
2092 (!HAS_BSD(dev)
2093 || list_empty(&dev_priv->bsd_ring.active_list)));
2199 spin_unlock(&dev_priv->mm.active_list_lock); 2094 spin_unlock(&dev_priv->mm.active_list_lock);
2200 BUG_ON(!lists_empty); 2095 BUG_ON(!lists_empty);
2201 2096
@@ -2209,8 +2104,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
2209 struct drm_gem_object *obj; 2104 struct drm_gem_object *obj;
2210 int ret; 2105 int ret;
2211 2106
2107 struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
2108 struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring;
2212 for (;;) { 2109 for (;;) {
2213 i915_gem_retire_requests(dev); 2110 i915_gem_retire_requests(dev, render_ring);
2111
2112 if (HAS_BSD(dev))
2113 i915_gem_retire_requests(dev, bsd_ring);
2214 2114
2215 /* If there's an inactive buffer available now, grab it 2115 /* If there's an inactive buffer available now, grab it
2216 * and be done. 2116 * and be done.
@@ -2234,14 +2134,30 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
2234 * things, wait for the next to finish and hopefully leave us 2134 * things, wait for the next to finish and hopefully leave us
2235 * a buffer to evict. 2135 * a buffer to evict.
2236 */ 2136 */
2237 if (!list_empty(&dev_priv->mm.request_list)) { 2137 if (!list_empty(&render_ring->request_list)) {
2138 struct drm_i915_gem_request *request;
2139
2140 request = list_first_entry(&render_ring->request_list,
2141 struct drm_i915_gem_request,
2142 list);
2143
2144 ret = i915_wait_request(dev,
2145 request->seqno, request->ring);
2146 if (ret)
2147 return ret;
2148
2149 continue;
2150 }
2151
2152 if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) {
2238 struct drm_i915_gem_request *request; 2153 struct drm_i915_gem_request *request;
2239 2154
2240 request = list_first_entry(&dev_priv->mm.request_list, 2155 request = list_first_entry(&bsd_ring->request_list,
2241 struct drm_i915_gem_request, 2156 struct drm_i915_gem_request,
2242 list); 2157 list);
2243 2158
2244 ret = i915_wait_request(dev, request->seqno); 2159 ret = i915_wait_request(dev,
2160 request->seqno, request->ring);
2245 if (ret) 2161 if (ret)
2246 return ret; 2162 return ret;
2247 2163
@@ -2268,10 +2184,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
2268 if (obj != NULL) { 2184 if (obj != NULL) {
2269 uint32_t seqno; 2185 uint32_t seqno;
2270 2186
2271 i915_gem_flush(dev, 2187 i915_gem_flush_ring(dev,
2188 obj->write_domain,
2272 obj->write_domain, 2189 obj->write_domain,
2273 obj->write_domain); 2190 obj_priv->ring);
2274 seqno = i915_add_request(dev, NULL, obj->write_domain); 2191 seqno = i915_add_request(dev, NULL,
2192 obj->write_domain,
2193 obj_priv->ring);
2275 if (seqno == 0) 2194 if (seqno == 0)
2276 return -ENOMEM; 2195 return -ENOMEM;
2277 continue; 2196 continue;
@@ -2299,6 +2218,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,
2299 struct inode *inode; 2218 struct inode *inode;
2300 struct page *page; 2219 struct page *page;
2301 2220
2221 BUG_ON(obj_priv->pages_refcount
2222 == DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT);
2223
2302 if (obj_priv->pages_refcount++ != 0) 2224 if (obj_priv->pages_refcount++ != 0)
2303 return 0; 2225 return 0;
2304 2226
@@ -2697,6 +2619,14 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2697 return -EINVAL; 2619 return -EINVAL;
2698 } 2620 }
2699 2621
2622 /* If the object is bigger than the entire aperture, reject it early
2623 * before evicting everything in a vain attempt to find space.
2624 */
2625 if (obj->size > dev->gtt_total) {
2626 DRM_ERROR("Attempting to bind an object larger than the aperture\n");
2627 return -E2BIG;
2628 }
2629
2700 search_free: 2630 search_free:
2701 free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, 2631 free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
2702 obj->size, alignment, 0); 2632 obj->size, alignment, 0);
@@ -2807,6 +2737,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
2807{ 2737{
2808 struct drm_device *dev = obj->dev; 2738 struct drm_device *dev = obj->dev;
2809 uint32_t old_write_domain; 2739 uint32_t old_write_domain;
2740 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
2810 2741
2811 if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) 2742 if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0)
2812 return; 2743 return;
@@ -2814,7 +2745,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
2814 /* Queue the GPU write cache flushing we need. */ 2745 /* Queue the GPU write cache flushing we need. */
2815 old_write_domain = obj->write_domain; 2746 old_write_domain = obj->write_domain;
2816 i915_gem_flush(dev, 0, obj->write_domain); 2747 i915_gem_flush(dev, 0, obj->write_domain);
2817 (void) i915_add_request(dev, NULL, obj->write_domain); 2748 (void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring);
2818 BUG_ON(obj->write_domain); 2749 BUG_ON(obj->write_domain);
2819 2750
2820 trace_i915_gem_object_change_domain(obj, 2751 trace_i915_gem_object_change_domain(obj,
@@ -2954,23 +2885,24 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
2954 DRM_INFO("%s: object %p wait for seqno %08x\n", 2885 DRM_INFO("%s: object %p wait for seqno %08x\n",
2955 __func__, obj, obj_priv->last_rendering_seqno); 2886 __func__, obj, obj_priv->last_rendering_seqno);
2956#endif 2887#endif
2957 ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0); 2888 ret = i915_do_wait_request(dev,
2889 obj_priv->last_rendering_seqno,
2890 0,
2891 obj_priv->ring);
2958 if (ret != 0) 2892 if (ret != 0)
2959 return ret; 2893 return ret;
2960 } 2894 }
2961 2895
2896 i915_gem_object_flush_cpu_write_domain(obj);
2897
2962 old_write_domain = obj->write_domain; 2898 old_write_domain = obj->write_domain;
2963 old_read_domains = obj->read_domains; 2899 old_read_domains = obj->read_domains;
2964 2900
2965 obj->read_domains &= I915_GEM_DOMAIN_GTT;
2966
2967 i915_gem_object_flush_cpu_write_domain(obj);
2968
2969 /* It should now be out of any other write domains, and we can update 2901 /* It should now be out of any other write domains, and we can update
2970 * the domain values for our changes. 2902 * the domain values for our changes.
2971 */ 2903 */
2972 BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); 2904 BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
2973 obj->read_domains |= I915_GEM_DOMAIN_GTT; 2905 obj->read_domains = I915_GEM_DOMAIN_GTT;
2974 obj->write_domain = I915_GEM_DOMAIN_GTT; 2906 obj->write_domain = I915_GEM_DOMAIN_GTT;
2975 obj_priv->dirty = 1; 2907 obj_priv->dirty = 1;
2976 2908
@@ -3354,9 +3286,13 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
3354 obj_priv->tiling_mode != I915_TILING_NONE; 3286 obj_priv->tiling_mode != I915_TILING_NONE;
3355 3287
3356 /* Check fence reg constraints and rebind if necessary */ 3288 /* Check fence reg constraints and rebind if necessary */
3357 if (need_fence && !i915_gem_object_fence_offset_ok(obj, 3289 if (need_fence &&
3358 obj_priv->tiling_mode)) 3290 !i915_gem_object_fence_offset_ok(obj,
3359 i915_gem_object_unbind(obj); 3291 obj_priv->tiling_mode)) {
3292 ret = i915_gem_object_unbind(obj);
3293 if (ret)
3294 return ret;
3295 }
3360 3296
3361 /* Choose the GTT offset for our buffer and put it there. */ 3297 /* Choose the GTT offset for our buffer and put it there. */
3362 ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); 3298 ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
@@ -3370,9 +3306,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
3370 if (need_fence) { 3306 if (need_fence) {
3371 ret = i915_gem_object_get_fence_reg(obj); 3307 ret = i915_gem_object_get_fence_reg(obj);
3372 if (ret != 0) { 3308 if (ret != 0) {
3373 if (ret != -EBUSY && ret != -ERESTARTSYS)
3374 DRM_ERROR("Failure to install fence: %d\n",
3375 ret);
3376 i915_gem_object_unpin(obj); 3309 i915_gem_object_unpin(obj);
3377 return ret; 3310 return ret;
3378 } 3311 }
@@ -3545,62 +3478,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
3545 return 0; 3478 return 0;
3546} 3479}
3547 3480
3548/** Dispatch a batchbuffer to the ring
3549 */
3550static int
3551i915_dispatch_gem_execbuffer(struct drm_device *dev,
3552 struct drm_i915_gem_execbuffer2 *exec,
3553 struct drm_clip_rect *cliprects,
3554 uint64_t exec_offset)
3555{
3556 drm_i915_private_t *dev_priv = dev->dev_private;
3557 int nbox = exec->num_cliprects;
3558 int i = 0, count;
3559 uint32_t exec_start, exec_len;
3560 RING_LOCALS;
3561
3562 exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
3563 exec_len = (uint32_t) exec->batch_len;
3564
3565 trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1);
3566
3567 count = nbox ? nbox : 1;
3568
3569 for (i = 0; i < count; i++) {
3570 if (i < nbox) {
3571 int ret = i915_emit_box(dev, cliprects, i,
3572 exec->DR1, exec->DR4);
3573 if (ret)
3574 return ret;
3575 }
3576
3577 if (IS_I830(dev) || IS_845G(dev)) {
3578 BEGIN_LP_RING(4);
3579 OUT_RING(MI_BATCH_BUFFER);
3580 OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3581 OUT_RING(exec_start + exec_len - 4);
3582 OUT_RING(0);
3583 ADVANCE_LP_RING();
3584 } else {
3585 BEGIN_LP_RING(2);
3586 if (IS_I965G(dev)) {
3587 OUT_RING(MI_BATCH_BUFFER_START |
3588 (2 << 6) |
3589 MI_BATCH_NON_SECURE_I965);
3590 OUT_RING(exec_start);
3591 } else {
3592 OUT_RING(MI_BATCH_BUFFER_START |
3593 (2 << 6));
3594 OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3595 }
3596 ADVANCE_LP_RING();
3597 }
3598 }
3599
3600 /* XXX breadcrumb */
3601 return 0;
3602}
3603
3604/* Throttle our rendering by waiting until the ring has completed our requests 3481/* Throttle our rendering by waiting until the ring has completed our requests
3605 * emitted over 20 msec ago. 3482 * emitted over 20 msec ago.
3606 * 3483 *
@@ -3629,7 +3506,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
3629 if (time_after_eq(request->emitted_jiffies, recent_enough)) 3506 if (time_after_eq(request->emitted_jiffies, recent_enough))
3630 break; 3507 break;
3631 3508
3632 ret = i915_wait_request(dev, request->seqno); 3509 ret = i915_wait_request(dev, request->seqno, request->ring);
3633 if (ret != 0) 3510 if (ret != 0)
3634 break; 3511 break;
3635 } 3512 }
@@ -3786,10 +3663,22 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
3786 uint32_t seqno, flush_domains, reloc_index; 3663 uint32_t seqno, flush_domains, reloc_index;
3787 int pin_tries, flips; 3664 int pin_tries, flips;
3788 3665
3666 struct intel_ring_buffer *ring = NULL;
3667
3789#if WATCH_EXEC 3668#if WATCH_EXEC
3790 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", 3669 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
3791 (int) args->buffers_ptr, args->buffer_count, args->batch_len); 3670 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
3792#endif 3671#endif
3672 if (args->flags & I915_EXEC_BSD) {
3673 if (!HAS_BSD(dev)) {
3674 DRM_ERROR("execbuf with wrong flag\n");
3675 return -EINVAL;
3676 }
3677 ring = &dev_priv->bsd_ring;
3678 } else {
3679 ring = &dev_priv->render_ring;
3680 }
3681
3793 3682
3794 if (args->buffer_count < 1) { 3683 if (args->buffer_count < 1) {
3795 DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); 3684 DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
@@ -3902,11 +3791,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
3902 if (ret != -ENOSPC || pin_tries >= 1) { 3791 if (ret != -ENOSPC || pin_tries >= 1) {
3903 if (ret != -ERESTARTSYS) { 3792 if (ret != -ERESTARTSYS) {
3904 unsigned long long total_size = 0; 3793 unsigned long long total_size = 0;
3905 for (i = 0; i < args->buffer_count; i++) 3794 int num_fences = 0;
3795 for (i = 0; i < args->buffer_count; i++) {
3796 obj_priv = object_list[i]->driver_private;
3797
3906 total_size += object_list[i]->size; 3798 total_size += object_list[i]->size;
3907 DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes: %d\n", 3799 num_fences +=
3800 exec_list[i].flags & EXEC_OBJECT_NEEDS_FENCE &&
3801 obj_priv->tiling_mode != I915_TILING_NONE;
3802 }
3803 DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes, %d fences: %d\n",
3908 pinned+1, args->buffer_count, 3804 pinned+1, args->buffer_count,
3909 total_size, ret); 3805 total_size, num_fences,
3806 ret);
3910 DRM_ERROR("%d objects [%d pinned], " 3807 DRM_ERROR("%d objects [%d pinned], "
3911 "%d object bytes [%d pinned], " 3808 "%d object bytes [%d pinned], "
3912 "%d/%d gtt bytes\n", 3809 "%d/%d gtt bytes\n",
@@ -3976,9 +3873,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
3976 i915_gem_flush(dev, 3873 i915_gem_flush(dev,
3977 dev->invalidate_domains, 3874 dev->invalidate_domains,
3978 dev->flush_domains); 3875 dev->flush_domains);
3979 if (dev->flush_domains & I915_GEM_GPU_DOMAINS) 3876 if (dev->flush_domains & I915_GEM_GPU_DOMAINS) {
3980 (void)i915_add_request(dev, file_priv, 3877 (void)i915_add_request(dev, file_priv,
3981 dev->flush_domains); 3878 dev->flush_domains,
3879 &dev_priv->render_ring);
3880
3881 if (HAS_BSD(dev))
3882 (void)i915_add_request(dev, file_priv,
3883 dev->flush_domains,
3884 &dev_priv->bsd_ring);
3885 }
3982 } 3886 }
3983 3887
3984 for (i = 0; i < args->buffer_count; i++) { 3888 for (i = 0; i < args->buffer_count; i++) {
@@ -4015,7 +3919,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
4015#endif 3919#endif
4016 3920
4017 /* Exec the batchbuffer */ 3921 /* Exec the batchbuffer */
4018 ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset); 3922 ret = ring->dispatch_gem_execbuffer(dev, ring, args,
3923 cliprects, exec_offset);
4019 if (ret) { 3924 if (ret) {
4020 DRM_ERROR("dispatch failed %d\n", ret); 3925 DRM_ERROR("dispatch failed %d\n", ret);
4021 goto err; 3926 goto err;
@@ -4025,7 +3930,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
4025 * Ensure that the commands in the batch buffer are 3930 * Ensure that the commands in the batch buffer are
4026 * finished before the interrupt fires 3931 * finished before the interrupt fires
4027 */ 3932 */
4028 flush_domains = i915_retire_commands(dev); 3933 flush_domains = i915_retire_commands(dev, ring);
4029 3934
4030 i915_verify_inactive(dev, __FILE__, __LINE__); 3935 i915_verify_inactive(dev, __FILE__, __LINE__);
4031 3936
@@ -4036,12 +3941,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
4036 * *some* interrupts representing completion of buffers that we can 3941 * *some* interrupts representing completion of buffers that we can
4037 * wait on when trying to clear up gtt space). 3942 * wait on when trying to clear up gtt space).
4038 */ 3943 */
4039 seqno = i915_add_request(dev, file_priv, flush_domains); 3944 seqno = i915_add_request(dev, file_priv, flush_domains, ring);
4040 BUG_ON(seqno == 0); 3945 BUG_ON(seqno == 0);
4041 for (i = 0; i < args->buffer_count; i++) { 3946 for (i = 0; i < args->buffer_count; i++) {
4042 struct drm_gem_object *obj = object_list[i]; 3947 struct drm_gem_object *obj = object_list[i];
3948 obj_priv = to_intel_bo(obj);
4043 3949
4044 i915_gem_object_move_to_active(obj, seqno); 3950 i915_gem_object_move_to_active(obj, seqno, ring);
4045#if WATCH_LRU 3951#if WATCH_LRU
4046 DRM_INFO("%s: move to exec list %p\n", __func__, obj); 3952 DRM_INFO("%s: move to exec list %p\n", __func__, obj);
4047#endif 3953#endif
@@ -4153,7 +4059,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
4153 exec2.DR4 = args->DR4; 4059 exec2.DR4 = args->DR4;
4154 exec2.num_cliprects = args->num_cliprects; 4060 exec2.num_cliprects = args->num_cliprects;
4155 exec2.cliprects_ptr = args->cliprects_ptr; 4061 exec2.cliprects_ptr = args->cliprects_ptr;
4156 exec2.flags = 0; 4062 exec2.flags = I915_EXEC_RENDER;
4157 4063
4158 ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); 4064 ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list);
4159 if (!ret) { 4065 if (!ret) {
@@ -4239,7 +4145,20 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
4239 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); 4145 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
4240 int ret; 4146 int ret;
4241 4147
4148 BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT);
4149
4242 i915_verify_inactive(dev, __FILE__, __LINE__); 4150 i915_verify_inactive(dev, __FILE__, __LINE__);
4151
4152 if (obj_priv->gtt_space != NULL) {
4153 if (alignment == 0)
4154 alignment = i915_gem_get_gtt_alignment(obj);
4155 if (obj_priv->gtt_offset & (alignment - 1)) {
4156 ret = i915_gem_object_unbind(obj);
4157 if (ret)
4158 return ret;
4159 }
4160 }
4161
4243 if (obj_priv->gtt_space == NULL) { 4162 if (obj_priv->gtt_space == NULL) {
4244 ret = i915_gem_object_bind_to_gtt(obj, alignment); 4163 ret = i915_gem_object_bind_to_gtt(obj, alignment);
4245 if (ret) 4164 if (ret)
@@ -4392,6 +4311,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
4392 struct drm_i915_gem_busy *args = data; 4311 struct drm_i915_gem_busy *args = data;
4393 struct drm_gem_object *obj; 4312 struct drm_gem_object *obj;
4394 struct drm_i915_gem_object *obj_priv; 4313 struct drm_i915_gem_object *obj_priv;
4314 drm_i915_private_t *dev_priv = dev->dev_private;
4395 4315
4396 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 4316 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4397 if (obj == NULL) { 4317 if (obj == NULL) {
@@ -4406,7 +4326,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
4406 * actually unmasked, and our working set ends up being larger than 4326 * actually unmasked, and our working set ends up being larger than
4407 * required. 4327 * required.
4408 */ 4328 */
4409 i915_gem_retire_requests(dev); 4329 i915_gem_retire_requests(dev, &dev_priv->render_ring);
4330
4331 if (HAS_BSD(dev))
4332 i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
4410 4333
4411 obj_priv = to_intel_bo(obj); 4334 obj_priv = to_intel_bo(obj);
4412 /* Don't count being on the flushing list against the object being 4335 /* Don't count being on the flushing list against the object being
@@ -4573,7 +4496,10 @@ i915_gem_idle(struct drm_device *dev)
4573 4496
4574 mutex_lock(&dev->struct_mutex); 4497 mutex_lock(&dev->struct_mutex);
4575 4498
4576 if (dev_priv->mm.suspended || dev_priv->ring.ring_obj == NULL) { 4499 if (dev_priv->mm.suspended ||
4500 (dev_priv->render_ring.gem_object == NULL) ||
4501 (HAS_BSD(dev) &&
4502 dev_priv->bsd_ring.gem_object == NULL)) {
4577 mutex_unlock(&dev->struct_mutex); 4503 mutex_unlock(&dev->struct_mutex);
4578 return 0; 4504 return 0;
4579 } 4505 }
@@ -4654,71 +4580,6 @@ err:
4654 return ret; 4580 return ret;
4655} 4581}
4656 4582
4657static int
4658i915_gem_init_hws(struct drm_device *dev)
4659{
4660 drm_i915_private_t *dev_priv = dev->dev_private;
4661 struct drm_gem_object *obj;
4662 struct drm_i915_gem_object *obj_priv;
4663 int ret;
4664
4665 /* If we need a physical address for the status page, it's already
4666 * initialized at driver load time.
4667 */
4668 if (!I915_NEED_GFX_HWS(dev))
4669 return 0;
4670
4671 obj = i915_gem_alloc_object(dev, 4096);
4672 if (obj == NULL) {
4673 DRM_ERROR("Failed to allocate status page\n");
4674 ret = -ENOMEM;
4675 goto err;
4676 }
4677 obj_priv = to_intel_bo(obj);
4678 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
4679
4680 ret = i915_gem_object_pin(obj, 4096);
4681 if (ret != 0) {
4682 drm_gem_object_unreference(obj);
4683 goto err_unref;
4684 }
4685
4686 dev_priv->status_gfx_addr = obj_priv->gtt_offset;
4687
4688 dev_priv->hw_status_page = kmap(obj_priv->pages[0]);
4689 if (dev_priv->hw_status_page == NULL) {
4690 DRM_ERROR("Failed to map status page.\n");
4691 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
4692 ret = -EINVAL;
4693 goto err_unpin;
4694 }
4695
4696 if (HAS_PIPE_CONTROL(dev)) {
4697 ret = i915_gem_init_pipe_control(dev);
4698 if (ret)
4699 goto err_unpin;
4700 }
4701
4702 dev_priv->hws_obj = obj;
4703 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
4704 if (IS_GEN6(dev)) {
4705 I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr);
4706 I915_READ(HWS_PGA_GEN6); /* posting read */
4707 } else {
4708 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
4709 I915_READ(HWS_PGA); /* posting read */
4710 }
4711 DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
4712
4713 return 0;
4714
4715err_unpin:
4716 i915_gem_object_unpin(obj);
4717err_unref:
4718 drm_gem_object_unreference(obj);
4719err:
4720 return 0;
4721}
4722 4583
4723static void 4584static void
4724i915_gem_cleanup_pipe_control(struct drm_device *dev) 4585i915_gem_cleanup_pipe_control(struct drm_device *dev)
@@ -4737,146 +4598,46 @@ i915_gem_cleanup_pipe_control(struct drm_device *dev)
4737 dev_priv->seqno_page = NULL; 4598 dev_priv->seqno_page = NULL;
4738} 4599}
4739 4600
4740static void
4741i915_gem_cleanup_hws(struct drm_device *dev)
4742{
4743 drm_i915_private_t *dev_priv = dev->dev_private;
4744 struct drm_gem_object *obj;
4745 struct drm_i915_gem_object *obj_priv;
4746
4747 if (dev_priv->hws_obj == NULL)
4748 return;
4749
4750 obj = dev_priv->hws_obj;
4751 obj_priv = to_intel_bo(obj);
4752
4753 kunmap(obj_priv->pages[0]);
4754 i915_gem_object_unpin(obj);
4755 drm_gem_object_unreference(obj);
4756 dev_priv->hws_obj = NULL;
4757
4758 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
4759 dev_priv->hw_status_page = NULL;
4760
4761 if (HAS_PIPE_CONTROL(dev))
4762 i915_gem_cleanup_pipe_control(dev);
4763
4764 /* Write high address into HWS_PGA when disabling. */
4765 I915_WRITE(HWS_PGA, 0x1ffff000);
4766}
4767
4768int 4601int
4769i915_gem_init_ringbuffer(struct drm_device *dev) 4602i915_gem_init_ringbuffer(struct drm_device *dev)
4770{ 4603{
4771 drm_i915_private_t *dev_priv = dev->dev_private; 4604 drm_i915_private_t *dev_priv = dev->dev_private;
4772 struct drm_gem_object *obj;
4773 struct drm_i915_gem_object *obj_priv;
4774 drm_i915_ring_buffer_t *ring = &dev_priv->ring;
4775 int ret; 4605 int ret;
4776 u32 head;
4777
4778 ret = i915_gem_init_hws(dev);
4779 if (ret != 0)
4780 return ret;
4781 4606
4782 obj = i915_gem_alloc_object(dev, 128 * 1024); 4607 dev_priv->render_ring = render_ring;
4783 if (obj == NULL) {
4784 DRM_ERROR("Failed to allocate ringbuffer\n");
4785 i915_gem_cleanup_hws(dev);
4786 return -ENOMEM;
4787 }
4788 obj_priv = to_intel_bo(obj);
4789 4608
4790 ret = i915_gem_object_pin(obj, 4096); 4609 if (!I915_NEED_GFX_HWS(dev)) {
4791 if (ret != 0) { 4610 dev_priv->render_ring.status_page.page_addr
4792 drm_gem_object_unreference(obj); 4611 = dev_priv->status_page_dmah->vaddr;
4793 i915_gem_cleanup_hws(dev); 4612 memset(dev_priv->render_ring.status_page.page_addr,
4794 return ret; 4613 0, PAGE_SIZE);
4795 } 4614 }
4796 4615
4797 /* Set up the kernel mapping for the ring. */ 4616 if (HAS_PIPE_CONTROL(dev)) {
4798 ring->Size = obj->size; 4617 ret = i915_gem_init_pipe_control(dev);
4799 4618 if (ret)
4800 ring->map.offset = dev->agp->base + obj_priv->gtt_offset; 4619 return ret;
4801 ring->map.size = obj->size;
4802 ring->map.type = 0;
4803 ring->map.flags = 0;
4804 ring->map.mtrr = 0;
4805
4806 drm_core_ioremap_wc(&ring->map, dev);
4807 if (ring->map.handle == NULL) {
4808 DRM_ERROR("Failed to map ringbuffer.\n");
4809 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
4810 i915_gem_object_unpin(obj);
4811 drm_gem_object_unreference(obj);
4812 i915_gem_cleanup_hws(dev);
4813 return -EINVAL;
4814 }
4815 ring->ring_obj = obj;
4816 ring->virtual_start = ring->map.handle;
4817
4818 /* Stop the ring if it's running. */
4819 I915_WRITE(PRB0_CTL, 0);
4820 I915_WRITE(PRB0_TAIL, 0);
4821 I915_WRITE(PRB0_HEAD, 0);
4822
4823 /* Initialize the ring. */
4824 I915_WRITE(PRB0_START, obj_priv->gtt_offset);
4825 head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
4826
4827 /* G45 ring initialization fails to reset head to zero */
4828 if (head != 0) {
4829 DRM_ERROR("Ring head not reset to zero "
4830 "ctl %08x head %08x tail %08x start %08x\n",
4831 I915_READ(PRB0_CTL),
4832 I915_READ(PRB0_HEAD),
4833 I915_READ(PRB0_TAIL),
4834 I915_READ(PRB0_START));
4835 I915_WRITE(PRB0_HEAD, 0);
4836
4837 DRM_ERROR("Ring head forced to zero "
4838 "ctl %08x head %08x tail %08x start %08x\n",
4839 I915_READ(PRB0_CTL),
4840 I915_READ(PRB0_HEAD),
4841 I915_READ(PRB0_TAIL),
4842 I915_READ(PRB0_START));
4843 }
4844
4845 I915_WRITE(PRB0_CTL,
4846 ((obj->size - 4096) & RING_NR_PAGES) |
4847 RING_NO_REPORT |
4848 RING_VALID);
4849
4850 head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
4851
4852 /* If the head is still not zero, the ring is dead */
4853 if (head != 0) {
4854 DRM_ERROR("Ring initialization failed "
4855 "ctl %08x head %08x tail %08x start %08x\n",
4856 I915_READ(PRB0_CTL),
4857 I915_READ(PRB0_HEAD),
4858 I915_READ(PRB0_TAIL),
4859 I915_READ(PRB0_START));
4860 return -EIO;
4861 } 4620 }
4862 4621
4863 /* Update our cache of the ring state */ 4622 ret = intel_init_ring_buffer(dev, &dev_priv->render_ring);
4864 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 4623 if (ret)
4865 i915_kernel_lost_context(dev); 4624 goto cleanup_pipe_control;
4866 else {
4867 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
4868 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
4869 ring->space = ring->head - (ring->tail + 8);
4870 if (ring->space < 0)
4871 ring->space += ring->Size;
4872 }
4873 4625
4874 if (IS_I9XX(dev) && !IS_GEN3(dev)) { 4626 if (HAS_BSD(dev)) {
4875 I915_WRITE(MI_MODE, 4627 dev_priv->bsd_ring = bsd_ring;
4876 (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); 4628 ret = intel_init_ring_buffer(dev, &dev_priv->bsd_ring);
4629 if (ret)
4630 goto cleanup_render_ring;
4877 } 4631 }
4878 4632
4879 return 0; 4633 return 0;
4634
4635cleanup_render_ring:
4636 intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
4637cleanup_pipe_control:
4638 if (HAS_PIPE_CONTROL(dev))
4639 i915_gem_cleanup_pipe_control(dev);
4640 return ret;
4880} 4641}
4881 4642
4882void 4643void
@@ -4884,17 +4645,11 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
4884{ 4645{
4885 drm_i915_private_t *dev_priv = dev->dev_private; 4646 drm_i915_private_t *dev_priv = dev->dev_private;
4886 4647
4887 if (dev_priv->ring.ring_obj == NULL) 4648 intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
4888 return; 4649 if (HAS_BSD(dev))
4889 4650 intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
4890 drm_core_ioremapfree(&dev_priv->ring.map, dev); 4651 if (HAS_PIPE_CONTROL(dev))
4891 4652 i915_gem_cleanup_pipe_control(dev);
4892 i915_gem_object_unpin(dev_priv->ring.ring_obj);
4893 drm_gem_object_unreference(dev_priv->ring.ring_obj);
4894 dev_priv->ring.ring_obj = NULL;
4895 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
4896
4897 i915_gem_cleanup_hws(dev);
4898} 4653}
4899 4654
4900int 4655int
@@ -4922,12 +4677,14 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
4922 } 4677 }
4923 4678
4924 spin_lock(&dev_priv->mm.active_list_lock); 4679 spin_lock(&dev_priv->mm.active_list_lock);
4925 BUG_ON(!list_empty(&dev_priv->mm.active_list)); 4680 BUG_ON(!list_empty(&dev_priv->render_ring.active_list));
4681 BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.active_list));
4926 spin_unlock(&dev_priv->mm.active_list_lock); 4682 spin_unlock(&dev_priv->mm.active_list_lock);
4927 4683
4928 BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); 4684 BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
4929 BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); 4685 BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
4930 BUG_ON(!list_empty(&dev_priv->mm.request_list)); 4686 BUG_ON(!list_empty(&dev_priv->render_ring.request_list));
4687 BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list));
4931 mutex_unlock(&dev->struct_mutex); 4688 mutex_unlock(&dev->struct_mutex);
4932 4689
4933 drm_irq_install(dev); 4690 drm_irq_install(dev);
@@ -4966,18 +4723,20 @@ i915_gem_load(struct drm_device *dev)
4966 drm_i915_private_t *dev_priv = dev->dev_private; 4723 drm_i915_private_t *dev_priv = dev->dev_private;
4967 4724
4968 spin_lock_init(&dev_priv->mm.active_list_lock); 4725 spin_lock_init(&dev_priv->mm.active_list_lock);
4969 INIT_LIST_HEAD(&dev_priv->mm.active_list);
4970 INIT_LIST_HEAD(&dev_priv->mm.flushing_list); 4726 INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
4971 INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); 4727 INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
4972 INIT_LIST_HEAD(&dev_priv->mm.inactive_list); 4728 INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
4973 INIT_LIST_HEAD(&dev_priv->mm.request_list);
4974 INIT_LIST_HEAD(&dev_priv->mm.fence_list); 4729 INIT_LIST_HEAD(&dev_priv->mm.fence_list);
4730 INIT_LIST_HEAD(&dev_priv->render_ring.active_list);
4731 INIT_LIST_HEAD(&dev_priv->render_ring.request_list);
4732 if (HAS_BSD(dev)) {
4733 INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list);
4734 INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list);
4735 }
4975 for (i = 0; i < 16; i++) 4736 for (i = 0; i < 16; i++)
4976 INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); 4737 INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
4977 INIT_DELAYED_WORK(&dev_priv->mm.retire_work, 4738 INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
4978 i915_gem_retire_work_handler); 4739 i915_gem_retire_work_handler);
4979 dev_priv->mm.next_gem_seqno = 1;
4980
4981 spin_lock(&shrink_list_lock); 4740 spin_lock(&shrink_list_lock);
4982 list_add(&dev_priv->mm.shrink_list, &shrink_list); 4741 list_add(&dev_priv->mm.shrink_list, &shrink_list);
4983 spin_unlock(&shrink_list_lock); 4742 spin_unlock(&shrink_list_lock);
@@ -5209,7 +4968,9 @@ i915_gpu_is_active(struct drm_device *dev)
5209 4968
5210 spin_lock(&dev_priv->mm.active_list_lock); 4969 spin_lock(&dev_priv->mm.active_list_lock);
5211 lists_empty = list_empty(&dev_priv->mm.flushing_list) && 4970 lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
5212 list_empty(&dev_priv->mm.active_list); 4971 list_empty(&dev_priv->render_ring.active_list);
4972 if (HAS_BSD(dev))
4973 lists_empty &= list_empty(&dev_priv->bsd_ring.active_list);
5213 spin_unlock(&dev_priv->mm.active_list_lock); 4974 spin_unlock(&dev_priv->mm.active_list_lock);
5214 4975
5215 return !lists_empty; 4976 return !lists_empty;
@@ -5254,8 +5015,10 @@ rescan:
5254 continue; 5015 continue;
5255 5016
5256 spin_unlock(&shrink_list_lock); 5017 spin_unlock(&shrink_list_lock);
5018 i915_gem_retire_requests(dev, &dev_priv->render_ring);
5257 5019
5258 i915_gem_retire_requests(dev); 5020 if (HAS_BSD(dev))
5021 i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
5259 5022
5260 list_for_each_entry_safe(obj_priv, next_obj, 5023 list_for_each_entry_safe(obj_priv, next_obj,
5261 &dev_priv->mm.inactive_list, 5024 &dev_priv->mm.inactive_list,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 8c3f0802686d..2479be001e40 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -53,7 +53,7 @@
53 I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) 53 I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
54 54
55/** Interrupts that we mask and unmask at runtime. */ 55/** Interrupts that we mask and unmask at runtime. */
56#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) 56#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT | I915_BSD_USER_INTERRUPT)
57 57
58#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ 58#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\
59 PIPE_VBLANK_INTERRUPT_STATUS) 59 PIPE_VBLANK_INTERRUPT_STATUS)
@@ -74,7 +74,7 @@ ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
74 } 74 }
75} 75}
76 76
77static inline void 77void
78ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) 78ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
79{ 79{
80 if ((dev_priv->gt_irq_mask_reg & mask) != mask) { 80 if ((dev_priv->gt_irq_mask_reg & mask) != mask) {
@@ -115,7 +115,7 @@ i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
115 } 115 }
116} 116}
117 117
118static inline void 118void
119i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) 119i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
120{ 120{
121 if ((dev_priv->irq_mask_reg & mask) != mask) { 121 if ((dev_priv->irq_mask_reg & mask) != mask) {
@@ -278,10 +278,9 @@ static void i915_handle_rps_change(struct drm_device *dev)
278{ 278{
279 drm_i915_private_t *dev_priv = dev->dev_private; 279 drm_i915_private_t *dev_priv = dev->dev_private;
280 u32 busy_up, busy_down, max_avg, min_avg; 280 u32 busy_up, busy_down, max_avg, min_avg;
281 u16 rgvswctl;
282 u8 new_delay = dev_priv->cur_delay; 281 u8 new_delay = dev_priv->cur_delay;
283 282
284 I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS) & ~MEMINT_EVAL_CHG); 283 I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG);
285 busy_up = I915_READ(RCPREVBSYTUPAVG); 284 busy_up = I915_READ(RCPREVBSYTUPAVG);
286 busy_down = I915_READ(RCPREVBSYTDNAVG); 285 busy_down = I915_READ(RCPREVBSYTDNAVG);
287 max_avg = I915_READ(RCBMAXAVG); 286 max_avg = I915_READ(RCBMAXAVG);
@@ -300,27 +299,8 @@ static void i915_handle_rps_change(struct drm_device *dev)
300 new_delay = dev_priv->min_delay; 299 new_delay = dev_priv->min_delay;
301 } 300 }
302 301
303 DRM_DEBUG("rps change requested: %d -> %d\n", 302 if (ironlake_set_drps(dev, new_delay))
304 dev_priv->cur_delay, new_delay); 303 dev_priv->cur_delay = new_delay;
305
306 rgvswctl = I915_READ(MEMSWCTL);
307 if (rgvswctl & MEMCTL_CMD_STS) {
308 DRM_ERROR("gpu busy, RCS change rejected\n");
309 return; /* still busy with another command */
310 }
311
312 /* Program the new state */
313 rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
314 (new_delay << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
315 I915_WRITE(MEMSWCTL, rgvswctl);
316 POSTING_READ(MEMSWCTL);
317
318 rgvswctl |= MEMCTL_CMD_STS;
319 I915_WRITE(MEMSWCTL, rgvswctl);
320
321 dev_priv->cur_delay = new_delay;
322
323 DRM_DEBUG("rps changed\n");
324 304
325 return; 305 return;
326} 306}
@@ -331,6 +311,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
331 int ret = IRQ_NONE; 311 int ret = IRQ_NONE;
332 u32 de_iir, gt_iir, de_ier, pch_iir; 312 u32 de_iir, gt_iir, de_ier, pch_iir;
333 struct drm_i915_master_private *master_priv; 313 struct drm_i915_master_private *master_priv;
314 struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
334 315
335 /* disable master interrupt before clearing iir */ 316 /* disable master interrupt before clearing iir */
336 de_ier = I915_READ(DEIER); 317 de_ier = I915_READ(DEIER);
@@ -354,13 +335,16 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
354 } 335 }
355 336
356 if (gt_iir & GT_PIPE_NOTIFY) { 337 if (gt_iir & GT_PIPE_NOTIFY) {
357 u32 seqno = i915_get_gem_seqno(dev); 338 u32 seqno = render_ring->get_gem_seqno(dev, render_ring);
358 dev_priv->mm.irq_gem_seqno = seqno; 339 render_ring->irq_gem_seqno = seqno;
359 trace_i915_gem_request_complete(dev, seqno); 340 trace_i915_gem_request_complete(dev, seqno);
360 DRM_WAKEUP(&dev_priv->irq_queue); 341 DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
361 dev_priv->hangcheck_count = 0; 342 dev_priv->hangcheck_count = 0;
362 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); 343 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
363 } 344 }
345 if (gt_iir & GT_BSD_USER_INTERRUPT)
346 DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
347
364 348
365 if (de_iir & DE_GSE) 349 if (de_iir & DE_GSE)
366 ironlake_opregion_gse_intr(dev); 350 ironlake_opregion_gse_intr(dev);
@@ -388,7 +372,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
388 } 372 }
389 373
390 if (de_iir & DE_PCU_EVENT) { 374 if (de_iir & DE_PCU_EVENT) {
391 I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS)); 375 I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS));
392 i915_handle_rps_change(dev); 376 i915_handle_rps_change(dev);
393 } 377 }
394 378
@@ -536,17 +520,18 @@ i915_ringbuffer_last_batch(struct drm_device *dev)
536 */ 520 */
537 bbaddr = 0; 521 bbaddr = 0;
538 head = I915_READ(PRB0_HEAD) & HEAD_ADDR; 522 head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
539 ring = (u32 *)(dev_priv->ring.virtual_start + head); 523 ring = (u32 *)(dev_priv->render_ring.virtual_start + head);
540 524
541 while (--ring >= (u32 *)dev_priv->ring.virtual_start) { 525 while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) {
542 bbaddr = i915_get_bbaddr(dev, ring); 526 bbaddr = i915_get_bbaddr(dev, ring);
543 if (bbaddr) 527 if (bbaddr)
544 break; 528 break;
545 } 529 }
546 530
547 if (bbaddr == 0) { 531 if (bbaddr == 0) {
548 ring = (u32 *)(dev_priv->ring.virtual_start + dev_priv->ring.Size); 532 ring = (u32 *)(dev_priv->render_ring.virtual_start
549 while (--ring >= (u32 *)dev_priv->ring.virtual_start) { 533 + dev_priv->render_ring.size);
534 while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) {
550 bbaddr = i915_get_bbaddr(dev, ring); 535 bbaddr = i915_get_bbaddr(dev, ring);
551 if (bbaddr) 536 if (bbaddr)
552 break; 537 break;
@@ -587,7 +572,7 @@ static void i915_capture_error_state(struct drm_device *dev)
587 return; 572 return;
588 } 573 }
589 574
590 error->seqno = i915_get_gem_seqno(dev); 575 error->seqno = i915_get_gem_seqno(dev, &dev_priv->render_ring);
591 error->eir = I915_READ(EIR); 576 error->eir = I915_READ(EIR);
592 error->pgtbl_er = I915_READ(PGTBL_ER); 577 error->pgtbl_er = I915_READ(PGTBL_ER);
593 error->pipeastat = I915_READ(PIPEASTAT); 578 error->pipeastat = I915_READ(PIPEASTAT);
@@ -615,7 +600,9 @@ static void i915_capture_error_state(struct drm_device *dev)
615 batchbuffer[0] = NULL; 600 batchbuffer[0] = NULL;
616 batchbuffer[1] = NULL; 601 batchbuffer[1] = NULL;
617 count = 0; 602 count = 0;
618 list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { 603 list_for_each_entry(obj_priv,
604 &dev_priv->render_ring.active_list, list) {
605
619 struct drm_gem_object *obj = &obj_priv->base; 606 struct drm_gem_object *obj = &obj_priv->base;
620 607
621 if (batchbuffer[0] == NULL && 608 if (batchbuffer[0] == NULL &&
@@ -639,7 +626,8 @@ static void i915_capture_error_state(struct drm_device *dev)
639 error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); 626 error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]);
640 627
641 /* Record the ringbuffer */ 628 /* Record the ringbuffer */
642 error->ringbuffer = i915_error_object_create(dev, dev_priv->ring.ring_obj); 629 error->ringbuffer = i915_error_object_create(dev,
630 dev_priv->render_ring.gem_object);
643 631
644 /* Record buffers on the active list. */ 632 /* Record buffers on the active list. */
645 error->active_bo = NULL; 633 error->active_bo = NULL;
@@ -651,7 +639,8 @@ static void i915_capture_error_state(struct drm_device *dev)
651 639
652 if (error->active_bo) { 640 if (error->active_bo) {
653 int i = 0; 641 int i = 0;
654 list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { 642 list_for_each_entry(obj_priv,
643 &dev_priv->render_ring.active_list, list) {
655 struct drm_gem_object *obj = &obj_priv->base; 644 struct drm_gem_object *obj = &obj_priv->base;
656 645
657 error->active_bo[i].size = obj->size; 646 error->active_bo[i].size = obj->size;
@@ -703,24 +692,13 @@ void i915_destroy_error_state(struct drm_device *dev)
703 i915_error_state_free(dev, error); 692 i915_error_state_free(dev, error);
704} 693}
705 694
706/** 695static void i915_report_and_clear_eir(struct drm_device *dev)
707 * i915_handle_error - handle an error interrupt
708 * @dev: drm device
709 *
710 * Do some basic checking of regsiter state at error interrupt time and
711 * dump it to the syslog. Also call i915_capture_error_state() to make
712 * sure we get a record and make it available in debugfs. Fire a uevent
713 * so userspace knows something bad happened (should trigger collection
714 * of a ring dump etc.).
715 */
716static void i915_handle_error(struct drm_device *dev, bool wedged)
717{ 696{
718 struct drm_i915_private *dev_priv = dev->dev_private; 697 struct drm_i915_private *dev_priv = dev->dev_private;
719 u32 eir = I915_READ(EIR); 698 u32 eir = I915_READ(EIR);
720 u32 pipea_stats = I915_READ(PIPEASTAT);
721 u32 pipeb_stats = I915_READ(PIPEBSTAT);
722 699
723 i915_capture_error_state(dev); 700 if (!eir)
701 return;
724 702
725 printk(KERN_ERR "render error detected, EIR: 0x%08x\n", 703 printk(KERN_ERR "render error detected, EIR: 0x%08x\n",
726 eir); 704 eir);
@@ -766,6 +744,9 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
766 } 744 }
767 745
768 if (eir & I915_ERROR_MEMORY_REFRESH) { 746 if (eir & I915_ERROR_MEMORY_REFRESH) {
747 u32 pipea_stats = I915_READ(PIPEASTAT);
748 u32 pipeb_stats = I915_READ(PIPEBSTAT);
749
769 printk(KERN_ERR "memory refresh error\n"); 750 printk(KERN_ERR "memory refresh error\n");
770 printk(KERN_ERR "PIPEASTAT: 0x%08x\n", 751 printk(KERN_ERR "PIPEASTAT: 0x%08x\n",
771 pipea_stats); 752 pipea_stats);
@@ -822,6 +803,24 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
822 I915_WRITE(EMR, I915_READ(EMR) | eir); 803 I915_WRITE(EMR, I915_READ(EMR) | eir);
823 I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); 804 I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
824 } 805 }
806}
807
808/**
809 * i915_handle_error - handle an error interrupt
810 * @dev: drm device
811 *
812 * Do some basic checking of regsiter state at error interrupt time and
813 * dump it to the syslog. Also call i915_capture_error_state() to make
814 * sure we get a record and make it available in debugfs. Fire a uevent
815 * so userspace knows something bad happened (should trigger collection
816 * of a ring dump etc.).
817 */
818static void i915_handle_error(struct drm_device *dev, bool wedged)
819{
820 struct drm_i915_private *dev_priv = dev->dev_private;
821
822 i915_capture_error_state(dev);
823 i915_report_and_clear_eir(dev);
825 824
826 if (wedged) { 825 if (wedged) {
827 atomic_set(&dev_priv->mm.wedged, 1); 826 atomic_set(&dev_priv->mm.wedged, 1);
@@ -829,7 +828,7 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
829 /* 828 /*
830 * Wakeup waiting processes so they don't hang 829 * Wakeup waiting processes so they don't hang
831 */ 830 */
832 DRM_WAKEUP(&dev_priv->irq_queue); 831 DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
833 } 832 }
834 833
835 queue_work(dev_priv->wq, &dev_priv->error_work); 834 queue_work(dev_priv->wq, &dev_priv->error_work);
@@ -848,6 +847,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
848 unsigned long irqflags; 847 unsigned long irqflags;
849 int irq_received; 848 int irq_received;
850 int ret = IRQ_NONE; 849 int ret = IRQ_NONE;
850 struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
851 851
852 atomic_inc(&dev_priv->irq_received); 852 atomic_inc(&dev_priv->irq_received);
853 853
@@ -928,14 +928,18 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
928 } 928 }
929 929
930 if (iir & I915_USER_INTERRUPT) { 930 if (iir & I915_USER_INTERRUPT) {
931 u32 seqno = i915_get_gem_seqno(dev); 931 u32 seqno =
932 dev_priv->mm.irq_gem_seqno = seqno; 932 render_ring->get_gem_seqno(dev, render_ring);
933 render_ring->irq_gem_seqno = seqno;
933 trace_i915_gem_request_complete(dev, seqno); 934 trace_i915_gem_request_complete(dev, seqno);
934 DRM_WAKEUP(&dev_priv->irq_queue); 935 DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
935 dev_priv->hangcheck_count = 0; 936 dev_priv->hangcheck_count = 0;
936 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); 937 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
937 } 938 }
938 939
940 if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT))
941 DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
942
939 if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) 943 if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
940 intel_prepare_page_flip(dev, 0); 944 intel_prepare_page_flip(dev, 0);
941 945
@@ -984,7 +988,6 @@ static int i915_emit_irq(struct drm_device * dev)
984{ 988{
985 drm_i915_private_t *dev_priv = dev->dev_private; 989 drm_i915_private_t *dev_priv = dev->dev_private;
986 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 990 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
987 RING_LOCALS;
988 991
989 i915_kernel_lost_context(dev); 992 i915_kernel_lost_context(dev);
990 993
@@ -1006,43 +1009,13 @@ static int i915_emit_irq(struct drm_device * dev)
1006 return dev_priv->counter; 1009 return dev_priv->counter;
1007} 1010}
1008 1011
1009void i915_user_irq_get(struct drm_device *dev)
1010{
1011 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1012 unsigned long irqflags;
1013
1014 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1015 if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
1016 if (HAS_PCH_SPLIT(dev))
1017 ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
1018 else
1019 i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
1020 }
1021 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
1022}
1023
1024void i915_user_irq_put(struct drm_device *dev)
1025{
1026 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1027 unsigned long irqflags;
1028
1029 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1030 BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
1031 if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
1032 if (HAS_PCH_SPLIT(dev))
1033 ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
1034 else
1035 i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
1036 }
1037 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
1038}
1039
1040void i915_trace_irq_get(struct drm_device *dev, u32 seqno) 1012void i915_trace_irq_get(struct drm_device *dev, u32 seqno)
1041{ 1013{
1042 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 1014 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1015 struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
1043 1016
1044 if (dev_priv->trace_irq_seqno == 0) 1017 if (dev_priv->trace_irq_seqno == 0)
1045 i915_user_irq_get(dev); 1018 render_ring->user_irq_get(dev, render_ring);
1046 1019
1047 dev_priv->trace_irq_seqno = seqno; 1020 dev_priv->trace_irq_seqno = seqno;
1048} 1021}
@@ -1052,6 +1025,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
1052 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 1025 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1053 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 1026 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
1054 int ret = 0; 1027 int ret = 0;
1028 struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
1055 1029
1056 DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, 1030 DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr,
1057 READ_BREADCRUMB(dev_priv)); 1031 READ_BREADCRUMB(dev_priv));
@@ -1065,10 +1039,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
1065 if (master_priv->sarea_priv) 1039 if (master_priv->sarea_priv)
1066 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 1040 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
1067 1041
1068 i915_user_irq_get(dev); 1042 render_ring->user_irq_get(dev, render_ring);
1069 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, 1043 DRM_WAIT_ON(ret, dev_priv->render_ring.irq_queue, 3 * DRM_HZ,
1070 READ_BREADCRUMB(dev_priv) >= irq_nr); 1044 READ_BREADCRUMB(dev_priv) >= irq_nr);
1071 i915_user_irq_put(dev); 1045 render_ring->user_irq_put(dev, render_ring);
1072 1046
1073 if (ret == -EBUSY) { 1047 if (ret == -EBUSY) {
1074 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", 1048 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
@@ -1087,7 +1061,7 @@ int i915_irq_emit(struct drm_device *dev, void *data,
1087 drm_i915_irq_emit_t *emit = data; 1061 drm_i915_irq_emit_t *emit = data;
1088 int result; 1062 int result;
1089 1063
1090 if (!dev_priv || !dev_priv->ring.virtual_start) { 1064 if (!dev_priv || !dev_priv->render_ring.virtual_start) {
1091 DRM_ERROR("called with no initialization\n"); 1065 DRM_ERROR("called with no initialization\n");
1092 return -EINVAL; 1066 return -EINVAL;
1093 } 1067 }
@@ -1233,9 +1207,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1233 return -EINVAL; 1207 return -EINVAL;
1234} 1208}
1235 1209
1236struct drm_i915_gem_request *i915_get_tail_request(struct drm_device *dev) { 1210struct drm_i915_gem_request *
1211i915_get_tail_request(struct drm_device *dev)
1212{
1237 drm_i915_private_t *dev_priv = dev->dev_private; 1213 drm_i915_private_t *dev_priv = dev->dev_private;
1238 return list_entry(dev_priv->mm.request_list.prev, struct drm_i915_gem_request, list); 1214 return list_entry(dev_priv->render_ring.request_list.prev,
1215 struct drm_i915_gem_request, list);
1239} 1216}
1240 1217
1241/** 1218/**
@@ -1260,8 +1237,10 @@ void i915_hangcheck_elapsed(unsigned long data)
1260 acthd = I915_READ(ACTHD_I965); 1237 acthd = I915_READ(ACTHD_I965);
1261 1238
1262 /* If all work is done then ACTHD clearly hasn't advanced. */ 1239 /* If all work is done then ACTHD clearly hasn't advanced. */
1263 if (list_empty(&dev_priv->mm.request_list) || 1240 if (list_empty(&dev_priv->render_ring.request_list) ||
1264 i915_seqno_passed(i915_get_gem_seqno(dev), i915_get_tail_request(dev)->seqno)) { 1241 i915_seqno_passed(i915_get_gem_seqno(dev,
1242 &dev_priv->render_ring),
1243 i915_get_tail_request(dev)->seqno)) {
1265 dev_priv->hangcheck_count = 0; 1244 dev_priv->hangcheck_count = 0;
1266 return; 1245 return;
1267 } 1246 }
@@ -1314,7 +1293,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1314 /* enable kind of interrupts always enabled */ 1293 /* enable kind of interrupts always enabled */
1315 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | 1294 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
1316 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; 1295 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
1317 u32 render_mask = GT_PIPE_NOTIFY; 1296 u32 render_mask = GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT;
1318 u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | 1297 u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
1319 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; 1298 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
1320 1299
@@ -1328,7 +1307,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1328 (void) I915_READ(DEIER); 1307 (void) I915_READ(DEIER);
1329 1308
1330 /* user interrupt should be enabled, but masked initial */ 1309 /* user interrupt should be enabled, but masked initial */
1331 dev_priv->gt_irq_mask_reg = 0xffffffff; 1310 dev_priv->gt_irq_mask_reg = ~render_mask;
1332 dev_priv->gt_irq_enable_reg = render_mask; 1311 dev_priv->gt_irq_enable_reg = render_mask;
1333 1312
1334 I915_WRITE(GTIIR, I915_READ(GTIIR)); 1313 I915_WRITE(GTIIR, I915_READ(GTIIR));
@@ -1391,7 +1370,10 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
1391 u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; 1370 u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
1392 u32 error_mask; 1371 u32 error_mask;
1393 1372
1394 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); 1373 DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue);
1374
1375 if (HAS_BSD(dev))
1376 DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue);
1395 1377
1396 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; 1378 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1397 1379
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f3e39cc46f0d..64b0a3afd92b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -334,6 +334,7 @@
334#define I915_DEBUG_INTERRUPT (1<<2) 334#define I915_DEBUG_INTERRUPT (1<<2)
335#define I915_USER_INTERRUPT (1<<1) 335#define I915_USER_INTERRUPT (1<<1)
336#define I915_ASLE_INTERRUPT (1<<0) 336#define I915_ASLE_INTERRUPT (1<<0)
337#define I915_BSD_USER_INTERRUPT (1<<25)
337#define EIR 0x020b0 338#define EIR 0x020b0
338#define EMR 0x020b4 339#define EMR 0x020b4
339#define ESR 0x020b8 340#define ESR 0x020b8
@@ -368,6 +369,36 @@
368#define BB_ADDR 0x02140 /* 8 bytes */ 369#define BB_ADDR 0x02140 /* 8 bytes */
369#define GFX_FLSH_CNTL 0x02170 /* 915+ only */ 370#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
370 371
372/* GEN6 interrupt control */
373#define GEN6_RENDER_HWSTAM 0x2098
374#define GEN6_RENDER_IMR 0x20a8
375#define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8)
376#define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7)
377#define GEN6_RENDER TIMEOUT_COUNTER_EXPIRED (1 << 6)
378#define GEN6_RENDER_L3_PARITY_ERROR (1 << 5)
379#define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4)
380#define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3)
381#define GEN6_RENDER_SYNC_STATUS (1 << 2)
382#define GEN6_RENDER_DEBUG_INTERRUPT (1 << 1)
383#define GEN6_RENDER_USER_INTERRUPT (1 << 0)
384
385#define GEN6_BLITTER_HWSTAM 0x22098
386#define GEN6_BLITTER_IMR 0x220a8
387#define GEN6_BLITTER_MI_FLUSH_DW_NOTIFY_INTERRUPT (1 << 26)
388#define GEN6_BLITTER_COMMAND_PARSER_MASTER_ERROR (1 << 25)
389#define GEN6_BLITTER_SYNC_STATUS (1 << 24)
390#define GEN6_BLITTER_USER_INTERRUPT (1 << 22)
391/*
392 * BSD (bit stream decoder instruction and interrupt control register defines
393 * (G4X and Ironlake only)
394 */
395
396#define BSD_RING_TAIL 0x04030
397#define BSD_RING_HEAD 0x04034
398#define BSD_RING_START 0x04038
399#define BSD_RING_CTL 0x0403c
400#define BSD_RING_ACTHD 0x04074
401#define BSD_HWS_PGA 0x04080
371 402
372/* 403/*
373 * Framebuffer compression (915+ only) 404 * Framebuffer compression (915+ only)
@@ -805,6 +836,10 @@
805#define DCC_CHANNEL_XOR_DISABLE (1 << 10) 836#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
806#define DCC_CHANNEL_XOR_BIT_17 (1 << 9) 837#define DCC_CHANNEL_XOR_BIT_17 (1 << 9)
807 838
839/** Pineview MCH register contains DDR3 setting */
840#define CSHRDDR3CTL 0x101a8
841#define CSHRDDR3CTL_DDR3 (1 << 2)
842
808/** 965 MCH register controlling DRAM channel configuration */ 843/** 965 MCH register controlling DRAM channel configuration */
809#define C0DRB3 0x10206 844#define C0DRB3 0x10206
810#define C1DRB3 0x10606 845#define C1DRB3 0x10606
@@ -826,6 +861,12 @@
826#define CLKCFG_MEM_800 (3 << 4) 861#define CLKCFG_MEM_800 (3 << 4)
827#define CLKCFG_MEM_MASK (7 << 4) 862#define CLKCFG_MEM_MASK (7 << 4)
828 863
864#define TR1 0x11006
865#define TSFS 0x11020
866#define TSFS_SLOPE_MASK 0x0000ff00
867#define TSFS_SLOPE_SHIFT 8
868#define TSFS_INTR_MASK 0x000000ff
869
829#define CRSTANDVID 0x11100 870#define CRSTANDVID 0x11100
830#define PXVFREQ_BASE 0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */ 871#define PXVFREQ_BASE 0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */
831#define PXVFREQ_PX_MASK 0x7f000000 872#define PXVFREQ_PX_MASK 0x7f000000
@@ -964,6 +1005,41 @@
964#define MEMSTAT_SRC_CTL_STDBY 3 1005#define MEMSTAT_SRC_CTL_STDBY 3
965#define RCPREVBSYTUPAVG 0x113b8 1006#define RCPREVBSYTUPAVG 0x113b8
966#define RCPREVBSYTDNAVG 0x113bc 1007#define RCPREVBSYTDNAVG 0x113bc
1008#define SDEW 0x1124c
1009#define CSIEW0 0x11250
1010#define CSIEW1 0x11254
1011#define CSIEW2 0x11258
1012#define PEW 0x1125c
1013#define DEW 0x11270
1014#define MCHAFE 0x112c0
1015#define CSIEC 0x112e0
1016#define DMIEC 0x112e4
1017#define DDREC 0x112e8
1018#define PEG0EC 0x112ec
1019#define PEG1EC 0x112f0
1020#define GFXEC 0x112f4
1021#define RPPREVBSYTUPAVG 0x113b8
1022#define RPPREVBSYTDNAVG 0x113bc
1023#define ECR 0x11600
1024#define ECR_GPFE (1<<31)
1025#define ECR_IMONE (1<<30)
1026#define ECR_CAP_MASK 0x0000001f /* Event range, 0-31 */
1027#define OGW0 0x11608
1028#define OGW1 0x1160c
1029#define EG0 0x11610
1030#define EG1 0x11614
1031#define EG2 0x11618
1032#define EG3 0x1161c
1033#define EG4 0x11620
1034#define EG5 0x11624
1035#define EG6 0x11628
1036#define EG7 0x1162c
1037#define PXW 0x11664
1038#define PXWL 0x11680
1039#define LCFUSE02 0x116c0
1040#define LCFUSE_HIV_MASK 0x000000ff
1041#define CSIPLL0 0x12c10
1042#define DDRMPLL1 0X12c20
967#define PEG_BAND_GAP_DATA 0x14d68 1043#define PEG_BAND_GAP_DATA 0x14d68
968 1044
969/* 1045/*
@@ -1055,7 +1131,6 @@
1055#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) 1131#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
1056#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) 1132#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
1057#define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ 1133#define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */
1058#define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f
1059 1134
1060#define PORT_HOTPLUG_STAT 0x61114 1135#define PORT_HOTPLUG_STAT 0x61114
1061#define HDMIB_HOTPLUG_INT_STATUS (1 << 29) 1136#define HDMIB_HOTPLUG_INT_STATUS (1 << 29)
@@ -2355,6 +2430,8 @@
2355#define GT_PIPE_NOTIFY (1 << 4) 2430#define GT_PIPE_NOTIFY (1 << 4)
2356#define GT_SYNC_STATUS (1 << 2) 2431#define GT_SYNC_STATUS (1 << 2)
2357#define GT_USER_INTERRUPT (1 << 0) 2432#define GT_USER_INTERRUPT (1 << 0)
2433#define GT_BSD_USER_INTERRUPT (1 << 5)
2434
2358 2435
2359#define GTISR 0x44010 2436#define GTISR 0x44010
2360#define GTIMR 0x44014 2437#define GTIMR 0x44014
@@ -2690,6 +2767,9 @@
2690#define SDVO_ENCODING (0) 2767#define SDVO_ENCODING (0)
2691#define TMDS_ENCODING (2 << 10) 2768#define TMDS_ENCODING (2 << 10)
2692#define NULL_PACKET_VSYNC_ENABLE (1 << 9) 2769#define NULL_PACKET_VSYNC_ENABLE (1 << 9)
2770/* CPT */
2771#define HDMI_MODE_SELECT (1 << 9)
2772#define DVI_MODE_SELECT (0)
2693#define SDVOB_BORDER_ENABLE (1 << 7) 2773#define SDVOB_BORDER_ENABLE (1 << 7)
2694#define AUDIO_ENABLE (1 << 6) 2774#define AUDIO_ENABLE (1 << 6)
2695#define VSYNC_ACTIVE_HIGH (1 << 4) 2775#define VSYNC_ACTIVE_HIGH (1 << 4)
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 9e4c45f68d6e..fab21760dd57 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -53,23 +53,6 @@ TRACE_EVENT(i915_gem_object_bind,
53 __entry->obj, __entry->gtt_offset) 53 __entry->obj, __entry->gtt_offset)
54); 54);
55 55
56TRACE_EVENT(i915_gem_object_clflush,
57
58 TP_PROTO(struct drm_gem_object *obj),
59
60 TP_ARGS(obj),
61
62 TP_STRUCT__entry(
63 __field(struct drm_gem_object *, obj)
64 ),
65
66 TP_fast_assign(
67 __entry->obj = obj;
68 ),
69
70 TP_printk("obj=%p", __entry->obj)
71);
72
73TRACE_EVENT(i915_gem_object_change_domain, 56TRACE_EVENT(i915_gem_object_change_domain,
74 57
75 TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), 58 TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain),
@@ -132,6 +115,13 @@ DECLARE_EVENT_CLASS(i915_gem_object,
132 TP_printk("obj=%p", __entry->obj) 115 TP_printk("obj=%p", __entry->obj)
133); 116);
134 117
118DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush,
119
120 TP_PROTO(struct drm_gem_object *obj),
121
122 TP_ARGS(obj)
123);
124
135DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, 125DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind,
136 126
137 TP_PROTO(struct drm_gem_object *obj), 127 TP_PROTO(struct drm_gem_object *obj),
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4c748d8f73d6..96f75d7f6633 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -95,6 +95,16 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
95 panel_fixed_mode->clock = dvo_timing->clock * 10; 95 panel_fixed_mode->clock = dvo_timing->clock * 10;
96 panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; 96 panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
97 97
98 if (dvo_timing->hsync_positive)
99 panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;
100 else
101 panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;
102
103 if (dvo_timing->vsync_positive)
104 panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;
105 else
106 panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;
107
98 /* Some VBTs have bogus h/vtotal values */ 108 /* Some VBTs have bogus h/vtotal values */
99 if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) 109 if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
100 panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; 110 panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index e16ac5a28c3c..22ff38455731 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -217,7 +217,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
217{ 217{
218 struct drm_device *dev = connector->dev; 218 struct drm_device *dev = connector->dev;
219 struct drm_i915_private *dev_priv = dev->dev_private; 219 struct drm_i915_private *dev_priv = dev->dev_private;
220 u32 hotplug_en; 220 u32 hotplug_en, orig, stat;
221 bool ret = false;
221 int i, tries = 0; 222 int i, tries = 0;
222 223
223 if (HAS_PCH_SPLIT(dev)) 224 if (HAS_PCH_SPLIT(dev))
@@ -232,8 +233,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
232 tries = 2; 233 tries = 2;
233 else 234 else
234 tries = 1; 235 tries = 1;
235 hotplug_en = I915_READ(PORT_HOTPLUG_EN); 236 hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN);
236 hotplug_en &= CRT_FORCE_HOTPLUG_MASK; 237 hotplug_en &= CRT_HOTPLUG_MASK;
237 hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; 238 hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
238 239
239 if (IS_G4X(dev)) 240 if (IS_G4X(dev))
@@ -255,11 +256,17 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
255 } while (time_after(timeout, jiffies)); 256 } while (time_after(timeout, jiffies));
256 } 257 }
257 258
258 if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != 259 stat = I915_READ(PORT_HOTPLUG_STAT);
259 CRT_HOTPLUG_MONITOR_NONE) 260 if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
260 return true; 261 ret = true;
262
263 /* clear the interrupt we just generated, if any */
264 I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
261 265
262 return false; 266 /* and put the bits back */
267 I915_WRITE(PORT_HOTPLUG_EN, orig);
268
269 return ret;
263} 270}
264 271
265static bool intel_crt_detect_ddc(struct drm_encoder *encoder) 272static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
@@ -569,7 +576,7 @@ void intel_crt_init(struct drm_device *dev)
569 (1 << INTEL_ANALOG_CLONE_BIT) | 576 (1 << INTEL_ANALOG_CLONE_BIT) |
570 (1 << INTEL_SDVO_LVDS_CLONE_BIT); 577 (1 << INTEL_SDVO_LVDS_CLONE_BIT);
571 intel_encoder->crtc_mask = (1 << 0) | (1 << 1); 578 intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
572 connector->interlace_allowed = 0; 579 connector->interlace_allowed = 1;
573 connector->doublescan_allowed = 0; 580 connector->doublescan_allowed = 0;
574 581
575 drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); 582 drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f469a84cacfd..04e1bb499ff8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1029,19 +1029,28 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
1029void i8xx_disable_fbc(struct drm_device *dev) 1029void i8xx_disable_fbc(struct drm_device *dev)
1030{ 1030{
1031 struct drm_i915_private *dev_priv = dev->dev_private; 1031 struct drm_i915_private *dev_priv = dev->dev_private;
1032 unsigned long timeout = jiffies + msecs_to_jiffies(1);
1032 u32 fbc_ctl; 1033 u32 fbc_ctl;
1033 1034
1034 if (!I915_HAS_FBC(dev)) 1035 if (!I915_HAS_FBC(dev))
1035 return; 1036 return;
1036 1037
1038 if (!(I915_READ(FBC_CONTROL) & FBC_CTL_EN))
1039 return; /* Already off, just return */
1040
1037 /* Disable compression */ 1041 /* Disable compression */
1038 fbc_ctl = I915_READ(FBC_CONTROL); 1042 fbc_ctl = I915_READ(FBC_CONTROL);
1039 fbc_ctl &= ~FBC_CTL_EN; 1043 fbc_ctl &= ~FBC_CTL_EN;
1040 I915_WRITE(FBC_CONTROL, fbc_ctl); 1044 I915_WRITE(FBC_CONTROL, fbc_ctl);
1041 1045
1042 /* Wait for compressing bit to clear */ 1046 /* Wait for compressing bit to clear */
1043 while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) 1047 while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) {
1044 ; /* nothing */ 1048 if (time_after(jiffies, timeout)) {
1049 DRM_DEBUG_DRIVER("FBC idle timed out\n");
1050 break;
1051 }
1052 ; /* do nothing */
1053 }
1045 1054
1046 intel_wait_for_vblank(dev); 1055 intel_wait_for_vblank(dev);
1047 1056
@@ -1239,10 +1248,11 @@ static void intel_update_fbc(struct drm_crtc *crtc,
1239 return; 1248 return;
1240 1249
1241out_disable: 1250out_disable:
1242 DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
1243 /* Multiple disables should be harmless */ 1251 /* Multiple disables should be harmless */
1244 if (intel_fbc_enabled(dev)) 1252 if (intel_fbc_enabled(dev)) {
1253 DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
1245 intel_disable_fbc(dev); 1254 intel_disable_fbc(dev);
1255 }
1246} 1256}
1247 1257
1248static int 1258static int
@@ -1386,7 +1396,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1386 Start = obj_priv->gtt_offset; 1396 Start = obj_priv->gtt_offset;
1387 Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); 1397 Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
1388 1398
1389 DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); 1399 DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
1400 Start, Offset, x, y, crtc->fb->pitch);
1390 I915_WRITE(dspstride, crtc->fb->pitch); 1401 I915_WRITE(dspstride, crtc->fb->pitch);
1391 if (IS_I965G(dev)) { 1402 if (IS_I965G(dev)) {
1392 I915_WRITE(dspbase, Offset); 1403 I915_WRITE(dspbase, Offset);
@@ -2345,6 +2356,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
2345 if (mode->clock * 3 > 27000 * 4) 2356 if (mode->clock * 3 > 27000 * 4)
2346 return MODE_CLOCK_HIGH; 2357 return MODE_CLOCK_HIGH;
2347 } 2358 }
2359
2360 drm_mode_set_crtcinfo(adjusted_mode, 0);
2348 return true; 2361 return true;
2349} 2362}
2350 2363
@@ -2629,6 +2642,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
2629 2642
2630struct cxsr_latency { 2643struct cxsr_latency {
2631 int is_desktop; 2644 int is_desktop;
2645 int is_ddr3;
2632 unsigned long fsb_freq; 2646 unsigned long fsb_freq;
2633 unsigned long mem_freq; 2647 unsigned long mem_freq;
2634 unsigned long display_sr; 2648 unsigned long display_sr;
@@ -2638,33 +2652,45 @@ struct cxsr_latency {
2638}; 2652};
2639 2653
2640static struct cxsr_latency cxsr_latency_table[] = { 2654static struct cxsr_latency cxsr_latency_table[] = {
2641 {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ 2655 {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */
2642 {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ 2656 {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */
2643 {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ 2657 {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */
2644 2658 {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */
2645 {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ 2659 {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */
2646 {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ 2660
2647 {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ 2661 {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */
2648 2662 {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */
2649 {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ 2663 {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */
2650 {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ 2664 {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */
2651 {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ 2665 {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */
2652 2666
2653 {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ 2667 {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */
2654 {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ 2668 {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */
2655 {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ 2669 {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */
2656 2670 {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */
2657 {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ 2671 {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */
2658 {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ 2672
2659 {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ 2673 {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */
2660 2674 {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */
2661 {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ 2675 {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */
2662 {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ 2676 {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */
2663 {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ 2677 {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */
2678
2679 {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */
2680 {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */
2681 {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */
2682 {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */
2683 {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */
2684
2685 {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */
2686 {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */
2687 {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */
2688 {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */
2689 {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */
2664}; 2690};
2665 2691
2666static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, 2692static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3,
2667 int mem) 2693 int fsb, int mem)
2668{ 2694{
2669 int i; 2695 int i;
2670 struct cxsr_latency *latency; 2696 struct cxsr_latency *latency;
@@ -2675,6 +2701,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
2675 for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { 2701 for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) {
2676 latency = &cxsr_latency_table[i]; 2702 latency = &cxsr_latency_table[i];
2677 if (is_desktop == latency->is_desktop && 2703 if (is_desktop == latency->is_desktop &&
2704 is_ddr3 == latency->is_ddr3 &&
2678 fsb == latency->fsb_freq && mem == latency->mem_freq) 2705 fsb == latency->fsb_freq && mem == latency->mem_freq)
2679 return latency; 2706 return latency;
2680 } 2707 }
@@ -2789,8 +2816,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock,
2789 struct cxsr_latency *latency; 2816 struct cxsr_latency *latency;
2790 int sr_clock; 2817 int sr_clock;
2791 2818
2792 latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq, 2819 latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3,
2793 dev_priv->mem_freq); 2820 dev_priv->fsb_freq, dev_priv->mem_freq);
2794 if (!latency) { 2821 if (!latency) {
2795 DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); 2822 DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
2796 pineview_disable_cxsr(dev); 2823 pineview_disable_cxsr(dev);
@@ -3772,6 +3799,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
3772 } 3799 }
3773 } 3800 }
3774 3801
3802 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
3803 pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
3804 /* the chip adds 2 halflines automatically */
3805 adjusted_mode->crtc_vdisplay -= 1;
3806 adjusted_mode->crtc_vtotal -= 1;
3807 adjusted_mode->crtc_vblank_start -= 1;
3808 adjusted_mode->crtc_vblank_end -= 1;
3809 adjusted_mode->crtc_vsync_end -= 1;
3810 adjusted_mode->crtc_vsync_start -= 1;
3811 } else
3812 pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */
3813
3775 I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | 3814 I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
3776 ((adjusted_mode->crtc_htotal - 1) << 16)); 3815 ((adjusted_mode->crtc_htotal - 1) << 16));
3777 I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | 3816 I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
@@ -3934,6 +3973,13 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
3934 DRM_ERROR("failed to pin cursor bo\n"); 3973 DRM_ERROR("failed to pin cursor bo\n");
3935 goto fail_locked; 3974 goto fail_locked;
3936 } 3975 }
3976
3977 ret = i915_gem_object_set_to_gtt_domain(bo, 0);
3978 if (ret) {
3979 DRM_ERROR("failed to move cursor bo into the GTT\n");
3980 goto fail_unpin;
3981 }
3982
3937 addr = obj_priv->gtt_offset; 3983 addr = obj_priv->gtt_offset;
3938 } else { 3984 } else {
3939 ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); 3985 ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
@@ -3977,6 +4023,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
3977 intel_crtc->cursor_bo = bo; 4023 intel_crtc->cursor_bo = bo;
3978 4024
3979 return 0; 4025 return 0;
4026fail_unpin:
4027 i915_gem_object_unpin(bo);
3980fail_locked: 4028fail_locked:
3981 mutex_unlock(&dev->struct_mutex); 4029 mutex_unlock(&dev->struct_mutex);
3982fail: 4030fail:
@@ -4436,6 +4484,8 @@ static void intel_idle_update(struct work_struct *work)
4436 4484
4437 mutex_lock(&dev->struct_mutex); 4485 mutex_lock(&dev->struct_mutex);
4438 4486
4487 i915_update_gfx_val(dev_priv);
4488
4439 if (IS_I945G(dev) || IS_I945GM(dev)) { 4489 if (IS_I945G(dev) || IS_I945GM(dev)) {
4440 DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); 4490 DRM_DEBUG_DRIVER("enable memory self refresh on 945\n");
4441 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); 4491 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
@@ -4564,12 +4614,6 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
4564 spin_lock_irqsave(&dev->event_lock, flags); 4614 spin_lock_irqsave(&dev->event_lock, flags);
4565 work = intel_crtc->unpin_work; 4615 work = intel_crtc->unpin_work;
4566 if (work == NULL || !work->pending) { 4616 if (work == NULL || !work->pending) {
4567 if (work && !work->pending) {
4568 obj_priv = to_intel_bo(work->pending_flip_obj);
4569 DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
4570 obj_priv,
4571 atomic_read(&obj_priv->pending_flip));
4572 }
4573 spin_unlock_irqrestore(&dev->event_lock, flags); 4617 spin_unlock_irqrestore(&dev->event_lock, flags);
4574 return; 4618 return;
4575 } 4619 }
@@ -4629,14 +4673,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4629 unsigned long flags; 4673 unsigned long flags;
4630 int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; 4674 int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
4631 int ret, pipesrc; 4675 int ret, pipesrc;
4632 RING_LOCALS;
4633 4676
4634 work = kzalloc(sizeof *work, GFP_KERNEL); 4677 work = kzalloc(sizeof *work, GFP_KERNEL);
4635 if (work == NULL) 4678 if (work == NULL)
4636 return -ENOMEM; 4679 return -ENOMEM;
4637 4680
4638 mutex_lock(&dev->struct_mutex);
4639
4640 work->event = event; 4681 work->event = event;
4641 work->dev = crtc->dev; 4682 work->dev = crtc->dev;
4642 intel_fb = to_intel_framebuffer(crtc->fb); 4683 intel_fb = to_intel_framebuffer(crtc->fb);
@@ -4646,10 +4687,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4646 /* We borrow the event spin lock for protecting unpin_work */ 4687 /* We borrow the event spin lock for protecting unpin_work */
4647 spin_lock_irqsave(&dev->event_lock, flags); 4688 spin_lock_irqsave(&dev->event_lock, flags);
4648 if (intel_crtc->unpin_work) { 4689 if (intel_crtc->unpin_work) {
4649 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
4650 spin_unlock_irqrestore(&dev->event_lock, flags); 4690 spin_unlock_irqrestore(&dev->event_lock, flags);
4651 kfree(work); 4691 kfree(work);
4652 mutex_unlock(&dev->struct_mutex); 4692
4693 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
4653 return -EBUSY; 4694 return -EBUSY;
4654 } 4695 }
4655 intel_crtc->unpin_work = work; 4696 intel_crtc->unpin_work = work;
@@ -4658,13 +4699,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4658 intel_fb = to_intel_framebuffer(fb); 4699 intel_fb = to_intel_framebuffer(fb);
4659 obj = intel_fb->obj; 4700 obj = intel_fb->obj;
4660 4701
4702 mutex_lock(&dev->struct_mutex);
4661 ret = intel_pin_and_fence_fb_obj(dev, obj); 4703 ret = intel_pin_and_fence_fb_obj(dev, obj);
4662 if (ret != 0) { 4704 if (ret != 0) {
4663 DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
4664 to_intel_bo(obj));
4665 kfree(work);
4666 intel_crtc->unpin_work = NULL;
4667 mutex_unlock(&dev->struct_mutex); 4705 mutex_unlock(&dev->struct_mutex);
4706
4707 spin_lock_irqsave(&dev->event_lock, flags);
4708 intel_crtc->unpin_work = NULL;
4709 spin_unlock_irqrestore(&dev->event_lock, flags);
4710
4711 kfree(work);
4712
4713 DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
4714 to_intel_bo(obj));
4668 return ret; 4715 return ret;
4669 } 4716 }
4670 4717
@@ -5023,10 +5070,32 @@ err_unref:
5023 return NULL; 5070 return NULL;
5024} 5071}
5025 5072
5073bool ironlake_set_drps(struct drm_device *dev, u8 val)
5074{
5075 struct drm_i915_private *dev_priv = dev->dev_private;
5076 u16 rgvswctl;
5077
5078 rgvswctl = I915_READ16(MEMSWCTL);
5079 if (rgvswctl & MEMCTL_CMD_STS) {
5080 DRM_DEBUG("gpu busy, RCS change rejected\n");
5081 return false; /* still busy with another command */
5082 }
5083
5084 rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
5085 (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
5086 I915_WRITE16(MEMSWCTL, rgvswctl);
5087 POSTING_READ16(MEMSWCTL);
5088
5089 rgvswctl |= MEMCTL_CMD_STS;
5090 I915_WRITE16(MEMSWCTL, rgvswctl);
5091
5092 return true;
5093}
5094
5026void ironlake_enable_drps(struct drm_device *dev) 5095void ironlake_enable_drps(struct drm_device *dev)
5027{ 5096{
5028 struct drm_i915_private *dev_priv = dev->dev_private; 5097 struct drm_i915_private *dev_priv = dev->dev_private;
5029 u32 rgvmodectl = I915_READ(MEMMODECTL), rgvswctl; 5098 u32 rgvmodectl = I915_READ(MEMMODECTL);
5030 u8 fmax, fmin, fstart, vstart; 5099 u8 fmax, fmin, fstart, vstart;
5031 int i = 0; 5100 int i = 0;
5032 5101
@@ -5045,13 +5114,21 @@ void ironlake_enable_drps(struct drm_device *dev)
5045 fmin = (rgvmodectl & MEMMODE_FMIN_MASK); 5114 fmin = (rgvmodectl & MEMMODE_FMIN_MASK);
5046 fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> 5115 fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
5047 MEMMODE_FSTART_SHIFT; 5116 MEMMODE_FSTART_SHIFT;
5117 fstart = fmax;
5118
5048 vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> 5119 vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >>
5049 PXVFREQ_PX_SHIFT; 5120 PXVFREQ_PX_SHIFT;
5050 5121
5051 dev_priv->max_delay = fstart; /* can't go to fmax w/o IPS */ 5122 dev_priv->fmax = fstart; /* IPS callback will increase this */
5123 dev_priv->fstart = fstart;
5124
5125 dev_priv->max_delay = fmax;
5052 dev_priv->min_delay = fmin; 5126 dev_priv->min_delay = fmin;
5053 dev_priv->cur_delay = fstart; 5127 dev_priv->cur_delay = fstart;
5054 5128
5129 DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin,
5130 fstart);
5131
5055 I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); 5132 I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN);
5056 5133
5057 /* 5134 /*
@@ -5073,20 +5150,19 @@ void ironlake_enable_drps(struct drm_device *dev)
5073 } 5150 }
5074 msleep(1); 5151 msleep(1);
5075 5152
5076 rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | 5153 ironlake_set_drps(dev, fstart);
5077 (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
5078 I915_WRITE(MEMSWCTL, rgvswctl);
5079 POSTING_READ(MEMSWCTL);
5080 5154
5081 rgvswctl |= MEMCTL_CMD_STS; 5155 dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) +
5082 I915_WRITE(MEMSWCTL, rgvswctl); 5156 I915_READ(0x112e0);
5157 dev_priv->last_time1 = jiffies_to_msecs(jiffies);
5158 dev_priv->last_count2 = I915_READ(0x112f4);
5159 getrawmonotonic(&dev_priv->last_time2);
5083} 5160}
5084 5161
5085void ironlake_disable_drps(struct drm_device *dev) 5162void ironlake_disable_drps(struct drm_device *dev)
5086{ 5163{
5087 struct drm_i915_private *dev_priv = dev->dev_private; 5164 struct drm_i915_private *dev_priv = dev->dev_private;
5088 u32 rgvswctl; 5165 u16 rgvswctl = I915_READ16(MEMSWCTL);
5089 u8 fstart;
5090 5166
5091 /* Ack interrupts, disable EFC interrupt */ 5167 /* Ack interrupts, disable EFC interrupt */
5092 I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); 5168 I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN);
@@ -5096,11 +5172,7 @@ void ironlake_disable_drps(struct drm_device *dev)
5096 I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); 5172 I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT);
5097 5173
5098 /* Go back to the starting frequency */ 5174 /* Go back to the starting frequency */
5099 fstart = (I915_READ(MEMMODECTL) & MEMMODE_FSTART_MASK) >> 5175 ironlake_set_drps(dev, dev_priv->fstart);
5100 MEMMODE_FSTART_SHIFT;
5101 rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
5102 (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
5103 I915_WRITE(MEMSWCTL, rgvswctl);
5104 msleep(1); 5176 msleep(1);
5105 rgvswctl |= MEMCTL_CMD_STS; 5177 rgvswctl |= MEMCTL_CMD_STS;
5106 I915_WRITE(MEMSWCTL, rgvswctl); 5178 I915_WRITE(MEMSWCTL, rgvswctl);
@@ -5108,6 +5180,92 @@ void ironlake_disable_drps(struct drm_device *dev)
5108 5180
5109} 5181}
5110 5182
5183static unsigned long intel_pxfreq(u32 vidfreq)
5184{
5185 unsigned long freq;
5186 int div = (vidfreq & 0x3f0000) >> 16;
5187 int post = (vidfreq & 0x3000) >> 12;
5188 int pre = (vidfreq & 0x7);
5189
5190 if (!pre)
5191 return 0;
5192
5193 freq = ((div * 133333) / ((1<<post) * pre));
5194
5195 return freq;
5196}
5197
5198void intel_init_emon(struct drm_device *dev)
5199{
5200 struct drm_i915_private *dev_priv = dev->dev_private;
5201 u32 lcfuse;
5202 u8 pxw[16];
5203 int i;
5204
5205 /* Disable to program */
5206 I915_WRITE(ECR, 0);
5207 POSTING_READ(ECR);
5208
5209 /* Program energy weights for various events */
5210 I915_WRITE(SDEW, 0x15040d00);
5211 I915_WRITE(CSIEW0, 0x007f0000);
5212 I915_WRITE(CSIEW1, 0x1e220004);
5213 I915_WRITE(CSIEW2, 0x04000004);
5214
5215 for (i = 0; i < 5; i++)
5216 I915_WRITE(PEW + (i * 4), 0);
5217 for (i = 0; i < 3; i++)
5218 I915_WRITE(DEW + (i * 4), 0);
5219
5220 /* Program P-state weights to account for frequency power adjustment */
5221 for (i = 0; i < 16; i++) {
5222 u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4));
5223 unsigned long freq = intel_pxfreq(pxvidfreq);
5224 unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >>
5225 PXVFREQ_PX_SHIFT;
5226 unsigned long val;
5227
5228 val = vid * vid;
5229 val *= (freq / 1000);
5230 val *= 255;
5231 val /= (127*127*900);
5232 if (val > 0xff)
5233 DRM_ERROR("bad pxval: %ld\n", val);
5234 pxw[i] = val;
5235 }
5236 /* Render standby states get 0 weight */
5237 pxw[14] = 0;
5238 pxw[15] = 0;
5239
5240 for (i = 0; i < 4; i++) {
5241 u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) |
5242 (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]);
5243 I915_WRITE(PXW + (i * 4), val);
5244 }
5245
5246 /* Adjust magic regs to magic values (more experimental results) */
5247 I915_WRITE(OGW0, 0);
5248 I915_WRITE(OGW1, 0);
5249 I915_WRITE(EG0, 0x00007f00);
5250 I915_WRITE(EG1, 0x0000000e);
5251 I915_WRITE(EG2, 0x000e0000);
5252 I915_WRITE(EG3, 0x68000300);
5253 I915_WRITE(EG4, 0x42000000);
5254 I915_WRITE(EG5, 0x00140031);
5255 I915_WRITE(EG6, 0);
5256 I915_WRITE(EG7, 0);
5257
5258 for (i = 0; i < 8; i++)
5259 I915_WRITE(PXWL + (i * 4), 0);
5260
5261 /* Enable PMON + select events */
5262 I915_WRITE(ECR, 0x80000019);
5263
5264 lcfuse = I915_READ(LCFUSE02);
5265
5266 dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
5267}
5268
5111void intel_init_clock_gating(struct drm_device *dev) 5269void intel_init_clock_gating(struct drm_device *dev)
5112{ 5270{
5113 struct drm_i915_private *dev_priv = dev->dev_private; 5271 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5277,11 +5435,13 @@ static void intel_init_display(struct drm_device *dev)
5277 dev_priv->display.update_wm = NULL; 5435 dev_priv->display.update_wm = NULL;
5278 } else if (IS_PINEVIEW(dev)) { 5436 } else if (IS_PINEVIEW(dev)) {
5279 if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), 5437 if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
5438 dev_priv->is_ddr3,
5280 dev_priv->fsb_freq, 5439 dev_priv->fsb_freq,
5281 dev_priv->mem_freq)) { 5440 dev_priv->mem_freq)) {
5282 DRM_INFO("failed to find known CxSR latency " 5441 DRM_INFO("failed to find known CxSR latency "
5283 "(found fsb freq %d, mem freq %d), " 5442 "(found ddr%s fsb freq %d, mem freq %d), "
5284 "disabling CxSR\n", 5443 "disabling CxSR\n",
5444 (dev_priv->is_ddr3 == 1) ? "3": "2",
5285 dev_priv->fsb_freq, dev_priv->mem_freq); 5445 dev_priv->fsb_freq, dev_priv->mem_freq);
5286 /* Disable CxSR and never update its watermark again */ 5446 /* Disable CxSR and never update its watermark again */
5287 pineview_disable_cxsr(dev); 5447 pineview_disable_cxsr(dev);
@@ -5354,8 +5514,10 @@ void intel_modeset_init(struct drm_device *dev)
5354 5514
5355 intel_init_clock_gating(dev); 5515 intel_init_clock_gating(dev);
5356 5516
5357 if (IS_IRONLAKE_M(dev)) 5517 if (IS_IRONLAKE_M(dev)) {
5358 ironlake_enable_drps(dev); 5518 ironlake_enable_drps(dev);
5519 intel_init_emon(dev);
5520 }
5359 5521
5360 INIT_WORK(&dev_priv->idle_work, intel_idle_update); 5522 INIT_WORK(&dev_priv->idle_work, intel_idle_update);
5361 setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, 5523 setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 6b1c9a27c27a..49b54f05d3cf 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -576,7 +576,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
576 struct intel_encoder *intel_encoder; 576 struct intel_encoder *intel_encoder;
577 struct intel_dp_priv *dp_priv; 577 struct intel_dp_priv *dp_priv;
578 578
579 if (!encoder || encoder->crtc != crtc) 579 if (encoder->crtc != crtc)
580 continue; 580 continue;
581 581
582 intel_encoder = enc_to_intel_encoder(encoder); 582 intel_encoder = enc_to_intel_encoder(encoder);
@@ -675,10 +675,9 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
675 dp_priv->link_configuration[1] = dp_priv->lane_count; 675 dp_priv->link_configuration[1] = dp_priv->lane_count;
676 676
677 /* 677 /*
678 * Check for DPCD version > 1.1, 678 * Check for DPCD version > 1.1 and enhanced framing support
679 * enable enahanced frame stuff in that case
680 */ 679 */
681 if (dp_priv->dpcd[0] >= 0x11) { 680 if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) {
682 dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; 681 dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
683 dp_priv->DP |= DP_ENHANCED_FRAMING; 682 dp_priv->DP |= DP_ENHANCED_FRAMING;
684 } 683 }
@@ -1208,6 +1207,8 @@ ironlake_dp_detect(struct drm_connector *connector)
1208 if (dp_priv->dpcd[0] != 0) 1207 if (dp_priv->dpcd[0] != 0)
1209 status = connector_status_connected; 1208 status = connector_status_connected;
1210 } 1209 }
1210 DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0],
1211 dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]);
1211 return status; 1212 return status;
1212} 1213}
1213 1214
@@ -1352,7 +1353,7 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc)
1352 struct intel_encoder *intel_encoder = NULL; 1353 struct intel_encoder *intel_encoder = NULL;
1353 1354
1354 list_for_each_entry(encoder, &mode_config->encoder_list, head) { 1355 list_for_each_entry(encoder, &mode_config->encoder_list, head) {
1355 if (!encoder || encoder->crtc != crtc) 1356 if (encoder->crtc != crtc)
1356 continue; 1357 continue;
1357 1358
1358 intel_encoder = enc_to_intel_encoder(encoder); 1359 intel_encoder = enc_to_intel_encoder(encoder);
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 6f53cf7fbc50..f8c76e64bb77 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -105,7 +105,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
105 } 105 }
106 106
107 /* Flush everything out, we'll be doing GTT only from now on */ 107 /* Flush everything out, we'll be doing GTT only from now on */
108 i915_gem_object_set_to_gtt_domain(fbo, 1); 108 ret = i915_gem_object_set_to_gtt_domain(fbo, 1);
109 if (ret) {
110 DRM_ERROR("failed to bind fb: %d.\n", ret);
111 goto out_unpin;
112 }
109 113
110 info = framebuffer_alloc(0, device); 114 info = framebuffer_alloc(0, device);
111 if (!info) { 115 if (!info) {
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 65727f0a79a3..83bd764b000e 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -59,8 +59,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
59 SDVO_VSYNC_ACTIVE_HIGH | 59 SDVO_VSYNC_ACTIVE_HIGH |
60 SDVO_HSYNC_ACTIVE_HIGH; 60 SDVO_HSYNC_ACTIVE_HIGH;
61 61
62 if (hdmi_priv->has_hdmi_sink) 62 if (hdmi_priv->has_hdmi_sink) {
63 sdvox |= SDVO_AUDIO_ENABLE; 63 sdvox |= SDVO_AUDIO_ENABLE;
64 if (HAS_PCH_CPT(dev))
65 sdvox |= HDMI_MODE_SELECT;
66 }
64 67
65 if (intel_crtc->pipe == 1) { 68 if (intel_crtc->pipe == 1) {
66 if (HAS_PCH_CPT(dev)) 69 if (HAS_PCH_CPT(dev))
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index b0e17b06eb6e..d7ad5139d17c 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -211,9 +211,8 @@ static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay)
211static int intel_overlay_on(struct intel_overlay *overlay) 211static int intel_overlay_on(struct intel_overlay *overlay)
212{ 212{
213 struct drm_device *dev = overlay->dev; 213 struct drm_device *dev = overlay->dev;
214 drm_i915_private_t *dev_priv = dev->dev_private;
215 int ret; 214 int ret;
216 RING_LOCALS; 215 drm_i915_private_t *dev_priv = dev->dev_private;
217 216
218 BUG_ON(overlay->active); 217 BUG_ON(overlay->active);
219 218
@@ -227,11 +226,13 @@ static int intel_overlay_on(struct intel_overlay *overlay)
227 OUT_RING(MI_NOOP); 226 OUT_RING(MI_NOOP);
228 ADVANCE_LP_RING(); 227 ADVANCE_LP_RING();
229 228
230 overlay->last_flip_req = i915_add_request(dev, NULL, 0); 229 overlay->last_flip_req =
230 i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
231 if (overlay->last_flip_req == 0) 231 if (overlay->last_flip_req == 0)
232 return -ENOMEM; 232 return -ENOMEM;
233 233
234 ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); 234 ret = i915_do_wait_request(dev,
235 overlay->last_flip_req, 1, &dev_priv->render_ring);
235 if (ret != 0) 236 if (ret != 0)
236 return ret; 237 return ret;
237 238
@@ -248,7 +249,6 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
248 drm_i915_private_t *dev_priv = dev->dev_private; 249 drm_i915_private_t *dev_priv = dev->dev_private;
249 u32 flip_addr = overlay->flip_addr; 250 u32 flip_addr = overlay->flip_addr;
250 u32 tmp; 251 u32 tmp;
251 RING_LOCALS;
252 252
253 BUG_ON(!overlay->active); 253 BUG_ON(!overlay->active);
254 254
@@ -265,7 +265,8 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
265 OUT_RING(flip_addr); 265 OUT_RING(flip_addr);
266 ADVANCE_LP_RING(); 266 ADVANCE_LP_RING();
267 267
268 overlay->last_flip_req = i915_add_request(dev, NULL, 0); 268 overlay->last_flip_req =
269 i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
269} 270}
270 271
271static int intel_overlay_wait_flip(struct intel_overlay *overlay) 272static int intel_overlay_wait_flip(struct intel_overlay *overlay)
@@ -274,10 +275,10 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay)
274 drm_i915_private_t *dev_priv = dev->dev_private; 275 drm_i915_private_t *dev_priv = dev->dev_private;
275 int ret; 276 int ret;
276 u32 tmp; 277 u32 tmp;
277 RING_LOCALS;
278 278
279 if (overlay->last_flip_req != 0) { 279 if (overlay->last_flip_req != 0) {
280 ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); 280 ret = i915_do_wait_request(dev, overlay->last_flip_req,
281 1, &dev_priv->render_ring);
281 if (ret == 0) { 282 if (ret == 0) {
282 overlay->last_flip_req = 0; 283 overlay->last_flip_req = 0;
283 284
@@ -296,11 +297,13 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay)
296 OUT_RING(MI_NOOP); 297 OUT_RING(MI_NOOP);
297 ADVANCE_LP_RING(); 298 ADVANCE_LP_RING();
298 299
299 overlay->last_flip_req = i915_add_request(dev, NULL, 0); 300 overlay->last_flip_req =
301 i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
300 if (overlay->last_flip_req == 0) 302 if (overlay->last_flip_req == 0)
301 return -ENOMEM; 303 return -ENOMEM;
302 304
303 ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); 305 ret = i915_do_wait_request(dev, overlay->last_flip_req,
306 1, &dev_priv->render_ring);
304 if (ret != 0) 307 if (ret != 0)
305 return ret; 308 return ret;
306 309
@@ -314,9 +317,8 @@ static int intel_overlay_off(struct intel_overlay *overlay)
314{ 317{
315 u32 flip_addr = overlay->flip_addr; 318 u32 flip_addr = overlay->flip_addr;
316 struct drm_device *dev = overlay->dev; 319 struct drm_device *dev = overlay->dev;
317 drm_i915_private_t *dev_priv = dev->dev_private; 320 drm_i915_private_t *dev_priv = dev->dev_private;
318 int ret; 321 int ret;
319 RING_LOCALS;
320 322
321 BUG_ON(!overlay->active); 323 BUG_ON(!overlay->active);
322 324
@@ -336,11 +338,13 @@ static int intel_overlay_off(struct intel_overlay *overlay)
336 OUT_RING(MI_NOOP); 338 OUT_RING(MI_NOOP);
337 ADVANCE_LP_RING(); 339 ADVANCE_LP_RING();
338 340
339 overlay->last_flip_req = i915_add_request(dev, NULL, 0); 341 overlay->last_flip_req =
342 i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
340 if (overlay->last_flip_req == 0) 343 if (overlay->last_flip_req == 0)
341 return -ENOMEM; 344 return -ENOMEM;
342 345
343 ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); 346 ret = i915_do_wait_request(dev, overlay->last_flip_req,
347 1, &dev_priv->render_ring);
344 if (ret != 0) 348 if (ret != 0)
345 return ret; 349 return ret;
346 350
@@ -354,11 +358,13 @@ static int intel_overlay_off(struct intel_overlay *overlay)
354 OUT_RING(MI_NOOP); 358 OUT_RING(MI_NOOP);
355 ADVANCE_LP_RING(); 359 ADVANCE_LP_RING();
356 360
357 overlay->last_flip_req = i915_add_request(dev, NULL, 0); 361 overlay->last_flip_req =
362 i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
358 if (overlay->last_flip_req == 0) 363 if (overlay->last_flip_req == 0)
359 return -ENOMEM; 364 return -ENOMEM;
360 365
361 ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); 366 ret = i915_do_wait_request(dev, overlay->last_flip_req,
367 1, &dev_priv->render_ring);
362 if (ret != 0) 368 if (ret != 0)
363 return ret; 369 return ret;
364 370
@@ -390,22 +396,23 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
390 int interruptible) 396 int interruptible)
391{ 397{
392 struct drm_device *dev = overlay->dev; 398 struct drm_device *dev = overlay->dev;
393 drm_i915_private_t *dev_priv = dev->dev_private;
394 struct drm_gem_object *obj; 399 struct drm_gem_object *obj;
400 drm_i915_private_t *dev_priv = dev->dev_private;
395 u32 flip_addr; 401 u32 flip_addr;
396 int ret; 402 int ret;
397 RING_LOCALS;
398 403
399 if (overlay->hw_wedged == HW_WEDGED) 404 if (overlay->hw_wedged == HW_WEDGED)
400 return -EIO; 405 return -EIO;
401 406
402 if (overlay->last_flip_req == 0) { 407 if (overlay->last_flip_req == 0) {
403 overlay->last_flip_req = i915_add_request(dev, NULL, 0); 408 overlay->last_flip_req =
409 i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
404 if (overlay->last_flip_req == 0) 410 if (overlay->last_flip_req == 0)
405 return -ENOMEM; 411 return -ENOMEM;
406 } 412 }
407 413
408 ret = i915_do_wait_request(dev, overlay->last_flip_req, interruptible); 414 ret = i915_do_wait_request(dev, overlay->last_flip_req,
415 interruptible, &dev_priv->render_ring);
409 if (ret != 0) 416 if (ret != 0)
410 return ret; 417 return ret;
411 418
@@ -429,12 +436,13 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
429 OUT_RING(MI_NOOP); 436 OUT_RING(MI_NOOP);
430 ADVANCE_LP_RING(); 437 ADVANCE_LP_RING();
431 438
432 overlay->last_flip_req = i915_add_request(dev, NULL, 0); 439 overlay->last_flip_req = i915_add_request(dev, NULL,
440 0, &dev_priv->render_ring);
433 if (overlay->last_flip_req == 0) 441 if (overlay->last_flip_req == 0)
434 return -ENOMEM; 442 return -ENOMEM;
435 443
436 ret = i915_do_wait_request(dev, overlay->last_flip_req, 444 ret = i915_do_wait_request(dev, overlay->last_flip_req,
437 interruptible); 445 interruptible, &dev_priv->render_ring);
438 if (ret != 0) 446 if (ret != 0)
439 return ret; 447 return ret;
440 448
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
new file mode 100644
index 000000000000..cea4f1a8709e
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -0,0 +1,849 @@
1/*
2 * Copyright © 2008-2010 Intel Corporation
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 * Zou Nan hai <nanhai.zou@intel.com>
26 * Xiang Hai hao<haihao.xiang@intel.com>
27 *
28 */
29
30#include "drmP.h"
31#include "drm.h"
32#include "i915_drv.h"
33#include "i915_drm.h"
34#include "i915_trace.h"
35
36static void
37render_ring_flush(struct drm_device *dev,
38 struct intel_ring_buffer *ring,
39 u32 invalidate_domains,
40 u32 flush_domains)
41{
42#if WATCH_EXEC
43 DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
44 invalidate_domains, flush_domains);
45#endif
46 u32 cmd;
47 trace_i915_gem_request_flush(dev, ring->next_seqno,
48 invalidate_domains, flush_domains);
49
50 if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) {
51 /*
52 * read/write caches:
53 *
54 * I915_GEM_DOMAIN_RENDER is always invalidated, but is
55 * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
56 * also flushed at 2d versus 3d pipeline switches.
57 *
58 * read-only caches:
59 *
60 * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
61 * MI_READ_FLUSH is set, and is always flushed on 965.
62 *
63 * I915_GEM_DOMAIN_COMMAND may not exist?
64 *
65 * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
66 * invalidated when MI_EXE_FLUSH is set.
67 *
68 * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
69 * invalidated with every MI_FLUSH.
70 *
71 * TLBs:
72 *
73 * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
74 * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
75 * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
76 * are flushed at any MI_FLUSH.
77 */
78
79 cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
80 if ((invalidate_domains|flush_domains) &
81 I915_GEM_DOMAIN_RENDER)
82 cmd &= ~MI_NO_WRITE_FLUSH;
83 if (!IS_I965G(dev)) {
84 /*
85 * On the 965, the sampler cache always gets flushed
86 * and this bit is reserved.
87 */
88 if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
89 cmd |= MI_READ_FLUSH;
90 }
91 if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
92 cmd |= MI_EXE_FLUSH;
93
94#if WATCH_EXEC
95 DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
96#endif
97 intel_ring_begin(dev, ring, 8);
98 intel_ring_emit(dev, ring, cmd);
99 intel_ring_emit(dev, ring, MI_NOOP);
100 intel_ring_advance(dev, ring);
101 }
102}
103
104static unsigned int render_ring_get_head(struct drm_device *dev,
105 struct intel_ring_buffer *ring)
106{
107 drm_i915_private_t *dev_priv = dev->dev_private;
108 return I915_READ(PRB0_HEAD) & HEAD_ADDR;
109}
110
111static unsigned int render_ring_get_tail(struct drm_device *dev,
112 struct intel_ring_buffer *ring)
113{
114 drm_i915_private_t *dev_priv = dev->dev_private;
115 return I915_READ(PRB0_TAIL) & TAIL_ADDR;
116}
117
118static unsigned int render_ring_get_active_head(struct drm_device *dev,
119 struct intel_ring_buffer *ring)
120{
121 drm_i915_private_t *dev_priv = dev->dev_private;
122 u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
123
124 return I915_READ(acthd_reg);
125}
126
127static void render_ring_advance_ring(struct drm_device *dev,
128 struct intel_ring_buffer *ring)
129{
130 drm_i915_private_t *dev_priv = dev->dev_private;
131 I915_WRITE(PRB0_TAIL, ring->tail);
132}
133
134static int init_ring_common(struct drm_device *dev,
135 struct intel_ring_buffer *ring)
136{
137 u32 head;
138 drm_i915_private_t *dev_priv = dev->dev_private;
139 struct drm_i915_gem_object *obj_priv;
140 obj_priv = to_intel_bo(ring->gem_object);
141
142 /* Stop the ring if it's running. */
143 I915_WRITE(ring->regs.ctl, 0);
144 I915_WRITE(ring->regs.head, 0);
145 I915_WRITE(ring->regs.tail, 0);
146
147 /* Initialize the ring. */
148 I915_WRITE(ring->regs.start, obj_priv->gtt_offset);
149 head = ring->get_head(dev, ring);
150
151 /* G45 ring initialization fails to reset head to zero */
152 if (head != 0) {
153 DRM_ERROR("%s head not reset to zero "
154 "ctl %08x head %08x tail %08x start %08x\n",
155 ring->name,
156 I915_READ(ring->regs.ctl),
157 I915_READ(ring->regs.head),
158 I915_READ(ring->regs.tail),
159 I915_READ(ring->regs.start));
160
161 I915_WRITE(ring->regs.head, 0);
162
163 DRM_ERROR("%s head forced to zero "
164 "ctl %08x head %08x tail %08x start %08x\n",
165 ring->name,
166 I915_READ(ring->regs.ctl),
167 I915_READ(ring->regs.head),
168 I915_READ(ring->regs.tail),
169 I915_READ(ring->regs.start));
170 }
171
172 I915_WRITE(ring->regs.ctl,
173 ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES)
174 | RING_NO_REPORT | RING_VALID);
175
176 head = I915_READ(ring->regs.head) & HEAD_ADDR;
177 /* If the head is still not zero, the ring is dead */
178 if (head != 0) {
179 DRM_ERROR("%s initialization failed "
180 "ctl %08x head %08x tail %08x start %08x\n",
181 ring->name,
182 I915_READ(ring->regs.ctl),
183 I915_READ(ring->regs.head),
184 I915_READ(ring->regs.tail),
185 I915_READ(ring->regs.start));
186 return -EIO;
187 }
188
189 if (!drm_core_check_feature(dev, DRIVER_MODESET))
190 i915_kernel_lost_context(dev);
191 else {
192 ring->head = ring->get_head(dev, ring);
193 ring->tail = ring->get_tail(dev, ring);
194 ring->space = ring->head - (ring->tail + 8);
195 if (ring->space < 0)
196 ring->space += ring->size;
197 }
198 return 0;
199}
200
201static int init_render_ring(struct drm_device *dev,
202 struct intel_ring_buffer *ring)
203{
204 drm_i915_private_t *dev_priv = dev->dev_private;
205 int ret = init_ring_common(dev, ring);
206 if (IS_I9XX(dev) && !IS_GEN3(dev)) {
207 I915_WRITE(MI_MODE,
208 (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
209 }
210 return ret;
211}
212
213#define PIPE_CONTROL_FLUSH(addr) \
214do { \
215 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \
216 PIPE_CONTROL_DEPTH_STALL | 2); \
217 OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \
218 OUT_RING(0); \
219 OUT_RING(0); \
220} while (0)
221
222/**
223 * Creates a new sequence number, emitting a write of it to the status page
224 * plus an interrupt, which will trigger i915_user_interrupt_handler.
225 *
226 * Must be called with struct_lock held.
227 *
228 * Returned sequence numbers are nonzero on success.
229 */
230static u32
231render_ring_add_request(struct drm_device *dev,
232 struct intel_ring_buffer *ring,
233 struct drm_file *file_priv,
234 u32 flush_domains)
235{
236 u32 seqno;
237 drm_i915_private_t *dev_priv = dev->dev_private;
238 seqno = intel_ring_get_seqno(dev, ring);
239
240 if (IS_GEN6(dev)) {
241 BEGIN_LP_RING(6);
242 OUT_RING(GFX_OP_PIPE_CONTROL | 3);
243 OUT_RING(PIPE_CONTROL_QW_WRITE |
244 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
245 PIPE_CONTROL_NOTIFY);
246 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
247 OUT_RING(seqno);
248 OUT_RING(0);
249 OUT_RING(0);
250 ADVANCE_LP_RING();
251 } else if (HAS_PIPE_CONTROL(dev)) {
252 u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
253
254 /*
255 * Workaround qword write incoherence by flushing the
256 * PIPE_NOTIFY buffers out to memory before requesting
257 * an interrupt.
258 */
259 BEGIN_LP_RING(32);
260 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
261 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
262 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
263 OUT_RING(seqno);
264 OUT_RING(0);
265 PIPE_CONTROL_FLUSH(scratch_addr);
266 scratch_addr += 128; /* write to separate cachelines */
267 PIPE_CONTROL_FLUSH(scratch_addr);
268 scratch_addr += 128;
269 PIPE_CONTROL_FLUSH(scratch_addr);
270 scratch_addr += 128;
271 PIPE_CONTROL_FLUSH(scratch_addr);
272 scratch_addr += 128;
273 PIPE_CONTROL_FLUSH(scratch_addr);
274 scratch_addr += 128;
275 PIPE_CONTROL_FLUSH(scratch_addr);
276 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
277 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
278 PIPE_CONTROL_NOTIFY);
279 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
280 OUT_RING(seqno);
281 OUT_RING(0);
282 ADVANCE_LP_RING();
283 } else {
284 BEGIN_LP_RING(4);
285 OUT_RING(MI_STORE_DWORD_INDEX);
286 OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
287 OUT_RING(seqno);
288
289 OUT_RING(MI_USER_INTERRUPT);
290 ADVANCE_LP_RING();
291 }
292 return seqno;
293}
294
295static u32
296render_ring_get_gem_seqno(struct drm_device *dev,
297 struct intel_ring_buffer *ring)
298{
299 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
300 if (HAS_PIPE_CONTROL(dev))
301 return ((volatile u32 *)(dev_priv->seqno_page))[0];
302 else
303 return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
304}
305
306static void
307render_ring_get_user_irq(struct drm_device *dev,
308 struct intel_ring_buffer *ring)
309{
310 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
311 unsigned long irqflags;
312
313 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
314 if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) {
315 if (HAS_PCH_SPLIT(dev))
316 ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
317 else
318 i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
319 }
320 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
321}
322
323static void
324render_ring_put_user_irq(struct drm_device *dev,
325 struct intel_ring_buffer *ring)
326{
327 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
328 unsigned long irqflags;
329
330 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
331 BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0);
332 if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) {
333 if (HAS_PCH_SPLIT(dev))
334 ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
335 else
336 i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
337 }
338 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
339}
340
341static void render_setup_status_page(struct drm_device *dev,
342 struct intel_ring_buffer *ring)
343{
344 drm_i915_private_t *dev_priv = dev->dev_private;
345 if (IS_GEN6(dev)) {
346 I915_WRITE(HWS_PGA_GEN6, ring->status_page.gfx_addr);
347 I915_READ(HWS_PGA_GEN6); /* posting read */
348 } else {
349 I915_WRITE(HWS_PGA, ring->status_page.gfx_addr);
350 I915_READ(HWS_PGA); /* posting read */
351 }
352
353}
354
355void
356bsd_ring_flush(struct drm_device *dev,
357 struct intel_ring_buffer *ring,
358 u32 invalidate_domains,
359 u32 flush_domains)
360{
361 intel_ring_begin(dev, ring, 8);
362 intel_ring_emit(dev, ring, MI_FLUSH);
363 intel_ring_emit(dev, ring, MI_NOOP);
364 intel_ring_advance(dev, ring);
365}
366
367static inline unsigned int bsd_ring_get_head(struct drm_device *dev,
368 struct intel_ring_buffer *ring)
369{
370 drm_i915_private_t *dev_priv = dev->dev_private;
371 return I915_READ(BSD_RING_HEAD) & HEAD_ADDR;
372}
373
374static inline unsigned int bsd_ring_get_tail(struct drm_device *dev,
375 struct intel_ring_buffer *ring)
376{
377 drm_i915_private_t *dev_priv = dev->dev_private;
378 return I915_READ(BSD_RING_TAIL) & TAIL_ADDR;
379}
380
381static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev,
382 struct intel_ring_buffer *ring)
383{
384 drm_i915_private_t *dev_priv = dev->dev_private;
385 return I915_READ(BSD_RING_ACTHD);
386}
387
388static inline void bsd_ring_advance_ring(struct drm_device *dev,
389 struct intel_ring_buffer *ring)
390{
391 drm_i915_private_t *dev_priv = dev->dev_private;
392 I915_WRITE(BSD_RING_TAIL, ring->tail);
393}
394
395static int init_bsd_ring(struct drm_device *dev,
396 struct intel_ring_buffer *ring)
397{
398 return init_ring_common(dev, ring);
399}
400
401static u32
402bsd_ring_add_request(struct drm_device *dev,
403 struct intel_ring_buffer *ring,
404 struct drm_file *file_priv,
405 u32 flush_domains)
406{
407 u32 seqno;
408 seqno = intel_ring_get_seqno(dev, ring);
409 intel_ring_begin(dev, ring, 4);
410 intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX);
411 intel_ring_emit(dev, ring,
412 I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
413 intel_ring_emit(dev, ring, seqno);
414 intel_ring_emit(dev, ring, MI_USER_INTERRUPT);
415 intel_ring_advance(dev, ring);
416
417 DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);
418
419 return seqno;
420}
421
422static void bsd_setup_status_page(struct drm_device *dev,
423 struct intel_ring_buffer *ring)
424{
425 drm_i915_private_t *dev_priv = dev->dev_private;
426 I915_WRITE(BSD_HWS_PGA, ring->status_page.gfx_addr);
427 I915_READ(BSD_HWS_PGA);
428}
429
430static void
431bsd_ring_get_user_irq(struct drm_device *dev,
432 struct intel_ring_buffer *ring)
433{
434 /* do nothing */
435}
436static void
437bsd_ring_put_user_irq(struct drm_device *dev,
438 struct intel_ring_buffer *ring)
439{
440 /* do nothing */
441}
442
443static u32
444bsd_ring_get_gem_seqno(struct drm_device *dev,
445 struct intel_ring_buffer *ring)
446{
447 return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
448}
449
450static int
451bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev,
452 struct intel_ring_buffer *ring,
453 struct drm_i915_gem_execbuffer2 *exec,
454 struct drm_clip_rect *cliprects,
455 uint64_t exec_offset)
456{
457 uint32_t exec_start;
458 exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
459 intel_ring_begin(dev, ring, 2);
460 intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START |
461 (2 << 6) | MI_BATCH_NON_SECURE_I965);
462 intel_ring_emit(dev, ring, exec_start);
463 intel_ring_advance(dev, ring);
464 return 0;
465}
466
467
468static int
469render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
470 struct intel_ring_buffer *ring,
471 struct drm_i915_gem_execbuffer2 *exec,
472 struct drm_clip_rect *cliprects,
473 uint64_t exec_offset)
474{
475 drm_i915_private_t *dev_priv = dev->dev_private;
476 int nbox = exec->num_cliprects;
477 int i = 0, count;
478 uint32_t exec_start, exec_len;
479 exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
480 exec_len = (uint32_t) exec->batch_len;
481
482 trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1);
483
484 count = nbox ? nbox : 1;
485
486 for (i = 0; i < count; i++) {
487 if (i < nbox) {
488 int ret = i915_emit_box(dev, cliprects, i,
489 exec->DR1, exec->DR4);
490 if (ret)
491 return ret;
492 }
493
494 if (IS_I830(dev) || IS_845G(dev)) {
495 intel_ring_begin(dev, ring, 4);
496 intel_ring_emit(dev, ring, MI_BATCH_BUFFER);
497 intel_ring_emit(dev, ring,
498 exec_start | MI_BATCH_NON_SECURE);
499 intel_ring_emit(dev, ring, exec_start + exec_len - 4);
500 intel_ring_emit(dev, ring, 0);
501 } else {
502 intel_ring_begin(dev, ring, 4);
503 if (IS_I965G(dev)) {
504 intel_ring_emit(dev, ring,
505 MI_BATCH_BUFFER_START | (2 << 6)
506 | MI_BATCH_NON_SECURE_I965);
507 intel_ring_emit(dev, ring, exec_start);
508 } else {
509 intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START
510 | (2 << 6));
511 intel_ring_emit(dev, ring, exec_start |
512 MI_BATCH_NON_SECURE);
513 }
514 }
515 intel_ring_advance(dev, ring);
516 }
517
518 /* XXX breadcrumb */
519 return 0;
520}
521
522static void cleanup_status_page(struct drm_device *dev,
523 struct intel_ring_buffer *ring)
524{
525 drm_i915_private_t *dev_priv = dev->dev_private;
526 struct drm_gem_object *obj;
527 struct drm_i915_gem_object *obj_priv;
528
529 obj = ring->status_page.obj;
530 if (obj == NULL)
531 return;
532 obj_priv = to_intel_bo(obj);
533
534 kunmap(obj_priv->pages[0]);
535 i915_gem_object_unpin(obj);
536 drm_gem_object_unreference(obj);
537 ring->status_page.obj = NULL;
538
539 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
540}
541
542static int init_status_page(struct drm_device *dev,
543 struct intel_ring_buffer *ring)
544{
545 drm_i915_private_t *dev_priv = dev->dev_private;
546 struct drm_gem_object *obj;
547 struct drm_i915_gem_object *obj_priv;
548 int ret;
549
550 obj = i915_gem_alloc_object(dev, 4096);
551 if (obj == NULL) {
552 DRM_ERROR("Failed to allocate status page\n");
553 ret = -ENOMEM;
554 goto err;
555 }
556 obj_priv = to_intel_bo(obj);
557 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
558
559 ret = i915_gem_object_pin(obj, 4096);
560 if (ret != 0) {
561 goto err_unref;
562 }
563
564 ring->status_page.gfx_addr = obj_priv->gtt_offset;
565 ring->status_page.page_addr = kmap(obj_priv->pages[0]);
566 if (ring->status_page.page_addr == NULL) {
567 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
568 goto err_unpin;
569 }
570 ring->status_page.obj = obj;
571 memset(ring->status_page.page_addr, 0, PAGE_SIZE);
572
573 ring->setup_status_page(dev, ring);
574 DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
575 ring->name, ring->status_page.gfx_addr);
576
577 return 0;
578
579err_unpin:
580 i915_gem_object_unpin(obj);
581err_unref:
582 drm_gem_object_unreference(obj);
583err:
584 return ret;
585}
586
587
588int intel_init_ring_buffer(struct drm_device *dev,
589 struct intel_ring_buffer *ring)
590{
591 int ret;
592 struct drm_i915_gem_object *obj_priv;
593 struct drm_gem_object *obj;
594 ring->dev = dev;
595
596 if (I915_NEED_GFX_HWS(dev)) {
597 ret = init_status_page(dev, ring);
598 if (ret)
599 return ret;
600 }
601
602 obj = i915_gem_alloc_object(dev, ring->size);
603 if (obj == NULL) {
604 DRM_ERROR("Failed to allocate ringbuffer\n");
605 ret = -ENOMEM;
606 goto cleanup;
607 }
608
609 ring->gem_object = obj;
610
611 ret = i915_gem_object_pin(obj, ring->alignment);
612 if (ret != 0) {
613 drm_gem_object_unreference(obj);
614 goto cleanup;
615 }
616
617 obj_priv = to_intel_bo(obj);
618 ring->map.size = ring->size;
619 ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
620 ring->map.type = 0;
621 ring->map.flags = 0;
622 ring->map.mtrr = 0;
623
624 drm_core_ioremap_wc(&ring->map, dev);
625 if (ring->map.handle == NULL) {
626 DRM_ERROR("Failed to map ringbuffer.\n");
627 i915_gem_object_unpin(obj);
628 drm_gem_object_unreference(obj);
629 ret = -EINVAL;
630 goto cleanup;
631 }
632
633 ring->virtual_start = ring->map.handle;
634 ret = ring->init(dev, ring);
635 if (ret != 0) {
636 intel_cleanup_ring_buffer(dev, ring);
637 return ret;
638 }
639
640 if (!drm_core_check_feature(dev, DRIVER_MODESET))
641 i915_kernel_lost_context(dev);
642 else {
643 ring->head = ring->get_head(dev, ring);
644 ring->tail = ring->get_tail(dev, ring);
645 ring->space = ring->head - (ring->tail + 8);
646 if (ring->space < 0)
647 ring->space += ring->size;
648 }
649 INIT_LIST_HEAD(&ring->active_list);
650 INIT_LIST_HEAD(&ring->request_list);
651 return ret;
652cleanup:
653 cleanup_status_page(dev, ring);
654 return ret;
655}
656
657void intel_cleanup_ring_buffer(struct drm_device *dev,
658 struct intel_ring_buffer *ring)
659{
660 if (ring->gem_object == NULL)
661 return;
662
663 drm_core_ioremapfree(&ring->map, dev);
664
665 i915_gem_object_unpin(ring->gem_object);
666 drm_gem_object_unreference(ring->gem_object);
667 ring->gem_object = NULL;
668 cleanup_status_page(dev, ring);
669}
670
671int intel_wrap_ring_buffer(struct drm_device *dev,
672 struct intel_ring_buffer *ring)
673{
674 unsigned int *virt;
675 int rem;
676 rem = ring->size - ring->tail;
677
678 if (ring->space < rem) {
679 int ret = intel_wait_ring_buffer(dev, ring, rem);
680 if (ret)
681 return ret;
682 }
683
684 virt = (unsigned int *)(ring->virtual_start + ring->tail);
685 rem /= 4;
686 while (rem--)
687 *virt++ = MI_NOOP;
688
689 ring->tail = 0;
690
691 return 0;
692}
693
694int intel_wait_ring_buffer(struct drm_device *dev,
695 struct intel_ring_buffer *ring, int n)
696{
697 unsigned long end;
698
699 trace_i915_ring_wait_begin (dev);
700 end = jiffies + 3 * HZ;
701 do {
702 ring->head = ring->get_head(dev, ring);
703 ring->space = ring->head - (ring->tail + 8);
704 if (ring->space < 0)
705 ring->space += ring->size;
706 if (ring->space >= n) {
707 trace_i915_ring_wait_end (dev);
708 return 0;
709 }
710
711 if (dev->primary->master) {
712 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
713 if (master_priv->sarea_priv)
714 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
715 }
716
717 yield();
718 } while (!time_after(jiffies, end));
719 trace_i915_ring_wait_end (dev);
720 return -EBUSY;
721}
722
723void intel_ring_begin(struct drm_device *dev,
724 struct intel_ring_buffer *ring, int n)
725{
726 if (unlikely(ring->tail + n > ring->size))
727 intel_wrap_ring_buffer(dev, ring);
728 if (unlikely(ring->space < n))
729 intel_wait_ring_buffer(dev, ring, n);
730}
731
732void intel_ring_emit(struct drm_device *dev,
733 struct intel_ring_buffer *ring, unsigned int data)
734{
735 unsigned int *virt = ring->virtual_start + ring->tail;
736 *virt = data;
737 ring->tail += 4;
738 ring->tail &= ring->size - 1;
739 ring->space -= 4;
740}
741
742void intel_ring_advance(struct drm_device *dev,
743 struct intel_ring_buffer *ring)
744{
745 ring->advance_ring(dev, ring);
746}
747
748void intel_fill_struct(struct drm_device *dev,
749 struct intel_ring_buffer *ring,
750 void *data,
751 unsigned int len)
752{
753 unsigned int *virt = ring->virtual_start + ring->tail;
754 BUG_ON((len&~(4-1)) != 0);
755 intel_ring_begin(dev, ring, len);
756 memcpy(virt, data, len);
757 ring->tail += len;
758 ring->tail &= ring->size - 1;
759 ring->space -= len;
760 intel_ring_advance(dev, ring);
761}
762
763u32 intel_ring_get_seqno(struct drm_device *dev,
764 struct intel_ring_buffer *ring)
765{
766 u32 seqno;
767 seqno = ring->next_seqno;
768
769 /* reserve 0 for non-seqno */
770 if (++ring->next_seqno == 0)
771 ring->next_seqno = 1;
772 return seqno;
773}
774
775struct intel_ring_buffer render_ring = {
776 .name = "render ring",
777 .regs = {
778 .ctl = PRB0_CTL,
779 .head = PRB0_HEAD,
780 .tail = PRB0_TAIL,
781 .start = PRB0_START
782 },
783 .ring_flag = I915_EXEC_RENDER,
784 .size = 32 * PAGE_SIZE,
785 .alignment = PAGE_SIZE,
786 .virtual_start = NULL,
787 .dev = NULL,
788 .gem_object = NULL,
789 .head = 0,
790 .tail = 0,
791 .space = 0,
792 .next_seqno = 1,
793 .user_irq_refcount = 0,
794 .irq_gem_seqno = 0,
795 .waiting_gem_seqno = 0,
796 .setup_status_page = render_setup_status_page,
797 .init = init_render_ring,
798 .get_head = render_ring_get_head,
799 .get_tail = render_ring_get_tail,
800 .get_active_head = render_ring_get_active_head,
801 .advance_ring = render_ring_advance_ring,
802 .flush = render_ring_flush,
803 .add_request = render_ring_add_request,
804 .get_gem_seqno = render_ring_get_gem_seqno,
805 .user_irq_get = render_ring_get_user_irq,
806 .user_irq_put = render_ring_put_user_irq,
807 .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer,
808 .status_page = {NULL, 0, NULL},
809 .map = {0,}
810};
811
812/* ring buffer for bit-stream decoder */
813
814struct intel_ring_buffer bsd_ring = {
815 .name = "bsd ring",
816 .regs = {
817 .ctl = BSD_RING_CTL,
818 .head = BSD_RING_HEAD,
819 .tail = BSD_RING_TAIL,
820 .start = BSD_RING_START
821 },
822 .ring_flag = I915_EXEC_BSD,
823 .size = 32 * PAGE_SIZE,
824 .alignment = PAGE_SIZE,
825 .virtual_start = NULL,
826 .dev = NULL,
827 .gem_object = NULL,
828 .head = 0,
829 .tail = 0,
830 .space = 0,
831 .next_seqno = 1,
832 .user_irq_refcount = 0,
833 .irq_gem_seqno = 0,
834 .waiting_gem_seqno = 0,
835 .setup_status_page = bsd_setup_status_page,
836 .init = init_bsd_ring,
837 .get_head = bsd_ring_get_head,
838 .get_tail = bsd_ring_get_tail,
839 .get_active_head = bsd_ring_get_active_head,
840 .advance_ring = bsd_ring_advance_ring,
841 .flush = bsd_ring_flush,
842 .add_request = bsd_ring_add_request,
843 .get_gem_seqno = bsd_ring_get_gem_seqno,
844 .user_irq_get = bsd_ring_get_user_irq,
845 .user_irq_put = bsd_ring_put_user_irq,
846 .dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer,
847 .status_page = {NULL, 0, NULL},
848 .map = {0,}
849};
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
new file mode 100644
index 000000000000..d5568d3766de
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -0,0 +1,124 @@
1#ifndef _INTEL_RINGBUFFER_H_
2#define _INTEL_RINGBUFFER_H_
3
4struct intel_hw_status_page {
5 void *page_addr;
6 unsigned int gfx_addr;
7 struct drm_gem_object *obj;
8};
9
10struct drm_i915_gem_execbuffer2;
11struct intel_ring_buffer {
12 const char *name;
13 struct ring_regs {
14 u32 ctl;
15 u32 head;
16 u32 tail;
17 u32 start;
18 } regs;
19 unsigned int ring_flag;
20 unsigned long size;
21 unsigned int alignment;
22 void *virtual_start;
23 struct drm_device *dev;
24 struct drm_gem_object *gem_object;
25
26 unsigned int head;
27 unsigned int tail;
28 unsigned int space;
29 u32 next_seqno;
30 struct intel_hw_status_page status_page;
31
32 u32 irq_gem_seqno; /* last seq seem at irq time */
33 u32 waiting_gem_seqno;
34 int user_irq_refcount;
35 void (*user_irq_get)(struct drm_device *dev,
36 struct intel_ring_buffer *ring);
37 void (*user_irq_put)(struct drm_device *dev,
38 struct intel_ring_buffer *ring);
39 void (*setup_status_page)(struct drm_device *dev,
40 struct intel_ring_buffer *ring);
41
42 int (*init)(struct drm_device *dev,
43 struct intel_ring_buffer *ring);
44
45 unsigned int (*get_head)(struct drm_device *dev,
46 struct intel_ring_buffer *ring);
47 unsigned int (*get_tail)(struct drm_device *dev,
48 struct intel_ring_buffer *ring);
49 unsigned int (*get_active_head)(struct drm_device *dev,
50 struct intel_ring_buffer *ring);
51 void (*advance_ring)(struct drm_device *dev,
52 struct intel_ring_buffer *ring);
53 void (*flush)(struct drm_device *dev,
54 struct intel_ring_buffer *ring,
55 u32 invalidate_domains,
56 u32 flush_domains);
57 u32 (*add_request)(struct drm_device *dev,
58 struct intel_ring_buffer *ring,
59 struct drm_file *file_priv,
60 u32 flush_domains);
61 u32 (*get_gem_seqno)(struct drm_device *dev,
62 struct intel_ring_buffer *ring);
63 int (*dispatch_gem_execbuffer)(struct drm_device *dev,
64 struct intel_ring_buffer *ring,
65 struct drm_i915_gem_execbuffer2 *exec,
66 struct drm_clip_rect *cliprects,
67 uint64_t exec_offset);
68
69 /**
70 * List of objects currently involved in rendering from the
71 * ringbuffer.
72 *
73 * Includes buffers having the contents of their GPU caches
74 * flushed, not necessarily primitives. last_rendering_seqno
75 * represents when the rendering involved will be completed.
76 *
77 * A reference is held on the buffer while on this list.
78 */
79 struct list_head active_list;
80
81 /**
82 * List of breadcrumbs associated with GPU requests currently
83 * outstanding.
84 */
85 struct list_head request_list;
86
87 wait_queue_head_t irq_queue;
88 drm_local_map_t map;
89};
90
91static inline u32
92intel_read_status_page(struct intel_ring_buffer *ring,
93 int reg)
94{
95 u32 *regs = ring->status_page.page_addr;
96 return regs[reg];
97}
98
99int intel_init_ring_buffer(struct drm_device *dev,
100 struct intel_ring_buffer *ring);
101void intel_cleanup_ring_buffer(struct drm_device *dev,
102 struct intel_ring_buffer *ring);
103int intel_wait_ring_buffer(struct drm_device *dev,
104 struct intel_ring_buffer *ring, int n);
105int intel_wrap_ring_buffer(struct drm_device *dev,
106 struct intel_ring_buffer *ring);
107void intel_ring_begin(struct drm_device *dev,
108 struct intel_ring_buffer *ring, int n);
109void intel_ring_emit(struct drm_device *dev,
110 struct intel_ring_buffer *ring, u32 data);
111void intel_fill_struct(struct drm_device *dev,
112 struct intel_ring_buffer *ring,
113 void *data,
114 unsigned int len);
115void intel_ring_advance(struct drm_device *dev,
116 struct intel_ring_buffer *ring);
117
118u32 intel_ring_get_seqno(struct drm_device *dev,
119 struct intel_ring_buffer *ring);
120
121extern struct intel_ring_buffer render_ring;
122extern struct intel_ring_buffer bsd_ring;
123
124#endif /* _INTEL_RINGBUFFER_H_ */
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index aba72c489a2f..76993ac16cc1 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1479,7 +1479,7 @@ intel_find_analog_connector(struct drm_device *dev)
1479 intel_encoder = enc_to_intel_encoder(encoder); 1479 intel_encoder = enc_to_intel_encoder(encoder);
1480 if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { 1480 if (intel_encoder->type == INTEL_OUTPUT_ANALOG) {
1481 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1481 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1482 if (connector && encoder == intel_attached_encoder(connector)) 1482 if (encoder == intel_attached_encoder(connector))
1483 return connector; 1483 return connector;
1484 } 1484 }
1485 } 1485 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index e13f6af0037a..d4bcca8a5133 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -34,7 +34,7 @@
34static struct nouveau_dsm_priv { 34static struct nouveau_dsm_priv {
35 bool dsm_detected; 35 bool dsm_detected;
36 acpi_handle dhandle; 36 acpi_handle dhandle;
37 acpi_handle dsm_handle; 37 acpi_handle rom_handle;
38} nouveau_dsm_priv; 38} nouveau_dsm_priv;
39 39
40static const char nouveau_dsm_muid[] = { 40static const char nouveau_dsm_muid[] = {
@@ -107,9 +107,9 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
107static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) 107static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
108{ 108{
109 if (id == VGA_SWITCHEROO_IGD) 109 if (id == VGA_SWITCHEROO_IGD)
110 return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_STAMINA); 110 return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA);
111 else 111 else
112 return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_SPEED); 112 return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_SPEED);
113} 113}
114 114
115static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, 115static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
@@ -118,7 +118,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
118 if (id == VGA_SWITCHEROO_IGD) 118 if (id == VGA_SWITCHEROO_IGD)
119 return 0; 119 return 0;
120 120
121 return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dsm_handle, state); 121 return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
122} 122}
123 123
124static int nouveau_dsm_init(void) 124static int nouveau_dsm_init(void)
@@ -151,18 +151,18 @@ static bool nouveau_dsm_pci_probe(struct pci_dev *pdev)
151 dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); 151 dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
152 if (!dhandle) 152 if (!dhandle)
153 return false; 153 return false;
154
154 status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle); 155 status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle);
155 if (ACPI_FAILURE(status)) { 156 if (ACPI_FAILURE(status)) {
156 return false; 157 return false;
157 } 158 }
158 159
159 ret= nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED, 160 ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED,
160 NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); 161 NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
161 if (ret < 0) 162 if (ret < 0)
162 return false; 163 return false;
163 164
164 nouveau_dsm_priv.dhandle = dhandle; 165 nouveau_dsm_priv.dhandle = dhandle;
165 nouveau_dsm_priv.dsm_handle = nvidia_handle;
166 return true; 166 return true;
167} 167}
168 168
@@ -173,6 +173,7 @@ static bool nouveau_dsm_detect(void)
173 struct pci_dev *pdev = NULL; 173 struct pci_dev *pdev = NULL;
174 int has_dsm = 0; 174 int has_dsm = 0;
175 int vga_count = 0; 175 int vga_count = 0;
176
176 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { 177 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
177 vga_count++; 178 vga_count++;
178 179
@@ -180,7 +181,7 @@ static bool nouveau_dsm_detect(void)
180 } 181 }
181 182
182 if (vga_count == 2 && has_dsm) { 183 if (vga_count == 2 && has_dsm) {
183 acpi_get_name(nouveau_dsm_priv.dsm_handle, ACPI_FULL_PATHNAME, &buffer); 184 acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
184 printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", 185 printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
185 acpi_method_name); 186 acpi_method_name);
186 nouveau_dsm_priv.dsm_detected = true; 187 nouveau_dsm_priv.dsm_detected = true;
@@ -204,3 +205,57 @@ void nouveau_unregister_dsm_handler(void)
204{ 205{
205 vga_switcheroo_unregister_handler(); 206 vga_switcheroo_unregister_handler();
206} 207}
208
209/* retrieve the ROM in 4k blocks */
210static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios,
211 int offset, int len)
212{
213 acpi_status status;
214 union acpi_object rom_arg_elements[2], *obj;
215 struct acpi_object_list rom_arg;
216 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
217
218 rom_arg.count = 2;
219 rom_arg.pointer = &rom_arg_elements[0];
220
221 rom_arg_elements[0].type = ACPI_TYPE_INTEGER;
222 rom_arg_elements[0].integer.value = offset;
223
224 rom_arg_elements[1].type = ACPI_TYPE_INTEGER;
225 rom_arg_elements[1].integer.value = len;
226
227 status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer);
228 if (ACPI_FAILURE(status)) {
229 printk(KERN_INFO "failed to evaluate ROM got %s\n", acpi_format_exception(status));
230 return -ENODEV;
231 }
232 obj = (union acpi_object *)buffer.pointer;
233 memcpy(bios+offset, obj->buffer.pointer, len);
234 kfree(buffer.pointer);
235 return len;
236}
237
238bool nouveau_acpi_rom_supported(struct pci_dev *pdev)
239{
240 acpi_status status;
241 acpi_handle dhandle, rom_handle;
242
243 if (!nouveau_dsm_priv.dsm_detected)
244 return false;
245
246 dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
247 if (!dhandle)
248 return false;
249
250 status = acpi_get_handle(dhandle, "_ROM", &rom_handle);
251 if (ACPI_FAILURE(status))
252 return false;
253
254 nouveau_dsm_priv.rom_handle = rom_handle;
255 return true;
256}
257
258int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
259{
260 return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
261}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index e7e69ccce5c9..9ba2deaadcc7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -178,6 +178,25 @@ out:
178 pci_disable_rom(dev->pdev); 178 pci_disable_rom(dev->pdev);
179} 179}
180 180
181static void load_vbios_acpi(struct drm_device *dev, uint8_t *data)
182{
183 int i;
184 int ret;
185 int size = 64 * 1024;
186
187 if (!nouveau_acpi_rom_supported(dev->pdev))
188 return;
189
190 for (i = 0; i < (size / ROM_BIOS_PAGE); i++) {
191 ret = nouveau_acpi_get_bios_chunk(data,
192 (i * ROM_BIOS_PAGE),
193 ROM_BIOS_PAGE);
194 if (ret <= 0)
195 break;
196 }
197 return;
198}
199
181struct methods { 200struct methods {
182 const char desc[8]; 201 const char desc[8];
183 void (*loadbios)(struct drm_device *, uint8_t *); 202 void (*loadbios)(struct drm_device *, uint8_t *);
@@ -191,6 +210,7 @@ static struct methods nv04_methods[] = {
191}; 210};
192 211
193static struct methods nv50_methods[] = { 212static struct methods nv50_methods[] = {
213 { "ACPI", load_vbios_acpi, true },
194 { "PRAMIN", load_vbios_pramin, true }, 214 { "PRAMIN", load_vbios_pramin, true },
195 { "PROM", load_vbios_prom, false }, 215 { "PROM", load_vbios_prom, false },
196 { "PCIROM", load_vbios_pci, true }, 216 { "PCIROM", load_vbios_pci, true },
@@ -2807,7 +2827,10 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2807 2827
2808 BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); 2828 BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
2809 2829
2810 nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); 2830 BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n",
2831 offset, gpio->tag, gpio->state_default);
2832 if (bios->execute)
2833 nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
2811 2834
2812 /* The NVIDIA binary driver doesn't appear to actually do 2835 /* The NVIDIA binary driver doesn't appear to actually do
2813 * any of this, my VBIOS does however. 2836 * any of this, my VBIOS does however.
@@ -5533,12 +5556,6 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
5533 entry->bus = (conn >> 16) & 0xf; 5556 entry->bus = (conn >> 16) & 0xf;
5534 entry->location = (conn >> 20) & 0x3; 5557 entry->location = (conn >> 20) & 0x3;
5535 entry->or = (conn >> 24) & 0xf; 5558 entry->or = (conn >> 24) & 0xf;
5536 /*
5537 * Normal entries consist of a single bit, but dual link has the
5538 * next most significant bit set too
5539 */
5540 entry->duallink_possible =
5541 ((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
5542 5559
5543 switch (entry->type) { 5560 switch (entry->type) {
5544 case OUTPUT_ANALOG: 5561 case OUTPUT_ANALOG:
@@ -5622,6 +5639,16 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
5622 break; 5639 break;
5623 } 5640 }
5624 5641
5642 if (dcb->version < 0x40) {
5643 /* Normal entries consist of a single bit, but dual link has
5644 * the next most significant bit set too
5645 */
5646 entry->duallink_possible =
5647 ((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
5648 } else {
5649 entry->duallink_possible = (entry->sorconf.link == 3);
5650 }
5651
5625 /* unsure what DCB version introduces this, 3.0? */ 5652 /* unsure what DCB version introduces this, 3.0? */
5626 if (conf & 0x100000) 5653 if (conf & 0x100000)
5627 entry->i2c_upper_default = true; 5654 entry->i2c_upper_default = true;
@@ -6205,6 +6232,30 @@ nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
6205 nouveau_i2c_fini(dev, entry); 6232 nouveau_i2c_fini(dev, entry);
6206} 6233}
6207 6234
6235static bool
6236nouveau_bios_posted(struct drm_device *dev)
6237{
6238 struct drm_nouveau_private *dev_priv = dev->dev_private;
6239 bool was_locked;
6240 unsigned htotal;
6241
6242 if (dev_priv->chipset >= NV_50) {
6243 if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
6244 NVReadVgaCrtc(dev, 0, 0x1a) == 0)
6245 return false;
6246 return true;
6247 }
6248
6249 was_locked = NVLockVgaCrtcs(dev, false);
6250 htotal = NVReadVgaCrtc(dev, 0, 0x06);
6251 htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
6252 htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
6253 htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
6254 htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
6255 NVLockVgaCrtcs(dev, was_locked);
6256 return (htotal != 0);
6257}
6258
6208int 6259int
6209nouveau_bios_init(struct drm_device *dev) 6260nouveau_bios_init(struct drm_device *dev)
6210{ 6261{
@@ -6239,11 +6290,9 @@ nouveau_bios_init(struct drm_device *dev)
6239 bios->execute = false; 6290 bios->execute = false;
6240 6291
6241 /* ... unless card isn't POSTed already */ 6292 /* ... unless card isn't POSTed already */
6242 if (dev_priv->card_type >= NV_10 && 6293 if (!nouveau_bios_posted(dev)) {
6243 NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
6244 NVReadVgaCrtc(dev, 0, 0x1a) == 0) {
6245 NV_INFO(dev, "Adaptor not initialised\n"); 6294 NV_INFO(dev, "Adaptor not initialised\n");
6246 if (dev_priv->card_type < NV_50) { 6295 if (dev_priv->card_type < NV_40) {
6247 NV_ERROR(dev, "Unable to POST this chipset\n"); 6296 NV_ERROR(dev, "Unable to POST this chipset\n");
6248 return -ENODEV; 6297 return -ENODEV;
6249 } 6298 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 266b0ff441af..149ed224c3cb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -432,24 +432,27 @@ nouveau_connector_set_property(struct drm_connector *connector,
432} 432}
433 433
434static struct drm_display_mode * 434static struct drm_display_mode *
435nouveau_connector_native_mode(struct nouveau_connector *connector) 435nouveau_connector_native_mode(struct drm_connector *connector)
436{ 436{
437 struct drm_device *dev = connector->base.dev; 437 struct drm_connector_helper_funcs *helper = connector->helper_private;
438 struct nouveau_connector *nv_connector = nouveau_connector(connector);
439 struct drm_device *dev = connector->dev;
438 struct drm_display_mode *mode, *largest = NULL; 440 struct drm_display_mode *mode, *largest = NULL;
439 int high_w = 0, high_h = 0, high_v = 0; 441 int high_w = 0, high_h = 0, high_v = 0;
440 442
441 /* Use preferred mode if there is one.. */ 443 list_for_each_entry(mode, &nv_connector->base.probed_modes, head) {
442 list_for_each_entry(mode, &connector->base.probed_modes, head) { 444 if (helper->mode_valid(connector, mode) != MODE_OK)
445 continue;
446
447 /* Use preferred mode if there is one.. */
443 if (mode->type & DRM_MODE_TYPE_PREFERRED) { 448 if (mode->type & DRM_MODE_TYPE_PREFERRED) {
444 NV_DEBUG_KMS(dev, "native mode from preferred\n"); 449 NV_DEBUG_KMS(dev, "native mode from preferred\n");
445 return drm_mode_duplicate(dev, mode); 450 return drm_mode_duplicate(dev, mode);
446 } 451 }
447 }
448 452
449 /* Otherwise, take the resolution with the largest width, then height, 453 /* Otherwise, take the resolution with the largest width, then
450 * then vertical refresh 454 * height, then vertical refresh
451 */ 455 */
452 list_for_each_entry(mode, &connector->base.probed_modes, head) {
453 if (mode->hdisplay < high_w) 456 if (mode->hdisplay < high_w)
454 continue; 457 continue;
455 458
@@ -553,7 +556,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
553 */ 556 */
554 if (!nv_connector->native_mode) 557 if (!nv_connector->native_mode)
555 nv_connector->native_mode = 558 nv_connector->native_mode =
556 nouveau_connector_native_mode(nv_connector); 559 nouveau_connector_native_mode(connector);
557 if (ret == 0 && nv_connector->native_mode) { 560 if (ret == 0 && nv_connector->native_mode) {
558 struct drm_display_mode *mode; 561 struct drm_display_mode *mode;
559 562
@@ -584,9 +587,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
584 587
585 switch (nv_encoder->dcb->type) { 588 switch (nv_encoder->dcb->type) {
586 case OUTPUT_LVDS: 589 case OUTPUT_LVDS:
587 BUG_ON(!nv_connector->native_mode); 590 if (nv_connector->native_mode &&
588 if (mode->hdisplay > nv_connector->native_mode->hdisplay || 591 (mode->hdisplay > nv_connector->native_mode->hdisplay ||
589 mode->vdisplay > nv_connector->native_mode->vdisplay) 592 mode->vdisplay > nv_connector->native_mode->vdisplay))
590 return MODE_PANEL; 593 return MODE_PANEL;
591 594
592 min_clock = 0; 595 min_clock = 0;
@@ -594,8 +597,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
594 break; 597 break;
595 case OUTPUT_TMDS: 598 case OUTPUT_TMDS:
596 if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || 599 if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
597 (dev_priv->card_type < NV_50 && 600 !nv_encoder->dcb->duallink_possible)
598 !nv_encoder->dcb->duallink_possible))
599 max_clock = 165000; 601 max_clock = 165000;
600 else 602 else
601 max_clock = 330000; 603 max_clock = 330000;
@@ -729,7 +731,7 @@ nouveau_connector_create_lvds(struct drm_device *dev,
729 if (ret == 0) 731 if (ret == 0)
730 goto out; 732 goto out;
731 nv_connector->detected_encoder = nv_encoder; 733 nv_connector->detected_encoder = nv_encoder;
732 nv_connector->native_mode = nouveau_connector_native_mode(nv_connector); 734 nv_connector->native_mode = nouveau_connector_native_mode(connector);
733 list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) 735 list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
734 drm_mode_remove(connector, mode); 736 drm_mode_remove(connector, mode);
735 737
diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h
index 49fa7b2d257e..cb1ce2a09162 100644
--- a/drivers/gpu/drm/nouveau/nouveau_crtc.h
+++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h
@@ -40,6 +40,8 @@ struct nouveau_crtc {
40 int sharpness; 40 int sharpness;
41 int last_dpms; 41 int last_dpms;
42 42
43 int cursor_saved_x, cursor_saved_y;
44
43 struct { 45 struct {
44 int cpp; 46 int cpp;
45 bool blanked; 47 bool blanked;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index c6079e36669d..273770432298 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -175,6 +175,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
175 nouveau_bo_unpin(nouveau_fb->nvbo); 175 nouveau_bo_unpin(nouveau_fb->nvbo);
176 } 176 }
177 177
178 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
179 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
180
181 nouveau_bo_unmap(nv_crtc->cursor.nvbo);
182 nouveau_bo_unpin(nv_crtc->cursor.nvbo);
183 }
184
178 NV_INFO(dev, "Evicting buffers...\n"); 185 NV_INFO(dev, "Evicting buffers...\n");
179 ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); 186 ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
180 187
@@ -314,12 +321,34 @@ nouveau_pci_resume(struct pci_dev *pdev)
314 nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); 321 nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
315 } 322 }
316 323
324 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
325 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
326 int ret;
327
328 ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
329 if (!ret)
330 ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
331 if (ret)
332 NV_ERROR(dev, "Could not pin/map cursor.\n");
333 }
334
317 if (dev_priv->card_type < NV_50) { 335 if (dev_priv->card_type < NV_50) {
318 nv04_display_restore(dev); 336 nv04_display_restore(dev);
319 NVLockVgaCrtcs(dev, false); 337 NVLockVgaCrtcs(dev, false);
320 } else 338 } else
321 nv50_display_init(dev); 339 nv50_display_init(dev);
322 340
341 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
342 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
343
344 nv_crtc->cursor.set_offset(nv_crtc,
345 nv_crtc->cursor.nvbo->bo.offset -
346 dev_priv->vm_vram_base);
347
348 nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
349 nv_crtc->cursor_saved_y);
350 }
351
323 /* Force CLUT to get re-loaded during modeset */ 352 /* Force CLUT to get re-loaded during modeset */
324 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 353 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
325 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 354 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 5b134438effe..c69719106489 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -851,12 +851,17 @@ extern int nouveau_dma_init(struct nouveau_channel *);
851extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); 851extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
852 852
853/* nouveau_acpi.c */ 853/* nouveau_acpi.c */
854#define ROM_BIOS_PAGE 4096
854#if defined(CONFIG_ACPI) 855#if defined(CONFIG_ACPI)
855void nouveau_register_dsm_handler(void); 856void nouveau_register_dsm_handler(void);
856void nouveau_unregister_dsm_handler(void); 857void nouveau_unregister_dsm_handler(void);
858int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
859bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
857#else 860#else
858static inline void nouveau_register_dsm_handler(void) {} 861static inline void nouveau_register_dsm_handler(void) {}
859static inline void nouveau_unregister_dsm_handler(void) {} 862static inline void nouveau_unregister_dsm_handler(void) {}
863static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
864static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
860#endif 865#endif
861 866
862/* nouveau_backlight.c */ 867/* nouveau_backlight.c */
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 775a7017af64..c1fd42b0dad1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -540,7 +540,8 @@ nouveau_mem_detect(struct drm_device *dev)
540 dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); 540 dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA);
541 dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; 541 dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
542 if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) 542 if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
543 dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; 543 dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
544 dev_priv->vram_sys_base <<= 12;
544 } 545 }
545 546
546 NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); 547 NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index e632339c323e..147e59c40151 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -376,12 +376,15 @@ out_err:
376static void nouveau_switcheroo_set_state(struct pci_dev *pdev, 376static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
377 enum vga_switcheroo_state state) 377 enum vga_switcheroo_state state)
378{ 378{
379 struct drm_device *dev = pci_get_drvdata(pdev);
379 pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; 380 pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
380 if (state == VGA_SWITCHEROO_ON) { 381 if (state == VGA_SWITCHEROO_ON) {
381 printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); 382 printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
382 nouveau_pci_resume(pdev); 383 nouveau_pci_resume(pdev);
384 drm_kms_helper_poll_enable(dev);
383 } else { 385 } else {
384 printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); 386 printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
387 drm_kms_helper_poll_disable(dev);
385 nouveau_pci_suspend(pdev, pmm); 388 nouveau_pci_suspend(pdev, pmm);
386 } 389 }
387} 390}
@@ -913,6 +916,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
913 case NOUVEAU_GETPARAM_VM_VRAM_BASE: 916 case NOUVEAU_GETPARAM_VM_VRAM_BASE:
914 getparam->value = dev_priv->vm_vram_base; 917 getparam->value = dev_priv->vm_vram_base;
915 break; 918 break;
919 case NOUVEAU_GETPARAM_PTIMER_TIME:
920 getparam->value = dev_priv->engine.timer.read(dev);
921 break;
916 case NOUVEAU_GETPARAM_GRAPH_UNITS: 922 case NOUVEAU_GETPARAM_GRAPH_UNITS:
917 /* NV40 and NV50 versions are quite different, but register 923 /* NV40 and NV50 versions are quite different, but register
918 * address is the same. User is supposed to know the card 924 * address is the same. User is supposed to know the card
diff --git a/drivers/gpu/drm/nouveau/nv04_cursor.c b/drivers/gpu/drm/nouveau/nv04_cursor.c
index 89a91b9d8b25..aaf3de3bc816 100644
--- a/drivers/gpu/drm/nouveau/nv04_cursor.c
+++ b/drivers/gpu/drm/nouveau/nv04_cursor.c
@@ -20,6 +20,7 @@ nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
20static void 20static void
21nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) 21nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
22{ 22{
23 nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
23 NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index, 24 NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index,
24 NV_PRAMDAC_CU_START_POS, 25 NV_PRAMDAC_CU_START_POS,
25 XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) | 26 XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c
index 753e723adb3a..03ad7ab14f09 100644
--- a/drivers/gpu/drm/nouveau/nv50_cursor.c
+++ b/drivers/gpu/drm/nouveau/nv50_cursor.c
@@ -107,6 +107,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
107{ 107{
108 struct drm_device *dev = nv_crtc->base.dev; 108 struct drm_device *dev = nv_crtc->base.dev;
109 109
110 nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
110 nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index), 111 nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index),
111 ((y & 0xFFFF) << 16) | (x & 0xFFFF)); 112 ((y & 0xFFFF) << 16) | (x & 0xFFFF));
112 /* Needed to make the cursor move. */ 113 /* Needed to make the cursor move. */
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
index b11eaf9c5c7c..812778db76ac 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -274,7 +274,6 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
274int 274int
275nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) 275nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
276{ 276{
277 struct drm_nouveau_private *dev_priv = dev->dev_private;
278 struct nouveau_encoder *nv_encoder = NULL; 277 struct nouveau_encoder *nv_encoder = NULL;
279 struct drm_encoder *encoder; 278 struct drm_encoder *encoder;
280 bool dum; 279 bool dum;
@@ -324,11 +323,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
324 int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1); 323 int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1);
325 uint32_t tmp; 324 uint32_t tmp;
326 325
327 if (dev_priv->chipset < 0x90 || 326 tmp = nv_rd32(dev, 0x61c700 + (or * 0x800));
328 dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
329 tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
330 else
331 tmp = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
332 327
333 switch ((tmp & 0x00000f00) >> 8) { 328 switch ((tmp & 0x00000f00) >> 8) {
334 case 8: 329 case 8:
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 3c91312dea9a..84b1f2729d43 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -33,6 +33,9 @@ $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
33$(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable 33$(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable
34 $(call if_changed,mkregtable) 34 $(call if_changed,mkregtable)
35 35
36$(obj)/evergreen_reg_safe.h: $(src)/reg_srcs/evergreen $(obj)/mkregtable
37 $(call if_changed,mkregtable)
38
36$(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h 39$(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h
37 40
38$(obj)/r200.o: $(obj)/r200_reg_safe.h 41$(obj)/r200.o: $(obj)/r200_reg_safe.h
@@ -47,6 +50,8 @@ $(obj)/rs600.o: $(obj)/rs600_reg_safe.h
47 50
48$(obj)/r600_cs.o: $(obj)/r600_reg_safe.h 51$(obj)/r600_cs.o: $(obj)/r600_reg_safe.h
49 52
53$(obj)/evergreen_cs.o: $(obj)/evergreen_reg_safe.h
54
50radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ 55radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
51 radeon_irq.o r300_cmdbuf.o r600_cp.o 56 radeon_irq.o r300_cmdbuf.o r600_cp.o
52# add KMS driver 57# add KMS driver
@@ -60,7 +65,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
60 rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ 65 rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
61 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ 66 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
62 r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ 67 r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
63 evergreen.o 68 evergreen.o evergreen_cs.o
64 69
65radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 70radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
66radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o 71radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 8c8e4d3cbaa3..0440c0939bdd 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -41,7 +41,12 @@ void evergreen_fini(struct radeon_device *rdev);
41 41
42void evergreen_pm_misc(struct radeon_device *rdev) 42void evergreen_pm_misc(struct radeon_device *rdev)
43{ 43{
44 int requested_index = rdev->pm.requested_power_state_index;
45 struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
46 struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
44 47
48 if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
49 radeon_atom_set_voltage(rdev, voltage->voltage);
45} 50}
46 51
47void evergreen_pm_prepare(struct radeon_device *rdev) 52void evergreen_pm_prepare(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
new file mode 100644
index 000000000000..64516b950891
--- /dev/null
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -0,0 +1,1356 @@
1/*
2 * Copyright 2010 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 "evergreend.h"
31#include "evergreen_reg_safe.h"
32
33static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
34 struct radeon_cs_reloc **cs_reloc);
35
36struct evergreen_cs_track {
37 u32 group_size;
38 u32 nbanks;
39 u32 npipes;
40 /* value we track */
41 u32 nsamples;
42 u32 cb_color_base_last[12];
43 struct radeon_bo *cb_color_bo[12];
44 u32 cb_color_bo_offset[12];
45 struct radeon_bo *cb_color_fmask_bo[8];
46 struct radeon_bo *cb_color_cmask_bo[8];
47 u32 cb_color_info[12];
48 u32 cb_color_view[12];
49 u32 cb_color_pitch_idx[12];
50 u32 cb_color_slice_idx[12];
51 u32 cb_color_dim_idx[12];
52 u32 cb_color_dim[12];
53 u32 cb_color_pitch[12];
54 u32 cb_color_slice[12];
55 u32 cb_color_cmask_slice[8];
56 u32 cb_color_fmask_slice[8];
57 u32 cb_target_mask;
58 u32 cb_shader_mask;
59 u32 vgt_strmout_config;
60 u32 vgt_strmout_buffer_config;
61 u32 db_depth_control;
62 u32 db_depth_view;
63 u32 db_depth_size;
64 u32 db_depth_size_idx;
65 u32 db_z_info;
66 u32 db_z_idx;
67 u32 db_z_read_offset;
68 u32 db_z_write_offset;
69 struct radeon_bo *db_z_read_bo;
70 struct radeon_bo *db_z_write_bo;
71 u32 db_s_info;
72 u32 db_s_idx;
73 u32 db_s_read_offset;
74 u32 db_s_write_offset;
75 struct radeon_bo *db_s_read_bo;
76 struct radeon_bo *db_s_write_bo;
77};
78
79static void evergreen_cs_track_init(struct evergreen_cs_track *track)
80{
81 int i;
82
83 for (i = 0; i < 8; i++) {
84 track->cb_color_fmask_bo[i] = NULL;
85 track->cb_color_cmask_bo[i] = NULL;
86 track->cb_color_cmask_slice[i] = 0;
87 track->cb_color_fmask_slice[i] = 0;
88 }
89
90 for (i = 0; i < 12; i++) {
91 track->cb_color_base_last[i] = 0;
92 track->cb_color_bo[i] = NULL;
93 track->cb_color_bo_offset[i] = 0xFFFFFFFF;
94 track->cb_color_info[i] = 0;
95 track->cb_color_view[i] = 0;
96 track->cb_color_pitch_idx[i] = 0;
97 track->cb_color_slice_idx[i] = 0;
98 track->cb_color_dim[i] = 0;
99 track->cb_color_pitch[i] = 0;
100 track->cb_color_slice[i] = 0;
101 track->cb_color_dim[i] = 0;
102 }
103 track->cb_target_mask = 0xFFFFFFFF;
104 track->cb_shader_mask = 0xFFFFFFFF;
105
106 track->db_depth_view = 0xFFFFC000;
107 track->db_depth_size = 0xFFFFFFFF;
108 track->db_depth_size_idx = 0;
109 track->db_depth_control = 0xFFFFFFFF;
110 track->db_z_info = 0xFFFFFFFF;
111 track->db_z_idx = 0xFFFFFFFF;
112 track->db_z_read_offset = 0xFFFFFFFF;
113 track->db_z_write_offset = 0xFFFFFFFF;
114 track->db_z_read_bo = NULL;
115 track->db_z_write_bo = NULL;
116 track->db_s_info = 0xFFFFFFFF;
117 track->db_s_idx = 0xFFFFFFFF;
118 track->db_s_read_offset = 0xFFFFFFFF;
119 track->db_s_write_offset = 0xFFFFFFFF;
120 track->db_s_read_bo = NULL;
121 track->db_s_write_bo = NULL;
122}
123
124static inline int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
125{
126 /* XXX fill in */
127 return 0;
128}
129
130static int evergreen_cs_track_check(struct radeon_cs_parser *p)
131{
132 struct evergreen_cs_track *track = p->track;
133
134 /* we don't support stream out buffer yet */
135 if (track->vgt_strmout_config || track->vgt_strmout_buffer_config) {
136 dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n");
137 return -EINVAL;
138 }
139
140 /* XXX fill in */
141 return 0;
142}
143
144/**
145 * evergreen_cs_packet_parse() - parse cp packet and point ib index to next packet
146 * @parser: parser structure holding parsing context.
147 * @pkt: where to store packet informations
148 *
149 * Assume that chunk_ib_index is properly set. Will return -EINVAL
150 * if packet is bigger than remaining ib size. or if packets is unknown.
151 **/
152int evergreen_cs_packet_parse(struct radeon_cs_parser *p,
153 struct radeon_cs_packet *pkt,
154 unsigned idx)
155{
156 struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
157 uint32_t header;
158
159 if (idx >= ib_chunk->length_dw) {
160 DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
161 idx, ib_chunk->length_dw);
162 return -EINVAL;
163 }
164 header = radeon_get_ib_value(p, idx);
165 pkt->idx = idx;
166 pkt->type = CP_PACKET_GET_TYPE(header);
167 pkt->count = CP_PACKET_GET_COUNT(header);
168 pkt->one_reg_wr = 0;
169 switch (pkt->type) {
170 case PACKET_TYPE0:
171 pkt->reg = CP_PACKET0_GET_REG(header);
172 break;
173 case PACKET_TYPE3:
174 pkt->opcode = CP_PACKET3_GET_OPCODE(header);
175 break;
176 case PACKET_TYPE2:
177 pkt->count = -1;
178 break;
179 default:
180 DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
181 return -EINVAL;
182 }
183 if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) {
184 DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
185 pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw);
186 return -EINVAL;
187 }
188 return 0;
189}
190
191/**
192 * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3
193 * @parser: parser structure holding parsing context.
194 * @data: pointer to relocation data
195 * @offset_start: starting offset
196 * @offset_mask: offset mask (to align start offset on)
197 * @reloc: reloc informations
198 *
199 * Check next packet is relocation packet3, do bo validation and compute
200 * GPU offset using the provided start.
201 **/
202static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
203 struct radeon_cs_reloc **cs_reloc)
204{
205 struct radeon_cs_chunk *relocs_chunk;
206 struct radeon_cs_packet p3reloc;
207 unsigned idx;
208 int r;
209
210 if (p->chunk_relocs_idx == -1) {
211 DRM_ERROR("No relocation chunk !\n");
212 return -EINVAL;
213 }
214 *cs_reloc = NULL;
215 relocs_chunk = &p->chunks[p->chunk_relocs_idx];
216 r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
217 if (r) {
218 return r;
219 }
220 p->idx += p3reloc.count + 2;
221 if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
222 DRM_ERROR("No packet3 for relocation for packet at %d.\n",
223 p3reloc.idx);
224 return -EINVAL;
225 }
226 idx = radeon_get_ib_value(p, p3reloc.idx + 1);
227 if (idx >= relocs_chunk->length_dw) {
228 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
229 idx, relocs_chunk->length_dw);
230 return -EINVAL;
231 }
232 /* FIXME: we assume reloc size is 4 dwords */
233 *cs_reloc = p->relocs_ptr[(idx / 4)];
234 return 0;
235}
236
237/**
238 * evergreen_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc
239 * @parser: parser structure holding parsing context.
240 *
241 * Check next packet is relocation packet3, do bo validation and compute
242 * GPU offset using the provided start.
243 **/
244static inline int evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p)
245{
246 struct radeon_cs_packet p3reloc;
247 int r;
248
249 r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
250 if (r) {
251 return 0;
252 }
253 if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
254 return 0;
255 }
256 return 1;
257}
258
259/**
260 * evergreen_cs_packet_next_vline() - parse userspace VLINE packet
261 * @parser: parser structure holding parsing context.
262 *
263 * Userspace sends a special sequence for VLINE waits.
264 * PACKET0 - VLINE_START_END + value
265 * PACKET3 - WAIT_REG_MEM poll vline status reg
266 * RELOC (P3) - crtc_id in reloc.
267 *
268 * This function parses this and relocates the VLINE START END
269 * and WAIT_REG_MEM packets to the correct crtc.
270 * It also detects a switched off crtc and nulls out the
271 * wait in that case.
272 */
273static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p)
274{
275 struct drm_mode_object *obj;
276 struct drm_crtc *crtc;
277 struct radeon_crtc *radeon_crtc;
278 struct radeon_cs_packet p3reloc, wait_reg_mem;
279 int crtc_id;
280 int r;
281 uint32_t header, h_idx, reg, wait_reg_mem_info;
282 volatile uint32_t *ib;
283
284 ib = p->ib->ptr;
285
286 /* parse the WAIT_REG_MEM */
287 r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx);
288 if (r)
289 return r;
290
291 /* check its a WAIT_REG_MEM */
292 if (wait_reg_mem.type != PACKET_TYPE3 ||
293 wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) {
294 DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n");
295 r = -EINVAL;
296 return r;
297 }
298
299 wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1);
300 /* bit 4 is reg (0) or mem (1) */
301 if (wait_reg_mem_info & 0x10) {
302 DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n");
303 r = -EINVAL;
304 return r;
305 }
306 /* waiting for value to be equal */
307 if ((wait_reg_mem_info & 0x7) != 0x3) {
308 DRM_ERROR("vline WAIT_REG_MEM function not equal\n");
309 r = -EINVAL;
310 return r;
311 }
312 if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != EVERGREEN_VLINE_STATUS) {
313 DRM_ERROR("vline WAIT_REG_MEM bad reg\n");
314 r = -EINVAL;
315 return r;
316 }
317
318 if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != EVERGREEN_VLINE_STAT) {
319 DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n");
320 r = -EINVAL;
321 return r;
322 }
323
324 /* jump over the NOP */
325 r = evergreen_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2);
326 if (r)
327 return r;
328
329 h_idx = p->idx - 2;
330 p->idx += wait_reg_mem.count + 2;
331 p->idx += p3reloc.count + 2;
332
333 header = radeon_get_ib_value(p, h_idx);
334 crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
335 reg = CP_PACKET0_GET_REG(header);
336 mutex_lock(&p->rdev->ddev->mode_config.mutex);
337 obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
338 if (!obj) {
339 DRM_ERROR("cannot find crtc %d\n", crtc_id);
340 r = -EINVAL;
341 goto out;
342 }
343 crtc = obj_to_crtc(obj);
344 radeon_crtc = to_radeon_crtc(crtc);
345 crtc_id = radeon_crtc->crtc_id;
346
347 if (!crtc->enabled) {
348 /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */
349 ib[h_idx + 2] = PACKET2(0);
350 ib[h_idx + 3] = PACKET2(0);
351 ib[h_idx + 4] = PACKET2(0);
352 ib[h_idx + 5] = PACKET2(0);
353 ib[h_idx + 6] = PACKET2(0);
354 ib[h_idx + 7] = PACKET2(0);
355 ib[h_idx + 8] = PACKET2(0);
356 } else {
357 switch (reg) {
358 case EVERGREEN_VLINE_START_END:
359 header &= ~R600_CP_PACKET0_REG_MASK;
360 header |= (EVERGREEN_VLINE_START_END + radeon_crtc->crtc_offset) >> 2;
361 ib[h_idx] = header;
362 ib[h_idx + 4] = (EVERGREEN_VLINE_STATUS + radeon_crtc->crtc_offset) >> 2;
363 break;
364 default:
365 DRM_ERROR("unknown crtc reloc\n");
366 r = -EINVAL;
367 goto out;
368 }
369 }
370out:
371 mutex_unlock(&p->rdev->ddev->mode_config.mutex);
372 return r;
373}
374
375static int evergreen_packet0_check(struct radeon_cs_parser *p,
376 struct radeon_cs_packet *pkt,
377 unsigned idx, unsigned reg)
378{
379 int r;
380
381 switch (reg) {
382 case EVERGREEN_VLINE_START_END:
383 r = evergreen_cs_packet_parse_vline(p);
384 if (r) {
385 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
386 idx, reg);
387 return r;
388 }
389 break;
390 default:
391 printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
392 reg, idx);
393 return -EINVAL;
394 }
395 return 0;
396}
397
398static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p,
399 struct radeon_cs_packet *pkt)
400{
401 unsigned reg, i;
402 unsigned idx;
403 int r;
404
405 idx = pkt->idx + 1;
406 reg = pkt->reg;
407 for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
408 r = evergreen_packet0_check(p, pkt, idx, reg);
409 if (r) {
410 return r;
411 }
412 }
413 return 0;
414}
415
416/**
417 * evergreen_cs_check_reg() - check if register is authorized or not
418 * @parser: parser structure holding parsing context
419 * @reg: register we are testing
420 * @idx: index into the cs buffer
421 *
422 * This function will test against evergreen_reg_safe_bm and return 0
423 * if register is safe. If register is not flag as safe this function
424 * will test it against a list of register needind special handling.
425 */
426static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
427{
428 struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track;
429 struct radeon_cs_reloc *reloc;
430 u32 last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
431 u32 m, i, tmp, *ib;
432 int r;
433
434 i = (reg >> 7);
435 if (i > last_reg) {
436 dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
437 return -EINVAL;
438 }
439 m = 1 << ((reg >> 2) & 31);
440 if (!(evergreen_reg_safe_bm[i] & m))
441 return 0;
442 ib = p->ib->ptr;
443 switch (reg) {
444 /* force following reg to 0 in an attemp to disable out buffer
445 * which will need us to better understand how it works to perform
446 * security check on it (Jerome)
447 */
448 case SQ_ESGS_RING_SIZE:
449 case SQ_GSVS_RING_SIZE:
450 case SQ_ESTMP_RING_SIZE:
451 case SQ_GSTMP_RING_SIZE:
452 case SQ_HSTMP_RING_SIZE:
453 case SQ_LSTMP_RING_SIZE:
454 case SQ_PSTMP_RING_SIZE:
455 case SQ_VSTMP_RING_SIZE:
456 case SQ_ESGS_RING_ITEMSIZE:
457 case SQ_ESTMP_RING_ITEMSIZE:
458 case SQ_GSTMP_RING_ITEMSIZE:
459 case SQ_GSVS_RING_ITEMSIZE:
460 case SQ_GS_VERT_ITEMSIZE:
461 case SQ_GS_VERT_ITEMSIZE_1:
462 case SQ_GS_VERT_ITEMSIZE_2:
463 case SQ_GS_VERT_ITEMSIZE_3:
464 case SQ_GSVS_RING_OFFSET_1:
465 case SQ_GSVS_RING_OFFSET_2:
466 case SQ_GSVS_RING_OFFSET_3:
467 case SQ_HSTMP_RING_ITEMSIZE:
468 case SQ_LSTMP_RING_ITEMSIZE:
469 case SQ_PSTMP_RING_ITEMSIZE:
470 case SQ_VSTMP_RING_ITEMSIZE:
471 case VGT_TF_RING_SIZE:
472 /* get value to populate the IB don't remove */
473 tmp =radeon_get_ib_value(p, idx);
474 ib[idx] = 0;
475 break;
476 case DB_DEPTH_CONTROL:
477 track->db_depth_control = radeon_get_ib_value(p, idx);
478 break;
479 case DB_Z_INFO:
480 r = evergreen_cs_packet_next_reloc(p, &reloc);
481 if (r) {
482 dev_warn(p->dev, "bad SET_CONTEXT_REG "
483 "0x%04X\n", reg);
484 return -EINVAL;
485 }
486 track->db_z_info = radeon_get_ib_value(p, idx);
487 ib[idx] &= ~Z_ARRAY_MODE(0xf);
488 track->db_z_info &= ~Z_ARRAY_MODE(0xf);
489 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
490 ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
491 track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
492 } else {
493 ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
494 track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
495 }
496 break;
497 case DB_STENCIL_INFO:
498 track->db_s_info = radeon_get_ib_value(p, idx);
499 break;
500 case DB_DEPTH_VIEW:
501 track->db_depth_view = radeon_get_ib_value(p, idx);
502 break;
503 case DB_DEPTH_SIZE:
504 track->db_depth_size = radeon_get_ib_value(p, idx);
505 track->db_depth_size_idx = idx;
506 break;
507 case DB_Z_READ_BASE:
508 r = evergreen_cs_packet_next_reloc(p, &reloc);
509 if (r) {
510 dev_warn(p->dev, "bad SET_CONTEXT_REG "
511 "0x%04X\n", reg);
512 return -EINVAL;
513 }
514 track->db_z_read_offset = radeon_get_ib_value(p, idx);
515 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
516 track->db_z_read_bo = reloc->robj;
517 break;
518 case DB_Z_WRITE_BASE:
519 r = evergreen_cs_packet_next_reloc(p, &reloc);
520 if (r) {
521 dev_warn(p->dev, "bad SET_CONTEXT_REG "
522 "0x%04X\n", reg);
523 return -EINVAL;
524 }
525 track->db_z_write_offset = radeon_get_ib_value(p, idx);
526 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
527 track->db_z_write_bo = reloc->robj;
528 break;
529 case DB_STENCIL_READ_BASE:
530 r = evergreen_cs_packet_next_reloc(p, &reloc);
531 if (r) {
532 dev_warn(p->dev, "bad SET_CONTEXT_REG "
533 "0x%04X\n", reg);
534 return -EINVAL;
535 }
536 track->db_s_read_offset = radeon_get_ib_value(p, idx);
537 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
538 track->db_s_read_bo = reloc->robj;
539 break;
540 case DB_STENCIL_WRITE_BASE:
541 r = evergreen_cs_packet_next_reloc(p, &reloc);
542 if (r) {
543 dev_warn(p->dev, "bad SET_CONTEXT_REG "
544 "0x%04X\n", reg);
545 return -EINVAL;
546 }
547 track->db_s_write_offset = radeon_get_ib_value(p, idx);
548 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
549 track->db_s_write_bo = reloc->robj;
550 break;
551 case VGT_STRMOUT_CONFIG:
552 track->vgt_strmout_config = radeon_get_ib_value(p, idx);
553 break;
554 case VGT_STRMOUT_BUFFER_CONFIG:
555 track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx);
556 break;
557 case CB_TARGET_MASK:
558 track->cb_target_mask = radeon_get_ib_value(p, idx);
559 break;
560 case CB_SHADER_MASK:
561 track->cb_shader_mask = radeon_get_ib_value(p, idx);
562 break;
563 case PA_SC_AA_CONFIG:
564 tmp = radeon_get_ib_value(p, idx) & MSAA_NUM_SAMPLES_MASK;
565 track->nsamples = 1 << tmp;
566 break;
567 case CB_COLOR0_VIEW:
568 case CB_COLOR1_VIEW:
569 case CB_COLOR2_VIEW:
570 case CB_COLOR3_VIEW:
571 case CB_COLOR4_VIEW:
572 case CB_COLOR5_VIEW:
573 case CB_COLOR6_VIEW:
574 case CB_COLOR7_VIEW:
575 tmp = (reg - CB_COLOR0_VIEW) / 0x3c;
576 track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
577 break;
578 case CB_COLOR8_VIEW:
579 case CB_COLOR9_VIEW:
580 case CB_COLOR10_VIEW:
581 case CB_COLOR11_VIEW:
582 tmp = ((reg - CB_COLOR8_VIEW) / 0x1c) + 8;
583 track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
584 break;
585 case CB_COLOR0_INFO:
586 case CB_COLOR1_INFO:
587 case CB_COLOR2_INFO:
588 case CB_COLOR3_INFO:
589 case CB_COLOR4_INFO:
590 case CB_COLOR5_INFO:
591 case CB_COLOR6_INFO:
592 case CB_COLOR7_INFO:
593 r = evergreen_cs_packet_next_reloc(p, &reloc);
594 if (r) {
595 dev_warn(p->dev, "bad SET_CONTEXT_REG "
596 "0x%04X\n", reg);
597 return -EINVAL;
598 }
599 tmp = (reg - CB_COLOR0_INFO) / 0x3c;
600 track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
601 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
602 ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
603 track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
604 } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
605 ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
606 track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
607 }
608 break;
609 case CB_COLOR8_INFO:
610 case CB_COLOR9_INFO:
611 case CB_COLOR10_INFO:
612 case CB_COLOR11_INFO:
613 r = evergreen_cs_packet_next_reloc(p, &reloc);
614 if (r) {
615 dev_warn(p->dev, "bad SET_CONTEXT_REG "
616 "0x%04X\n", reg);
617 return -EINVAL;
618 }
619 tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8;
620 track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
621 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
622 ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
623 track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
624 } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
625 ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
626 track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
627 }
628 break;
629 case CB_COLOR0_PITCH:
630 case CB_COLOR1_PITCH:
631 case CB_COLOR2_PITCH:
632 case CB_COLOR3_PITCH:
633 case CB_COLOR4_PITCH:
634 case CB_COLOR5_PITCH:
635 case CB_COLOR6_PITCH:
636 case CB_COLOR7_PITCH:
637 tmp = (reg - CB_COLOR0_PITCH) / 0x3c;
638 track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx);
639 track->cb_color_pitch_idx[tmp] = idx;
640 break;
641 case CB_COLOR8_PITCH:
642 case CB_COLOR9_PITCH:
643 case CB_COLOR10_PITCH:
644 case CB_COLOR11_PITCH:
645 tmp = ((reg - CB_COLOR8_PITCH) / 0x1c) + 8;
646 track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx);
647 track->cb_color_pitch_idx[tmp] = idx;
648 break;
649 case CB_COLOR0_SLICE:
650 case CB_COLOR1_SLICE:
651 case CB_COLOR2_SLICE:
652 case CB_COLOR3_SLICE:
653 case CB_COLOR4_SLICE:
654 case CB_COLOR5_SLICE:
655 case CB_COLOR6_SLICE:
656 case CB_COLOR7_SLICE:
657 tmp = (reg - CB_COLOR0_SLICE) / 0x3c;
658 track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
659 track->cb_color_slice_idx[tmp] = idx;
660 break;
661 case CB_COLOR8_SLICE:
662 case CB_COLOR9_SLICE:
663 case CB_COLOR10_SLICE:
664 case CB_COLOR11_SLICE:
665 tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8;
666 track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
667 track->cb_color_slice_idx[tmp] = idx;
668 break;
669 case CB_COLOR0_ATTRIB:
670 case CB_COLOR1_ATTRIB:
671 case CB_COLOR2_ATTRIB:
672 case CB_COLOR3_ATTRIB:
673 case CB_COLOR4_ATTRIB:
674 case CB_COLOR5_ATTRIB:
675 case CB_COLOR6_ATTRIB:
676 case CB_COLOR7_ATTRIB:
677 case CB_COLOR8_ATTRIB:
678 case CB_COLOR9_ATTRIB:
679 case CB_COLOR10_ATTRIB:
680 case CB_COLOR11_ATTRIB:
681 break;
682 case CB_COLOR0_DIM:
683 case CB_COLOR1_DIM:
684 case CB_COLOR2_DIM:
685 case CB_COLOR3_DIM:
686 case CB_COLOR4_DIM:
687 case CB_COLOR5_DIM:
688 case CB_COLOR6_DIM:
689 case CB_COLOR7_DIM:
690 tmp = (reg - CB_COLOR0_DIM) / 0x3c;
691 track->cb_color_dim[tmp] = radeon_get_ib_value(p, idx);
692 track->cb_color_dim_idx[tmp] = idx;
693 break;
694 case CB_COLOR8_DIM:
695 case CB_COLOR9_DIM:
696 case CB_COLOR10_DIM:
697 case CB_COLOR11_DIM:
698 tmp = ((reg - CB_COLOR8_DIM) / 0x1c) + 8;
699 track->cb_color_dim[tmp] = radeon_get_ib_value(p, idx);
700 track->cb_color_dim_idx[tmp] = idx;
701 break;
702 case CB_COLOR0_FMASK:
703 case CB_COLOR1_FMASK:
704 case CB_COLOR2_FMASK:
705 case CB_COLOR3_FMASK:
706 case CB_COLOR4_FMASK:
707 case CB_COLOR5_FMASK:
708 case CB_COLOR6_FMASK:
709 case CB_COLOR7_FMASK:
710 tmp = (reg - CB_COLOR0_FMASK) / 0x3c;
711 r = evergreen_cs_packet_next_reloc(p, &reloc);
712 if (r) {
713 dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
714 return -EINVAL;
715 }
716 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
717 track->cb_color_fmask_bo[tmp] = reloc->robj;
718 break;
719 case CB_COLOR0_CMASK:
720 case CB_COLOR1_CMASK:
721 case CB_COLOR2_CMASK:
722 case CB_COLOR3_CMASK:
723 case CB_COLOR4_CMASK:
724 case CB_COLOR5_CMASK:
725 case CB_COLOR6_CMASK:
726 case CB_COLOR7_CMASK:
727 tmp = (reg - CB_COLOR0_CMASK) / 0x3c;
728 r = evergreen_cs_packet_next_reloc(p, &reloc);
729 if (r) {
730 dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
731 return -EINVAL;
732 }
733 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
734 track->cb_color_cmask_bo[tmp] = reloc->robj;
735 break;
736 case CB_COLOR0_FMASK_SLICE:
737 case CB_COLOR1_FMASK_SLICE:
738 case CB_COLOR2_FMASK_SLICE:
739 case CB_COLOR3_FMASK_SLICE:
740 case CB_COLOR4_FMASK_SLICE:
741 case CB_COLOR5_FMASK_SLICE:
742 case CB_COLOR6_FMASK_SLICE:
743 case CB_COLOR7_FMASK_SLICE:
744 tmp = (reg - CB_COLOR0_FMASK_SLICE) / 0x3c;
745 track->cb_color_fmask_slice[tmp] = radeon_get_ib_value(p, idx);
746 break;
747 case CB_COLOR0_CMASK_SLICE:
748 case CB_COLOR1_CMASK_SLICE:
749 case CB_COLOR2_CMASK_SLICE:
750 case CB_COLOR3_CMASK_SLICE:
751 case CB_COLOR4_CMASK_SLICE:
752 case CB_COLOR5_CMASK_SLICE:
753 case CB_COLOR6_CMASK_SLICE:
754 case CB_COLOR7_CMASK_SLICE:
755 tmp = (reg - CB_COLOR0_CMASK_SLICE) / 0x3c;
756 track->cb_color_cmask_slice[tmp] = radeon_get_ib_value(p, idx);
757 break;
758 case CB_COLOR0_BASE:
759 case CB_COLOR1_BASE:
760 case CB_COLOR2_BASE:
761 case CB_COLOR3_BASE:
762 case CB_COLOR4_BASE:
763 case CB_COLOR5_BASE:
764 case CB_COLOR6_BASE:
765 case CB_COLOR7_BASE:
766 r = evergreen_cs_packet_next_reloc(p, &reloc);
767 if (r) {
768 dev_warn(p->dev, "bad SET_CONTEXT_REG "
769 "0x%04X\n", reg);
770 return -EINVAL;
771 }
772 tmp = (reg - CB_COLOR0_BASE) / 0x3c;
773 track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
774 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
775 track->cb_color_base_last[tmp] = ib[idx];
776 track->cb_color_bo[tmp] = reloc->robj;
777 break;
778 case CB_COLOR8_BASE:
779 case CB_COLOR9_BASE:
780 case CB_COLOR10_BASE:
781 case CB_COLOR11_BASE:
782 r = evergreen_cs_packet_next_reloc(p, &reloc);
783 if (r) {
784 dev_warn(p->dev, "bad SET_CONTEXT_REG "
785 "0x%04X\n", reg);
786 return -EINVAL;
787 }
788 tmp = ((reg - CB_COLOR8_BASE) / 0x1c) + 8;
789 track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
790 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
791 track->cb_color_base_last[tmp] = ib[idx];
792 track->cb_color_bo[tmp] = reloc->robj;
793 break;
794 case CB_IMMED0_BASE:
795 case CB_IMMED1_BASE:
796 case CB_IMMED2_BASE:
797 case CB_IMMED3_BASE:
798 case CB_IMMED4_BASE:
799 case CB_IMMED5_BASE:
800 case CB_IMMED6_BASE:
801 case CB_IMMED7_BASE:
802 case CB_IMMED8_BASE:
803 case CB_IMMED9_BASE:
804 case CB_IMMED10_BASE:
805 case CB_IMMED11_BASE:
806 case DB_HTILE_DATA_BASE:
807 case SQ_PGM_START_FS:
808 case SQ_PGM_START_ES:
809 case SQ_PGM_START_VS:
810 case SQ_PGM_START_GS:
811 case SQ_PGM_START_PS:
812 case SQ_PGM_START_HS:
813 case SQ_PGM_START_LS:
814 case GDS_ADDR_BASE:
815 case SQ_CONST_MEM_BASE:
816 case SQ_ALU_CONST_CACHE_GS_0:
817 case SQ_ALU_CONST_CACHE_GS_1:
818 case SQ_ALU_CONST_CACHE_GS_2:
819 case SQ_ALU_CONST_CACHE_GS_3:
820 case SQ_ALU_CONST_CACHE_GS_4:
821 case SQ_ALU_CONST_CACHE_GS_5:
822 case SQ_ALU_CONST_CACHE_GS_6:
823 case SQ_ALU_CONST_CACHE_GS_7:
824 case SQ_ALU_CONST_CACHE_GS_8:
825 case SQ_ALU_CONST_CACHE_GS_9:
826 case SQ_ALU_CONST_CACHE_GS_10:
827 case SQ_ALU_CONST_CACHE_GS_11:
828 case SQ_ALU_CONST_CACHE_GS_12:
829 case SQ_ALU_CONST_CACHE_GS_13:
830 case SQ_ALU_CONST_CACHE_GS_14:
831 case SQ_ALU_CONST_CACHE_GS_15:
832 case SQ_ALU_CONST_CACHE_PS_0:
833 case SQ_ALU_CONST_CACHE_PS_1:
834 case SQ_ALU_CONST_CACHE_PS_2:
835 case SQ_ALU_CONST_CACHE_PS_3:
836 case SQ_ALU_CONST_CACHE_PS_4:
837 case SQ_ALU_CONST_CACHE_PS_5:
838 case SQ_ALU_CONST_CACHE_PS_6:
839 case SQ_ALU_CONST_CACHE_PS_7:
840 case SQ_ALU_CONST_CACHE_PS_8:
841 case SQ_ALU_CONST_CACHE_PS_9:
842 case SQ_ALU_CONST_CACHE_PS_10:
843 case SQ_ALU_CONST_CACHE_PS_11:
844 case SQ_ALU_CONST_CACHE_PS_12:
845 case SQ_ALU_CONST_CACHE_PS_13:
846 case SQ_ALU_CONST_CACHE_PS_14:
847 case SQ_ALU_CONST_CACHE_PS_15:
848 case SQ_ALU_CONST_CACHE_VS_0:
849 case SQ_ALU_CONST_CACHE_VS_1:
850 case SQ_ALU_CONST_CACHE_VS_2:
851 case SQ_ALU_CONST_CACHE_VS_3:
852 case SQ_ALU_CONST_CACHE_VS_4:
853 case SQ_ALU_CONST_CACHE_VS_5:
854 case SQ_ALU_CONST_CACHE_VS_6:
855 case SQ_ALU_CONST_CACHE_VS_7:
856 case SQ_ALU_CONST_CACHE_VS_8:
857 case SQ_ALU_CONST_CACHE_VS_9:
858 case SQ_ALU_CONST_CACHE_VS_10:
859 case SQ_ALU_CONST_CACHE_VS_11:
860 case SQ_ALU_CONST_CACHE_VS_12:
861 case SQ_ALU_CONST_CACHE_VS_13:
862 case SQ_ALU_CONST_CACHE_VS_14:
863 case SQ_ALU_CONST_CACHE_VS_15:
864 case SQ_ALU_CONST_CACHE_HS_0:
865 case SQ_ALU_CONST_CACHE_HS_1:
866 case SQ_ALU_CONST_CACHE_HS_2:
867 case SQ_ALU_CONST_CACHE_HS_3:
868 case SQ_ALU_CONST_CACHE_HS_4:
869 case SQ_ALU_CONST_CACHE_HS_5:
870 case SQ_ALU_CONST_CACHE_HS_6:
871 case SQ_ALU_CONST_CACHE_HS_7:
872 case SQ_ALU_CONST_CACHE_HS_8:
873 case SQ_ALU_CONST_CACHE_HS_9:
874 case SQ_ALU_CONST_CACHE_HS_10:
875 case SQ_ALU_CONST_CACHE_HS_11:
876 case SQ_ALU_CONST_CACHE_HS_12:
877 case SQ_ALU_CONST_CACHE_HS_13:
878 case SQ_ALU_CONST_CACHE_HS_14:
879 case SQ_ALU_CONST_CACHE_HS_15:
880 case SQ_ALU_CONST_CACHE_LS_0:
881 case SQ_ALU_CONST_CACHE_LS_1:
882 case SQ_ALU_CONST_CACHE_LS_2:
883 case SQ_ALU_CONST_CACHE_LS_3:
884 case SQ_ALU_CONST_CACHE_LS_4:
885 case SQ_ALU_CONST_CACHE_LS_5:
886 case SQ_ALU_CONST_CACHE_LS_6:
887 case SQ_ALU_CONST_CACHE_LS_7:
888 case SQ_ALU_CONST_CACHE_LS_8:
889 case SQ_ALU_CONST_CACHE_LS_9:
890 case SQ_ALU_CONST_CACHE_LS_10:
891 case SQ_ALU_CONST_CACHE_LS_11:
892 case SQ_ALU_CONST_CACHE_LS_12:
893 case SQ_ALU_CONST_CACHE_LS_13:
894 case SQ_ALU_CONST_CACHE_LS_14:
895 case SQ_ALU_CONST_CACHE_LS_15:
896 r = evergreen_cs_packet_next_reloc(p, &reloc);
897 if (r) {
898 dev_warn(p->dev, "bad SET_CONTEXT_REG "
899 "0x%04X\n", reg);
900 return -EINVAL;
901 }
902 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
903 break;
904 default:
905 dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
906 return -EINVAL;
907 }
908 return 0;
909}
910
911/**
912 * evergreen_check_texture_resource() - check if register is authorized or not
913 * @p: parser structure holding parsing context
914 * @idx: index into the cs buffer
915 * @texture: texture's bo structure
916 * @mipmap: mipmap's bo structure
917 *
918 * This function will check that the resource has valid field and that
919 * the texture and mipmap bo object are big enough to cover this resource.
920 */
921static inline int evergreen_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
922 struct radeon_bo *texture,
923 struct radeon_bo *mipmap)
924{
925 /* XXX fill in */
926 return 0;
927}
928
929static int evergreen_packet3_check(struct radeon_cs_parser *p,
930 struct radeon_cs_packet *pkt)
931{
932 struct radeon_cs_reloc *reloc;
933 struct evergreen_cs_track *track;
934 volatile u32 *ib;
935 unsigned idx;
936 unsigned i;
937 unsigned start_reg, end_reg, reg;
938 int r;
939 u32 idx_value;
940
941 track = (struct evergreen_cs_track *)p->track;
942 ib = p->ib->ptr;
943 idx = pkt->idx + 1;
944 idx_value = radeon_get_ib_value(p, idx);
945
946 switch (pkt->opcode) {
947 case PACKET3_CONTEXT_CONTROL:
948 if (pkt->count != 1) {
949 DRM_ERROR("bad CONTEXT_CONTROL\n");
950 return -EINVAL;
951 }
952 break;
953 case PACKET3_INDEX_TYPE:
954 case PACKET3_NUM_INSTANCES:
955 case PACKET3_CLEAR_STATE:
956 if (pkt->count) {
957 DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
958 return -EINVAL;
959 }
960 break;
961 case PACKET3_INDEX_BASE:
962 if (pkt->count != 1) {
963 DRM_ERROR("bad INDEX_BASE\n");
964 return -EINVAL;
965 }
966 r = evergreen_cs_packet_next_reloc(p, &reloc);
967 if (r) {
968 DRM_ERROR("bad INDEX_BASE\n");
969 return -EINVAL;
970 }
971 ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
972 ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
973 r = evergreen_cs_track_check(p);
974 if (r) {
975 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
976 return r;
977 }
978 break;
979 case PACKET3_DRAW_INDEX:
980 if (pkt->count != 3) {
981 DRM_ERROR("bad DRAW_INDEX\n");
982 return -EINVAL;
983 }
984 r = evergreen_cs_packet_next_reloc(p, &reloc);
985 if (r) {
986 DRM_ERROR("bad DRAW_INDEX\n");
987 return -EINVAL;
988 }
989 ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
990 ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
991 r = evergreen_cs_track_check(p);
992 if (r) {
993 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
994 return r;
995 }
996 break;
997 case PACKET3_DRAW_INDEX_2:
998 if (pkt->count != 4) {
999 DRM_ERROR("bad DRAW_INDEX_2\n");
1000 return -EINVAL;
1001 }
1002 r = evergreen_cs_packet_next_reloc(p, &reloc);
1003 if (r) {
1004 DRM_ERROR("bad DRAW_INDEX_2\n");
1005 return -EINVAL;
1006 }
1007 ib[idx+1] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1008 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1009 r = evergreen_cs_track_check(p);
1010 if (r) {
1011 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1012 return r;
1013 }
1014 break;
1015 case PACKET3_DRAW_INDEX_AUTO:
1016 if (pkt->count != 1) {
1017 DRM_ERROR("bad DRAW_INDEX_AUTO\n");
1018 return -EINVAL;
1019 }
1020 r = evergreen_cs_track_check(p);
1021 if (r) {
1022 dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
1023 return r;
1024 }
1025 break;
1026 case PACKET3_DRAW_INDEX_MULTI_AUTO:
1027 if (pkt->count != 2) {
1028 DRM_ERROR("bad DRAW_INDEX_MULTI_AUTO\n");
1029 return -EINVAL;
1030 }
1031 r = evergreen_cs_track_check(p);
1032 if (r) {
1033 dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
1034 return r;
1035 }
1036 break;
1037 case PACKET3_DRAW_INDEX_IMMD:
1038 if (pkt->count < 2) {
1039 DRM_ERROR("bad DRAW_INDEX_IMMD\n");
1040 return -EINVAL;
1041 }
1042 r = evergreen_cs_track_check(p);
1043 if (r) {
1044 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1045 return r;
1046 }
1047 break;
1048 case PACKET3_DRAW_INDEX_OFFSET:
1049 if (pkt->count != 2) {
1050 DRM_ERROR("bad DRAW_INDEX_OFFSET\n");
1051 return -EINVAL;
1052 }
1053 r = evergreen_cs_track_check(p);
1054 if (r) {
1055 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1056 return r;
1057 }
1058 break;
1059 case PACKET3_DRAW_INDEX_OFFSET_2:
1060 if (pkt->count != 3) {
1061 DRM_ERROR("bad DRAW_INDEX_OFFSET_2\n");
1062 return -EINVAL;
1063 }
1064 r = evergreen_cs_track_check(p);
1065 if (r) {
1066 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1067 return r;
1068 }
1069 break;
1070 case PACKET3_WAIT_REG_MEM:
1071 if (pkt->count != 5) {
1072 DRM_ERROR("bad WAIT_REG_MEM\n");
1073 return -EINVAL;
1074 }
1075 /* bit 4 is reg (0) or mem (1) */
1076 if (idx_value & 0x10) {
1077 r = evergreen_cs_packet_next_reloc(p, &reloc);
1078 if (r) {
1079 DRM_ERROR("bad WAIT_REG_MEM\n");
1080 return -EINVAL;
1081 }
1082 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1083 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1084 }
1085 break;
1086 case PACKET3_SURFACE_SYNC:
1087 if (pkt->count != 3) {
1088 DRM_ERROR("bad SURFACE_SYNC\n");
1089 return -EINVAL;
1090 }
1091 /* 0xffffffff/0x0 is flush all cache flag */
1092 if (radeon_get_ib_value(p, idx + 1) != 0xffffffff ||
1093 radeon_get_ib_value(p, idx + 2) != 0) {
1094 r = evergreen_cs_packet_next_reloc(p, &reloc);
1095 if (r) {
1096 DRM_ERROR("bad SURFACE_SYNC\n");
1097 return -EINVAL;
1098 }
1099 ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1100 }
1101 break;
1102 case PACKET3_EVENT_WRITE:
1103 if (pkt->count != 2 && pkt->count != 0) {
1104 DRM_ERROR("bad EVENT_WRITE\n");
1105 return -EINVAL;
1106 }
1107 if (pkt->count) {
1108 r = evergreen_cs_packet_next_reloc(p, &reloc);
1109 if (r) {
1110 DRM_ERROR("bad EVENT_WRITE\n");
1111 return -EINVAL;
1112 }
1113 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1114 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1115 }
1116 break;
1117 case PACKET3_EVENT_WRITE_EOP:
1118 if (pkt->count != 4) {
1119 DRM_ERROR("bad EVENT_WRITE_EOP\n");
1120 return -EINVAL;
1121 }
1122 r = evergreen_cs_packet_next_reloc(p, &reloc);
1123 if (r) {
1124 DRM_ERROR("bad EVENT_WRITE_EOP\n");
1125 return -EINVAL;
1126 }
1127 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1128 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1129 break;
1130 case PACKET3_EVENT_WRITE_EOS:
1131 if (pkt->count != 3) {
1132 DRM_ERROR("bad EVENT_WRITE_EOS\n");
1133 return -EINVAL;
1134 }
1135 r = evergreen_cs_packet_next_reloc(p, &reloc);
1136 if (r) {
1137 DRM_ERROR("bad EVENT_WRITE_EOS\n");
1138 return -EINVAL;
1139 }
1140 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1141 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1142 break;
1143 case PACKET3_SET_CONFIG_REG:
1144 start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
1145 end_reg = 4 * pkt->count + start_reg - 4;
1146 if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
1147 (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
1148 (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
1149 DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
1150 return -EINVAL;
1151 }
1152 for (i = 0; i < pkt->count; i++) {
1153 reg = start_reg + (4 * i);
1154 r = evergreen_cs_check_reg(p, reg, idx+1+i);
1155 if (r)
1156 return r;
1157 }
1158 break;
1159 case PACKET3_SET_CONTEXT_REG:
1160 start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_START;
1161 end_reg = 4 * pkt->count + start_reg - 4;
1162 if ((start_reg < PACKET3_SET_CONTEXT_REG_START) ||
1163 (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
1164 (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
1165 DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
1166 return -EINVAL;
1167 }
1168 for (i = 0; i < pkt->count; i++) {
1169 reg = start_reg + (4 * i);
1170 r = evergreen_cs_check_reg(p, reg, idx+1+i);
1171 if (r)
1172 return r;
1173 }
1174 break;
1175 case PACKET3_SET_RESOURCE:
1176 if (pkt->count % 8) {
1177 DRM_ERROR("bad SET_RESOURCE\n");
1178 return -EINVAL;
1179 }
1180 start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_START;
1181 end_reg = 4 * pkt->count + start_reg - 4;
1182 if ((start_reg < PACKET3_SET_RESOURCE_START) ||
1183 (start_reg >= PACKET3_SET_RESOURCE_END) ||
1184 (end_reg >= PACKET3_SET_RESOURCE_END)) {
1185 DRM_ERROR("bad SET_RESOURCE\n");
1186 return -EINVAL;
1187 }
1188 for (i = 0; i < (pkt->count / 8); i++) {
1189 struct radeon_bo *texture, *mipmap;
1190 u32 size, offset;
1191
1192 switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
1193 case SQ_TEX_VTX_VALID_TEXTURE:
1194 /* tex base */
1195 r = evergreen_cs_packet_next_reloc(p, &reloc);
1196 if (r) {
1197 DRM_ERROR("bad SET_RESOURCE (tex)\n");
1198 return -EINVAL;
1199 }
1200 ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1201 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1202 ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
1203 else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1204 ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
1205 texture = reloc->robj;
1206 /* tex mip base */
1207 r = evergreen_cs_packet_next_reloc(p, &reloc);
1208 if (r) {
1209 DRM_ERROR("bad SET_RESOURCE (tex)\n");
1210 return -EINVAL;
1211 }
1212 ib[idx+1+(i*8)+4] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1213 mipmap = reloc->robj;
1214 r = evergreen_check_texture_resource(p, idx+1+(i*8),
1215 texture, mipmap);
1216 if (r)
1217 return r;
1218 break;
1219 case SQ_TEX_VTX_VALID_BUFFER:
1220 /* vtx base */
1221 r = evergreen_cs_packet_next_reloc(p, &reloc);
1222 if (r) {
1223 DRM_ERROR("bad SET_RESOURCE (vtx)\n");
1224 return -EINVAL;
1225 }
1226 offset = radeon_get_ib_value(p, idx+1+(i*8)+0);
1227 size = radeon_get_ib_value(p, idx+1+(i*8)+1);
1228 if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
1229 /* force size to size of the buffer */
1230 dev_warn(p->dev, "vbo resource seems too big for the bo\n");
1231 ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->robj);
1232 }
1233 ib[idx+1+(i*8)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
1234 ib[idx+1+(i*8)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1235 break;
1236 case SQ_TEX_VTX_INVALID_TEXTURE:
1237 case SQ_TEX_VTX_INVALID_BUFFER:
1238 default:
1239 DRM_ERROR("bad SET_RESOURCE\n");
1240 return -EINVAL;
1241 }
1242 }
1243 break;
1244 case PACKET3_SET_ALU_CONST:
1245 /* XXX fix me ALU const buffers only */
1246 break;
1247 case PACKET3_SET_BOOL_CONST:
1248 start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_START;
1249 end_reg = 4 * pkt->count + start_reg - 4;
1250 if ((start_reg < PACKET3_SET_BOOL_CONST_START) ||
1251 (start_reg >= PACKET3_SET_BOOL_CONST_END) ||
1252 (end_reg >= PACKET3_SET_BOOL_CONST_END)) {
1253 DRM_ERROR("bad SET_BOOL_CONST\n");
1254 return -EINVAL;
1255 }
1256 break;
1257 case PACKET3_SET_LOOP_CONST:
1258 start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_START;
1259 end_reg = 4 * pkt->count + start_reg - 4;
1260 if ((start_reg < PACKET3_SET_LOOP_CONST_START) ||
1261 (start_reg >= PACKET3_SET_LOOP_CONST_END) ||
1262 (end_reg >= PACKET3_SET_LOOP_CONST_END)) {
1263 DRM_ERROR("bad SET_LOOP_CONST\n");
1264 return -EINVAL;
1265 }
1266 break;
1267 case PACKET3_SET_CTL_CONST:
1268 start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_START;
1269 end_reg = 4 * pkt->count + start_reg - 4;
1270 if ((start_reg < PACKET3_SET_CTL_CONST_START) ||
1271 (start_reg >= PACKET3_SET_CTL_CONST_END) ||
1272 (end_reg >= PACKET3_SET_CTL_CONST_END)) {
1273 DRM_ERROR("bad SET_CTL_CONST\n");
1274 return -EINVAL;
1275 }
1276 break;
1277 case PACKET3_SET_SAMPLER:
1278 if (pkt->count % 3) {
1279 DRM_ERROR("bad SET_SAMPLER\n");
1280 return -EINVAL;
1281 }
1282 start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_START;
1283 end_reg = 4 * pkt->count + start_reg - 4;
1284 if ((start_reg < PACKET3_SET_SAMPLER_START) ||
1285 (start_reg >= PACKET3_SET_SAMPLER_END) ||
1286 (end_reg >= PACKET3_SET_SAMPLER_END)) {
1287 DRM_ERROR("bad SET_SAMPLER\n");
1288 return -EINVAL;
1289 }
1290 break;
1291 case PACKET3_NOP:
1292 break;
1293 default:
1294 DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
1295 return -EINVAL;
1296 }
1297 return 0;
1298}
1299
1300int evergreen_cs_parse(struct radeon_cs_parser *p)
1301{
1302 struct radeon_cs_packet pkt;
1303 struct evergreen_cs_track *track;
1304 int r;
1305
1306 if (p->track == NULL) {
1307 /* initialize tracker, we are in kms */
1308 track = kzalloc(sizeof(*track), GFP_KERNEL);
1309 if (track == NULL)
1310 return -ENOMEM;
1311 evergreen_cs_track_init(track);
1312 track->npipes = p->rdev->config.evergreen.tiling_npipes;
1313 track->nbanks = p->rdev->config.evergreen.tiling_nbanks;
1314 track->group_size = p->rdev->config.evergreen.tiling_group_size;
1315 p->track = track;
1316 }
1317 do {
1318 r = evergreen_cs_packet_parse(p, &pkt, p->idx);
1319 if (r) {
1320 kfree(p->track);
1321 p->track = NULL;
1322 return r;
1323 }
1324 p->idx += pkt.count + 2;
1325 switch (pkt.type) {
1326 case PACKET_TYPE0:
1327 r = evergreen_cs_parse_packet0(p, &pkt);
1328 break;
1329 case PACKET_TYPE2:
1330 break;
1331 case PACKET_TYPE3:
1332 r = evergreen_packet3_check(p, &pkt);
1333 break;
1334 default:
1335 DRM_ERROR("Unknown packet type %d !\n", pkt.type);
1336 kfree(p->track);
1337 p->track = NULL;
1338 return -EINVAL;
1339 }
1340 if (r) {
1341 kfree(p->track);
1342 p->track = NULL;
1343 return r;
1344 }
1345 } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
1346#if 0
1347 for (r = 0; r < p->ib->length_dw; r++) {
1348 printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]);
1349 mdelay(1);
1350 }
1351#endif
1352 kfree(p->track);
1353 p->track = NULL;
1354 return 0;
1355}
1356
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index af86af836f13..e028c1cd9d9b 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -151,6 +151,9 @@
151#define EVERGREEN_DATA_FORMAT 0x6b00 151#define EVERGREEN_DATA_FORMAT 0x6b00
152# define EVERGREEN_INTERLEAVE_EN (1 << 0) 152# define EVERGREEN_INTERLEAVE_EN (1 << 0)
153#define EVERGREEN_DESKTOP_HEIGHT 0x6b04 153#define EVERGREEN_DESKTOP_HEIGHT 0x6b04
154#define EVERGREEN_VLINE_START_END 0x6b08
155#define EVERGREEN_VLINE_STATUS 0x6bb8
156# define EVERGREEN_VLINE_STAT (1 << 12)
154 157
155#define EVERGREEN_VIEWPORT_START 0x6d70 158#define EVERGREEN_VIEWPORT_START 0x6d70
156#define EVERGREEN_VIEWPORT_SIZE 0x6d74 159#define EVERGREEN_VIEWPORT_SIZE 0x6d74
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 93e9e17ad54a..79683f6b4452 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -218,6 +218,8 @@
218#define CLIP_VTX_REORDER_ENA (1 << 0) 218#define CLIP_VTX_REORDER_ENA (1 << 0)
219#define NUM_CLIP_SEQ(x) ((x) << 1) 219#define NUM_CLIP_SEQ(x) ((x) << 1)
220#define PA_SC_AA_CONFIG 0x28C04 220#define PA_SC_AA_CONFIG 0x28C04
221#define MSAA_NUM_SAMPLES_SHIFT 0
222#define MSAA_NUM_SAMPLES_MASK 0x3
221#define PA_SC_CLIPRECT_RULE 0x2820C 223#define PA_SC_CLIPRECT_RULE 0x2820C
222#define PA_SC_EDGERULE 0x28230 224#define PA_SC_EDGERULE 0x28230
223#define PA_SC_FIFO_SIZE 0x8BCC 225#define PA_SC_FIFO_SIZE 0x8BCC
@@ -553,4 +555,466 @@
553# define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) 555# define DC_HPDx_RX_INT_TIMER(x) ((x) << 16)
554# define DC_HPDx_EN (1 << 28) 556# define DC_HPDx_EN (1 << 28)
555 557
558/*
559 * PM4
560 */
561#define PACKET_TYPE0 0
562#define PACKET_TYPE1 1
563#define PACKET_TYPE2 2
564#define PACKET_TYPE3 3
565
566#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
567#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
568#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2)
569#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
570#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \
571 (((reg) >> 2) & 0xFFFF) | \
572 ((n) & 0x3FFF) << 16)
573#define CP_PACKET2 0x80000000
574#define PACKET2_PAD_SHIFT 0
575#define PACKET2_PAD_MASK (0x3fffffff << 0)
576
577#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
578
579#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
580 (((op) & 0xFF) << 8) | \
581 ((n) & 0x3FFF) << 16)
582
583/* Packet 3 types */
584#define PACKET3_NOP 0x10
585#define PACKET3_SET_BASE 0x11
586#define PACKET3_CLEAR_STATE 0x12
587#define PACKET3_INDIRECT_BUFFER_SIZE 0x13
588#define PACKET3_DISPATCH_DIRECT 0x15
589#define PACKET3_DISPATCH_INDIRECT 0x16
590#define PACKET3_INDIRECT_BUFFER_END 0x17
591#define PACKET3_SET_PREDICATION 0x20
592#define PACKET3_REG_RMW 0x21
593#define PACKET3_COND_EXEC 0x22
594#define PACKET3_PRED_EXEC 0x23
595#define PACKET3_DRAW_INDIRECT 0x24
596#define PACKET3_DRAW_INDEX_INDIRECT 0x25
597#define PACKET3_INDEX_BASE 0x26
598#define PACKET3_DRAW_INDEX_2 0x27
599#define PACKET3_CONTEXT_CONTROL 0x28
600#define PACKET3_DRAW_INDEX_OFFSET 0x29
601#define PACKET3_INDEX_TYPE 0x2A
602#define PACKET3_DRAW_INDEX 0x2B
603#define PACKET3_DRAW_INDEX_AUTO 0x2D
604#define PACKET3_DRAW_INDEX_IMMD 0x2E
605#define PACKET3_NUM_INSTANCES 0x2F
606#define PACKET3_DRAW_INDEX_MULTI_AUTO 0x30
607#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34
608#define PACKET3_DRAW_INDEX_OFFSET_2 0x35
609#define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36
610#define PACKET3_MEM_SEMAPHORE 0x39
611#define PACKET3_MPEG_INDEX 0x3A
612#define PACKET3_WAIT_REG_MEM 0x3C
613#define PACKET3_MEM_WRITE 0x3D
614#define PACKET3_INDIRECT_BUFFER 0x32
615#define PACKET3_SURFACE_SYNC 0x43
616# define PACKET3_CB0_DEST_BASE_ENA (1 << 6)
617# define PACKET3_CB1_DEST_BASE_ENA (1 << 7)
618# define PACKET3_CB2_DEST_BASE_ENA (1 << 8)
619# define PACKET3_CB3_DEST_BASE_ENA (1 << 9)
620# define PACKET3_CB4_DEST_BASE_ENA (1 << 10)
621# define PACKET3_CB5_DEST_BASE_ENA (1 << 11)
622# define PACKET3_CB6_DEST_BASE_ENA (1 << 12)
623# define PACKET3_CB7_DEST_BASE_ENA (1 << 13)
624# define PACKET3_DB_DEST_BASE_ENA (1 << 14)
625# define PACKET3_CB8_DEST_BASE_ENA (1 << 15)
626# define PACKET3_CB9_DEST_BASE_ENA (1 << 16)
627# define PACKET3_CB10_DEST_BASE_ENA (1 << 17)
628# define PACKET3_CB11_DEST_BASE_ENA (1 << 17)
629# define PACKET3_FULL_CACHE_ENA (1 << 20)
630# define PACKET3_TC_ACTION_ENA (1 << 23)
631# define PACKET3_VC_ACTION_ENA (1 << 24)
632# define PACKET3_CB_ACTION_ENA (1 << 25)
633# define PACKET3_DB_ACTION_ENA (1 << 26)
634# define PACKET3_SH_ACTION_ENA (1 << 27)
635# define PACKET3_SMX_ACTION_ENA (1 << 28)
636#define PACKET3_ME_INITIALIZE 0x44
637#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
638#define PACKET3_COND_WRITE 0x45
639#define PACKET3_EVENT_WRITE 0x46
640#define PACKET3_EVENT_WRITE_EOP 0x47
641#define PACKET3_EVENT_WRITE_EOS 0x48
642#define PACKET3_PREAMBLE_CNTL 0x4A
643#define PACKET3_RB_OFFSET 0x4B
644#define PACKET3_ALU_PS_CONST_BUFFER_COPY 0x4C
645#define PACKET3_ALU_VS_CONST_BUFFER_COPY 0x4D
646#define PACKET3_ALU_PS_CONST_UPDATE 0x4E
647#define PACKET3_ALU_VS_CONST_UPDATE 0x4F
648#define PACKET3_ONE_REG_WRITE 0x57
649#define PACKET3_SET_CONFIG_REG 0x68
650#define PACKET3_SET_CONFIG_REG_START 0x00008000
651#define PACKET3_SET_CONFIG_REG_END 0x0000ac00
652#define PACKET3_SET_CONTEXT_REG 0x69
653#define PACKET3_SET_CONTEXT_REG_START 0x00028000
654#define PACKET3_SET_CONTEXT_REG_END 0x00029000
655#define PACKET3_SET_ALU_CONST 0x6A
656/* alu const buffers only; no reg file */
657#define PACKET3_SET_BOOL_CONST 0x6B
658#define PACKET3_SET_BOOL_CONST_START 0x0003a500
659#define PACKET3_SET_BOOL_CONST_END 0x0003a518
660#define PACKET3_SET_LOOP_CONST 0x6C
661#define PACKET3_SET_LOOP_CONST_START 0x0003a200
662#define PACKET3_SET_LOOP_CONST_END 0x0003a500
663#define PACKET3_SET_RESOURCE 0x6D
664#define PACKET3_SET_RESOURCE_START 0x00030000
665#define PACKET3_SET_RESOURCE_END 0x00038000
666#define PACKET3_SET_SAMPLER 0x6E
667#define PACKET3_SET_SAMPLER_START 0x0003c000
668#define PACKET3_SET_SAMPLER_END 0x0003c600
669#define PACKET3_SET_CTL_CONST 0x6F
670#define PACKET3_SET_CTL_CONST_START 0x0003cff0
671#define PACKET3_SET_CTL_CONST_END 0x0003ff0c
672#define PACKET3_SET_RESOURCE_OFFSET 0x70
673#define PACKET3_SET_ALU_CONST_VS 0x71
674#define PACKET3_SET_ALU_CONST_DI 0x72
675#define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73
676#define PACKET3_SET_RESOURCE_INDIRECT 0x74
677#define PACKET3_SET_APPEND_CNT 0x75
678
679#define SQ_RESOURCE_CONSTANT_WORD7_0 0x3001c
680#define S__SQ_CONSTANT_TYPE(x) (((x) & 3) << 30)
681#define G__SQ_CONSTANT_TYPE(x) (((x) >> 30) & 3)
682#define SQ_TEX_VTX_INVALID_TEXTURE 0x0
683#define SQ_TEX_VTX_INVALID_BUFFER 0x1
684#define SQ_TEX_VTX_VALID_TEXTURE 0x2
685#define SQ_TEX_VTX_VALID_BUFFER 0x3
686
687#define SQ_CONST_MEM_BASE 0x8df8
688
689#define SQ_ESGS_RING_SIZE 0x8c44
690#define SQ_GSVS_RING_SIZE 0x8c4c
691#define SQ_ESTMP_RING_SIZE 0x8c54
692#define SQ_GSTMP_RING_SIZE 0x8c5c
693#define SQ_VSTMP_RING_SIZE 0x8c64
694#define SQ_PSTMP_RING_SIZE 0x8c6c
695#define SQ_LSTMP_RING_SIZE 0x8e14
696#define SQ_HSTMP_RING_SIZE 0x8e1c
697#define VGT_TF_RING_SIZE 0x8988
698
699#define SQ_ESGS_RING_ITEMSIZE 0x28900
700#define SQ_GSVS_RING_ITEMSIZE 0x28904
701#define SQ_ESTMP_RING_ITEMSIZE 0x28908
702#define SQ_GSTMP_RING_ITEMSIZE 0x2890c
703#define SQ_VSTMP_RING_ITEMSIZE 0x28910
704#define SQ_PSTMP_RING_ITEMSIZE 0x28914
705#define SQ_LSTMP_RING_ITEMSIZE 0x28830
706#define SQ_HSTMP_RING_ITEMSIZE 0x28834
707
708#define SQ_GS_VERT_ITEMSIZE 0x2891c
709#define SQ_GS_VERT_ITEMSIZE_1 0x28920
710#define SQ_GS_VERT_ITEMSIZE_2 0x28924
711#define SQ_GS_VERT_ITEMSIZE_3 0x28928
712#define SQ_GSVS_RING_OFFSET_1 0x2892c
713#define SQ_GSVS_RING_OFFSET_2 0x28930
714#define SQ_GSVS_RING_OFFSET_3 0x28934
715
716#define SQ_ALU_CONST_CACHE_PS_0 0x28940
717#define SQ_ALU_CONST_CACHE_PS_1 0x28944
718#define SQ_ALU_CONST_CACHE_PS_2 0x28948
719#define SQ_ALU_CONST_CACHE_PS_3 0x2894c
720#define SQ_ALU_CONST_CACHE_PS_4 0x28950
721#define SQ_ALU_CONST_CACHE_PS_5 0x28954
722#define SQ_ALU_CONST_CACHE_PS_6 0x28958
723#define SQ_ALU_CONST_CACHE_PS_7 0x2895c
724#define SQ_ALU_CONST_CACHE_PS_8 0x28960
725#define SQ_ALU_CONST_CACHE_PS_9 0x28964
726#define SQ_ALU_CONST_CACHE_PS_10 0x28968
727#define SQ_ALU_CONST_CACHE_PS_11 0x2896c
728#define SQ_ALU_CONST_CACHE_PS_12 0x28970
729#define SQ_ALU_CONST_CACHE_PS_13 0x28974
730#define SQ_ALU_CONST_CACHE_PS_14 0x28978
731#define SQ_ALU_CONST_CACHE_PS_15 0x2897c
732#define SQ_ALU_CONST_CACHE_VS_0 0x28980
733#define SQ_ALU_CONST_CACHE_VS_1 0x28984
734#define SQ_ALU_CONST_CACHE_VS_2 0x28988
735#define SQ_ALU_CONST_CACHE_VS_3 0x2898c
736#define SQ_ALU_CONST_CACHE_VS_4 0x28990
737#define SQ_ALU_CONST_CACHE_VS_5 0x28994
738#define SQ_ALU_CONST_CACHE_VS_6 0x28998
739#define SQ_ALU_CONST_CACHE_VS_7 0x2899c
740#define SQ_ALU_CONST_CACHE_VS_8 0x289a0
741#define SQ_ALU_CONST_CACHE_VS_9 0x289a4
742#define SQ_ALU_CONST_CACHE_VS_10 0x289a8
743#define SQ_ALU_CONST_CACHE_VS_11 0x289ac
744#define SQ_ALU_CONST_CACHE_VS_12 0x289b0
745#define SQ_ALU_CONST_CACHE_VS_13 0x289b4
746#define SQ_ALU_CONST_CACHE_VS_14 0x289b8
747#define SQ_ALU_CONST_CACHE_VS_15 0x289bc
748#define SQ_ALU_CONST_CACHE_GS_0 0x289c0
749#define SQ_ALU_CONST_CACHE_GS_1 0x289c4
750#define SQ_ALU_CONST_CACHE_GS_2 0x289c8
751#define SQ_ALU_CONST_CACHE_GS_3 0x289cc
752#define SQ_ALU_CONST_CACHE_GS_4 0x289d0
753#define SQ_ALU_CONST_CACHE_GS_5 0x289d4
754#define SQ_ALU_CONST_CACHE_GS_6 0x289d8
755#define SQ_ALU_CONST_CACHE_GS_7 0x289dc
756#define SQ_ALU_CONST_CACHE_GS_8 0x289e0
757#define SQ_ALU_CONST_CACHE_GS_9 0x289e4
758#define SQ_ALU_CONST_CACHE_GS_10 0x289e8
759#define SQ_ALU_CONST_CACHE_GS_11 0x289ec
760#define SQ_ALU_CONST_CACHE_GS_12 0x289f0
761#define SQ_ALU_CONST_CACHE_GS_13 0x289f4
762#define SQ_ALU_CONST_CACHE_GS_14 0x289f8
763#define SQ_ALU_CONST_CACHE_GS_15 0x289fc
764#define SQ_ALU_CONST_CACHE_HS_0 0x28f00
765#define SQ_ALU_CONST_CACHE_HS_1 0x28f04
766#define SQ_ALU_CONST_CACHE_HS_2 0x28f08
767#define SQ_ALU_CONST_CACHE_HS_3 0x28f0c
768#define SQ_ALU_CONST_CACHE_HS_4 0x28f10
769#define SQ_ALU_CONST_CACHE_HS_5 0x28f14
770#define SQ_ALU_CONST_CACHE_HS_6 0x28f18
771#define SQ_ALU_CONST_CACHE_HS_7 0x28f1c
772#define SQ_ALU_CONST_CACHE_HS_8 0x28f20
773#define SQ_ALU_CONST_CACHE_HS_9 0x28f24
774#define SQ_ALU_CONST_CACHE_HS_10 0x28f28
775#define SQ_ALU_CONST_CACHE_HS_11 0x28f2c
776#define SQ_ALU_CONST_CACHE_HS_12 0x28f30
777#define SQ_ALU_CONST_CACHE_HS_13 0x28f34
778#define SQ_ALU_CONST_CACHE_HS_14 0x28f38
779#define SQ_ALU_CONST_CACHE_HS_15 0x28f3c
780#define SQ_ALU_CONST_CACHE_LS_0 0x28f40
781#define SQ_ALU_CONST_CACHE_LS_1 0x28f44
782#define SQ_ALU_CONST_CACHE_LS_2 0x28f48
783#define SQ_ALU_CONST_CACHE_LS_3 0x28f4c
784#define SQ_ALU_CONST_CACHE_LS_4 0x28f50
785#define SQ_ALU_CONST_CACHE_LS_5 0x28f54
786#define SQ_ALU_CONST_CACHE_LS_6 0x28f58
787#define SQ_ALU_CONST_CACHE_LS_7 0x28f5c
788#define SQ_ALU_CONST_CACHE_LS_8 0x28f60
789#define SQ_ALU_CONST_CACHE_LS_9 0x28f64
790#define SQ_ALU_CONST_CACHE_LS_10 0x28f68
791#define SQ_ALU_CONST_CACHE_LS_11 0x28f6c
792#define SQ_ALU_CONST_CACHE_LS_12 0x28f70
793#define SQ_ALU_CONST_CACHE_LS_13 0x28f74
794#define SQ_ALU_CONST_CACHE_LS_14 0x28f78
795#define SQ_ALU_CONST_CACHE_LS_15 0x28f7c
796
797#define DB_DEPTH_CONTROL 0x28800
798#define DB_DEPTH_VIEW 0x28008
799#define DB_HTILE_DATA_BASE 0x28014
800#define DB_Z_INFO 0x28040
801# define Z_ARRAY_MODE(x) ((x) << 4)
802#define DB_STENCIL_INFO 0x28044
803#define DB_Z_READ_BASE 0x28048
804#define DB_STENCIL_READ_BASE 0x2804c
805#define DB_Z_WRITE_BASE 0x28050
806#define DB_STENCIL_WRITE_BASE 0x28054
807#define DB_DEPTH_SIZE 0x28058
808
809#define SQ_PGM_START_PS 0x28840
810#define SQ_PGM_START_VS 0x2885c
811#define SQ_PGM_START_GS 0x28874
812#define SQ_PGM_START_ES 0x2888c
813#define SQ_PGM_START_FS 0x288a4
814#define SQ_PGM_START_HS 0x288b8
815#define SQ_PGM_START_LS 0x288d0
816
817#define VGT_STRMOUT_CONFIG 0x28b94
818#define VGT_STRMOUT_BUFFER_CONFIG 0x28b98
819
820#define CB_TARGET_MASK 0x28238
821#define CB_SHADER_MASK 0x2823c
822
823#define GDS_ADDR_BASE 0x28720
824
825#define CB_IMMED0_BASE 0x28b9c
826#define CB_IMMED1_BASE 0x28ba0
827#define CB_IMMED2_BASE 0x28ba4
828#define CB_IMMED3_BASE 0x28ba8
829#define CB_IMMED4_BASE 0x28bac
830#define CB_IMMED5_BASE 0x28bb0
831#define CB_IMMED6_BASE 0x28bb4
832#define CB_IMMED7_BASE 0x28bb8
833#define CB_IMMED8_BASE 0x28bbc
834#define CB_IMMED9_BASE 0x28bc0
835#define CB_IMMED10_BASE 0x28bc4
836#define CB_IMMED11_BASE 0x28bc8
837
838/* all 12 CB blocks have these regs */
839#define CB_COLOR0_BASE 0x28c60
840#define CB_COLOR0_PITCH 0x28c64
841#define CB_COLOR0_SLICE 0x28c68
842#define CB_COLOR0_VIEW 0x28c6c
843#define CB_COLOR0_INFO 0x28c70
844# define CB_ARRAY_MODE(x) ((x) << 8)
845# define ARRAY_LINEAR_GENERAL 0
846# define ARRAY_LINEAR_ALIGNED 1
847# define ARRAY_1D_TILED_THIN1 2
848# define ARRAY_2D_TILED_THIN1 4
849#define CB_COLOR0_ATTRIB 0x28c74
850#define CB_COLOR0_DIM 0x28c78
851/* only CB0-7 blocks have these regs */
852#define CB_COLOR0_CMASK 0x28c7c
853#define CB_COLOR0_CMASK_SLICE 0x28c80
854#define CB_COLOR0_FMASK 0x28c84
855#define CB_COLOR0_FMASK_SLICE 0x28c88
856#define CB_COLOR0_CLEAR_WORD0 0x28c8c
857#define CB_COLOR0_CLEAR_WORD1 0x28c90
858#define CB_COLOR0_CLEAR_WORD2 0x28c94
859#define CB_COLOR0_CLEAR_WORD3 0x28c98
860
861#define CB_COLOR1_BASE 0x28c9c
862#define CB_COLOR2_BASE 0x28cd8
863#define CB_COLOR3_BASE 0x28d14
864#define CB_COLOR4_BASE 0x28d50
865#define CB_COLOR5_BASE 0x28d8c
866#define CB_COLOR6_BASE 0x28dc8
867#define CB_COLOR7_BASE 0x28e04
868#define CB_COLOR8_BASE 0x28e40
869#define CB_COLOR9_BASE 0x28e5c
870#define CB_COLOR10_BASE 0x28e78
871#define CB_COLOR11_BASE 0x28e94
872
873#define CB_COLOR1_PITCH 0x28ca0
874#define CB_COLOR2_PITCH 0x28cdc
875#define CB_COLOR3_PITCH 0x28d18
876#define CB_COLOR4_PITCH 0x28d54
877#define CB_COLOR5_PITCH 0x28d90
878#define CB_COLOR6_PITCH 0x28dcc
879#define CB_COLOR7_PITCH 0x28e08
880#define CB_COLOR8_PITCH 0x28e44
881#define CB_COLOR9_PITCH 0x28e60
882#define CB_COLOR10_PITCH 0x28e7c
883#define CB_COLOR11_PITCH 0x28e98
884
885#define CB_COLOR1_SLICE 0x28ca4
886#define CB_COLOR2_SLICE 0x28ce0
887#define CB_COLOR3_SLICE 0x28d1c
888#define CB_COLOR4_SLICE 0x28d58
889#define CB_COLOR5_SLICE 0x28d94
890#define CB_COLOR6_SLICE 0x28dd0
891#define CB_COLOR7_SLICE 0x28e0c
892#define CB_COLOR8_SLICE 0x28e48
893#define CB_COLOR9_SLICE 0x28e64
894#define CB_COLOR10_SLICE 0x28e80
895#define CB_COLOR11_SLICE 0x28e9c
896
897#define CB_COLOR1_VIEW 0x28ca8
898#define CB_COLOR2_VIEW 0x28ce4
899#define CB_COLOR3_VIEW 0x28d20
900#define CB_COLOR4_VIEW 0x28d5c
901#define CB_COLOR5_VIEW 0x28d98
902#define CB_COLOR6_VIEW 0x28dd4
903#define CB_COLOR7_VIEW 0x28e10
904#define CB_COLOR8_VIEW 0x28e4c
905#define CB_COLOR9_VIEW 0x28e68
906#define CB_COLOR10_VIEW 0x28e84
907#define CB_COLOR11_VIEW 0x28ea0
908
909#define CB_COLOR1_INFO 0x28cac
910#define CB_COLOR2_INFO 0x28ce8
911#define CB_COLOR3_INFO 0x28d24
912#define CB_COLOR4_INFO 0x28d60
913#define CB_COLOR5_INFO 0x28d9c
914#define CB_COLOR6_INFO 0x28dd8
915#define CB_COLOR7_INFO 0x28e14
916#define CB_COLOR8_INFO 0x28e50
917#define CB_COLOR9_INFO 0x28e6c
918#define CB_COLOR10_INFO 0x28e88
919#define CB_COLOR11_INFO 0x28ea4
920
921#define CB_COLOR1_ATTRIB 0x28cb0
922#define CB_COLOR2_ATTRIB 0x28cec
923#define CB_COLOR3_ATTRIB 0x28d28
924#define CB_COLOR4_ATTRIB 0x28d64
925#define CB_COLOR5_ATTRIB 0x28da0
926#define CB_COLOR6_ATTRIB 0x28ddc
927#define CB_COLOR7_ATTRIB 0x28e18
928#define CB_COLOR8_ATTRIB 0x28e54
929#define CB_COLOR9_ATTRIB 0x28e70
930#define CB_COLOR10_ATTRIB 0x28e8c
931#define CB_COLOR11_ATTRIB 0x28ea8
932
933#define CB_COLOR1_DIM 0x28cb4
934#define CB_COLOR2_DIM 0x28cf0
935#define CB_COLOR3_DIM 0x28d2c
936#define CB_COLOR4_DIM 0x28d68
937#define CB_COLOR5_DIM 0x28da4
938#define CB_COLOR6_DIM 0x28de0
939#define CB_COLOR7_DIM 0x28e1c
940#define CB_COLOR8_DIM 0x28e58
941#define CB_COLOR9_DIM 0x28e74
942#define CB_COLOR10_DIM 0x28e90
943#define CB_COLOR11_DIM 0x28eac
944
945#define CB_COLOR1_CMASK 0x28cb8
946#define CB_COLOR2_CMASK 0x28cf4
947#define CB_COLOR3_CMASK 0x28d30
948#define CB_COLOR4_CMASK 0x28d6c
949#define CB_COLOR5_CMASK 0x28da8
950#define CB_COLOR6_CMASK 0x28de4
951#define CB_COLOR7_CMASK 0x28e20
952
953#define CB_COLOR1_CMASK_SLICE 0x28cbc
954#define CB_COLOR2_CMASK_SLICE 0x28cf8
955#define CB_COLOR3_CMASK_SLICE 0x28d34
956#define CB_COLOR4_CMASK_SLICE 0x28d70
957#define CB_COLOR5_CMASK_SLICE 0x28dac
958#define CB_COLOR6_CMASK_SLICE 0x28de8
959#define CB_COLOR7_CMASK_SLICE 0x28e24
960
961#define CB_COLOR1_FMASK 0x28cc0
962#define CB_COLOR2_FMASK 0x28cfc
963#define CB_COLOR3_FMASK 0x28d38
964#define CB_COLOR4_FMASK 0x28d74
965#define CB_COLOR5_FMASK 0x28db0
966#define CB_COLOR6_FMASK 0x28dec
967#define CB_COLOR7_FMASK 0x28e28
968
969#define CB_COLOR1_FMASK_SLICE 0x28cc4
970#define CB_COLOR2_FMASK_SLICE 0x28d00
971#define CB_COLOR3_FMASK_SLICE 0x28d3c
972#define CB_COLOR4_FMASK_SLICE 0x28d78
973#define CB_COLOR5_FMASK_SLICE 0x28db4
974#define CB_COLOR6_FMASK_SLICE 0x28df0
975#define CB_COLOR7_FMASK_SLICE 0x28e2c
976
977#define CB_COLOR1_CLEAR_WORD0 0x28cc8
978#define CB_COLOR2_CLEAR_WORD0 0x28d04
979#define CB_COLOR3_CLEAR_WORD0 0x28d40
980#define CB_COLOR4_CLEAR_WORD0 0x28d7c
981#define CB_COLOR5_CLEAR_WORD0 0x28db8
982#define CB_COLOR6_CLEAR_WORD0 0x28df4
983#define CB_COLOR7_CLEAR_WORD0 0x28e30
984
985#define CB_COLOR1_CLEAR_WORD1 0x28ccc
986#define CB_COLOR2_CLEAR_WORD1 0x28d08
987#define CB_COLOR3_CLEAR_WORD1 0x28d44
988#define CB_COLOR4_CLEAR_WORD1 0x28d80
989#define CB_COLOR5_CLEAR_WORD1 0x28dbc
990#define CB_COLOR6_CLEAR_WORD1 0x28df8
991#define CB_COLOR7_CLEAR_WORD1 0x28e34
992
993#define CB_COLOR1_CLEAR_WORD2 0x28cd0
994#define CB_COLOR2_CLEAR_WORD2 0x28d0c
995#define CB_COLOR3_CLEAR_WORD2 0x28d48
996#define CB_COLOR4_CLEAR_WORD2 0x28d84
997#define CB_COLOR5_CLEAR_WORD2 0x28dc0
998#define CB_COLOR6_CLEAR_WORD2 0x28dfc
999#define CB_COLOR7_CLEAR_WORD2 0x28e38
1000
1001#define CB_COLOR1_CLEAR_WORD3 0x28cd4
1002#define CB_COLOR2_CLEAR_WORD3 0x28d10
1003#define CB_COLOR3_CLEAR_WORD3 0x28d4c
1004#define CB_COLOR4_CLEAR_WORD3 0x28d88
1005#define CB_COLOR5_CLEAR_WORD3 0x28dc4
1006#define CB_COLOR6_CLEAR_WORD3 0x28e00
1007#define CB_COLOR7_CLEAR_WORD3 0x28e3c
1008
1009#define SQ_TEX_RESOURCE_WORD0_0 0x30000
1010#define SQ_TEX_RESOURCE_WORD1_0 0x30004
1011# define TEX_ARRAY_MODE(x) ((x) << 28)
1012#define SQ_TEX_RESOURCE_WORD2_0 0x30008
1013#define SQ_TEX_RESOURCE_WORD3_0 0x3000C
1014#define SQ_TEX_RESOURCE_WORD4_0 0x30010
1015#define SQ_TEX_RESOURCE_WORD5_0 0x30014
1016#define SQ_TEX_RESOURCE_WORD6_0 0x30018
1017#define SQ_TEX_RESOURCE_WORD7_0 0x3001c
1018
1019
556#endif 1020#endif
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 44e96a2ae25a..e14f59748e65 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -475,6 +475,12 @@ void r600_pm_init_profile(struct radeon_device *rdev)
475 475
476void r600_pm_misc(struct radeon_device *rdev) 476void r600_pm_misc(struct radeon_device *rdev)
477{ 477{
478 int requested_index = rdev->pm.requested_power_state_index;
479 struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
480 struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
481
482 if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
483 radeon_atom_set_voltage(rdev, voltage->voltage);
478 484
479} 485}
480 486
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 669feb689bfc..5f96fe871b3f 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -176,6 +176,7 @@ void radeon_pm_suspend(struct radeon_device *rdev);
176void radeon_pm_resume(struct radeon_device *rdev); 176void radeon_pm_resume(struct radeon_device *rdev);
177void radeon_combios_get_power_modes(struct radeon_device *rdev); 177void radeon_combios_get_power_modes(struct radeon_device *rdev);
178void radeon_atombios_get_power_modes(struct radeon_device *rdev); 178void radeon_atombios_get_power_modes(struct radeon_device *rdev);
179void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level);
179 180
180/* 181/*
181 * Fences. 182 * Fences.
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index e57df08d4aeb..87f7e2cc52d4 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -724,8 +724,8 @@ static struct radeon_asic evergreen_asic = {
724 .irq_set = &evergreen_irq_set, 724 .irq_set = &evergreen_irq_set,
725 .irq_process = &evergreen_irq_process, 725 .irq_process = &evergreen_irq_process,
726 .get_vblank_counter = &evergreen_get_vblank_counter, 726 .get_vblank_counter = &evergreen_get_vblank_counter,
727 .fence_ring_emit = NULL, 727 .fence_ring_emit = &r600_fence_ring_emit,
728 .cs_parse = NULL, 728 .cs_parse = &evergreen_cs_parse,
729 .copy_blit = NULL, 729 .copy_blit = NULL,
730 .copy_dma = NULL, 730 .copy_dma = NULL,
731 .copy = NULL, 731 .copy = NULL,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 5c40a3dfaca2..c0bbaa64157a 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -314,6 +314,7 @@ void evergreen_hpd_set_polarity(struct radeon_device *rdev,
314u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc); 314u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc);
315int evergreen_irq_set(struct radeon_device *rdev); 315int evergreen_irq_set(struct radeon_device *rdev);
316int evergreen_irq_process(struct radeon_device *rdev); 316int evergreen_irq_process(struct radeon_device *rdev);
317extern int evergreen_cs_parse(struct radeon_cs_parser *p);
317extern void evergreen_pm_misc(struct radeon_device *rdev); 318extern void evergreen_pm_misc(struct radeon_device *rdev);
318extern void evergreen_pm_prepare(struct radeon_device *rdev); 319extern void evergreen_pm_prepare(struct radeon_device *rdev);
319extern void evergreen_pm_finish(struct radeon_device *rdev); 320extern void evergreen_pm_finish(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 24ea683f7cf5..4305cd55d0ac 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1538,7 +1538,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
1538 rdev->pm.power_state[state_index].pcie_lanes = 1538 rdev->pm.power_state[state_index].pcie_lanes =
1539 power_info->info.asPowerPlayInfo[i].ucNumPciELanes; 1539 power_info->info.asPowerPlayInfo[i].ucNumPciELanes;
1540 misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); 1540 misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo);
1541 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { 1541 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
1542 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
1542 rdev->pm.power_state[state_index].clock_info[0].voltage.type = 1543 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1543 VOLTAGE_GPIO; 1544 VOLTAGE_GPIO;
1544 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = 1545 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
@@ -1605,7 +1606,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
1605 power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; 1606 power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes;
1606 misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); 1607 misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo);
1607 misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); 1608 misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2);
1608 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { 1609 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
1610 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
1609 rdev->pm.power_state[state_index].clock_info[0].voltage.type = 1611 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1610 VOLTAGE_GPIO; 1612 VOLTAGE_GPIO;
1611 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = 1613 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
@@ -1679,7 +1681,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
1679 power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; 1681 power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes;
1680 misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); 1682 misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo);
1681 misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); 1683 misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2);
1682 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { 1684 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
1685 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
1683 rdev->pm.power_state[state_index].clock_info[0].voltage.type = 1686 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1684 VOLTAGE_GPIO; 1687 VOLTAGE_GPIO;
1685 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = 1688 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
@@ -1755,9 +1758,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
1755 rdev->pm.power_state[state_index].misc2 = 0; 1758 rdev->pm.power_state[state_index].misc2 = 0;
1756 } 1759 }
1757 } else { 1760 } else {
1761 int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
1762 uint8_t fw_frev, fw_crev;
1763 uint16_t fw_data_offset, vddc = 0;
1764 union firmware_info *firmware_info;
1765 ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController;
1766
1767 if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL,
1768 &fw_frev, &fw_crev, &fw_data_offset)) {
1769 firmware_info =
1770 (union firmware_info *)(mode_info->atom_context->bios +
1771 fw_data_offset);
1772 vddc = firmware_info->info_14.usBootUpVDDCVoltage;
1773 }
1774
1758 /* add the i2c bus for thermal/fan chip */ 1775 /* add the i2c bus for thermal/fan chip */
1759 /* no support for internal controller yet */ 1776 /* no support for internal controller yet */
1760 ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController;
1761 if (controller->ucType > 0) { 1777 if (controller->ucType > 0) {
1762 if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || 1778 if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) ||
1763 (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) || 1779 (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) ||
@@ -1904,6 +1920,16 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
1904 rdev->pm.default_power_state_index = state_index; 1920 rdev->pm.default_power_state_index = state_index;
1905 rdev->pm.power_state[state_index].default_clock_mode = 1921 rdev->pm.power_state[state_index].default_clock_mode =
1906 &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; 1922 &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
1923 /* patch the table values with the default slck/mclk from firmware info */
1924 for (j = 0; j < mode_index; j++) {
1925 rdev->pm.power_state[state_index].clock_info[j].mclk =
1926 rdev->clock.default_mclk;
1927 rdev->pm.power_state[state_index].clock_info[j].sclk =
1928 rdev->clock.default_sclk;
1929 if (vddc)
1930 rdev->pm.power_state[state_index].clock_info[j].voltage.voltage =
1931 vddc;
1932 }
1907 } 1933 }
1908 state_index++; 1934 state_index++;
1909 } 1935 }
@@ -1998,6 +2024,42 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev,
1998 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 2024 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1999} 2025}
2000 2026
2027union set_voltage {
2028 struct _SET_VOLTAGE_PS_ALLOCATION alloc;
2029 struct _SET_VOLTAGE_PARAMETERS v1;
2030 struct _SET_VOLTAGE_PARAMETERS_V2 v2;
2031};
2032
2033void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level)
2034{
2035 union set_voltage args;
2036 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
2037 u8 frev, crev, volt_index = level;
2038
2039 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
2040 return;
2041
2042 switch (crev) {
2043 case 1:
2044 args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC;
2045 args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE;
2046 args.v1.ucVoltageIndex = volt_index;
2047 break;
2048 case 2:
2049 args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC;
2050 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;
2051 args.v2.usVoltageLevel = cpu_to_le16(level);
2052 break;
2053 default:
2054 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
2055 return;
2056 }
2057
2058 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2059}
2060
2061
2062
2001void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) 2063void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
2002{ 2064{
2003 struct radeon_device *rdev = dev->dev_private; 2065 struct radeon_device *rdev = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 7b5e10d3e9c9..102c744eaf5a 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -2454,7 +2454,12 @@ default_mode:
2454 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; 2454 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
2455 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; 2455 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
2456 rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; 2456 rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
2457 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; 2457 if ((state_index > 0) &&
2458 (rdev->pm.power_state[0].clock_info[0].voltage.type = VOLTAGE_GPIO))
2459 rdev->pm.power_state[state_index].clock_info[0].voltage =
2460 rdev->pm.power_state[0].clock_info[0].voltage;
2461 else
2462 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2458 rdev->pm.power_state[state_index].pcie_lanes = 16; 2463 rdev->pm.power_state[state_index].pcie_lanes = 16;
2459 rdev->pm.power_state[state_index].flags = 0; 2464 rdev->pm.power_state[state_index].flags = 0;
2460 rdev->pm.default_power_state_index = state_index; 2465 rdev->pm.default_power_state_index = state_index;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index fdc3fdf78acb..f10faed21567 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -546,8 +546,10 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
546 /* don't suspend or resume card normally */ 546 /* don't suspend or resume card normally */
547 rdev->powered_down = false; 547 rdev->powered_down = false;
548 radeon_resume_kms(dev); 548 radeon_resume_kms(dev);
549 drm_kms_helper_poll_enable(dev);
549 } else { 550 } else {
550 printk(KERN_INFO "radeon: switched off\n"); 551 printk(KERN_INFO "radeon: switched off\n");
552 drm_kms_helper_poll_disable(dev);
551 radeon_suspend_kms(dev, pmm); 553 radeon_suspend_kms(dev, pmm);
552 /* don't suspend or resume card normally */ 554 /* don't suspend or resume card normally */
553 rdev->powered_down = true; 555 rdev->powered_down = true;
@@ -711,6 +713,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
711{ 713{
712 struct radeon_device *rdev; 714 struct radeon_device *rdev;
713 struct drm_crtc *crtc; 715 struct drm_crtc *crtc;
716 struct drm_connector *connector;
714 int r; 717 int r;
715 718
716 if (dev == NULL || dev->dev_private == NULL) { 719 if (dev == NULL || dev->dev_private == NULL) {
@@ -723,6 +726,12 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
723 726
724 if (rdev->powered_down) 727 if (rdev->powered_down)
725 return 0; 728 return 0;
729
730 /* turn off display hw */
731 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
732 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
733 }
734
726 /* unpin the front buffers */ 735 /* unpin the front buffers */
727 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 736 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
728 struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); 737 struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index a8d162c6f829..02281269a881 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -151,6 +151,7 @@ static void radeon_sync_with_vblank(struct radeon_device *rdev)
151static void radeon_set_power_state(struct radeon_device *rdev) 151static void radeon_set_power_state(struct radeon_device *rdev)
152{ 152{
153 u32 sclk, mclk; 153 u32 sclk, mclk;
154 bool misc_after = false;
154 155
155 if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && 156 if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) &&
156 (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) 157 (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index))
@@ -167,55 +168,47 @@ static void radeon_set_power_state(struct radeon_device *rdev)
167 if (mclk > rdev->clock.default_mclk) 168 if (mclk > rdev->clock.default_mclk)
168 mclk = rdev->clock.default_mclk; 169 mclk = rdev->clock.default_mclk;
169 170
170 /* voltage, pcie lanes, etc.*/ 171 /* upvolt before raising clocks, downvolt after lowering clocks */
171 radeon_pm_misc(rdev); 172 if (sclk < rdev->pm.current_sclk)
173 misc_after = true;
172 174
173 if (rdev->pm.pm_method == PM_METHOD_DYNPM) { 175 radeon_sync_with_vblank(rdev);
174 radeon_sync_with_vblank(rdev);
175 176
177 if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
176 if (!radeon_pm_in_vbl(rdev)) 178 if (!radeon_pm_in_vbl(rdev))
177 return; 179 return;
180 }
178 181
179 radeon_pm_prepare(rdev); 182 radeon_pm_prepare(rdev);
180 /* set engine clock */
181 if (sclk != rdev->pm.current_sclk) {
182 radeon_pm_debug_check_in_vbl(rdev, false);
183 radeon_set_engine_clock(rdev, sclk);
184 radeon_pm_debug_check_in_vbl(rdev, true);
185 rdev->pm.current_sclk = sclk;
186 DRM_DEBUG("Setting: e: %d\n", sclk);
187 }
188 183
189 /* set memory clock */ 184 if (!misc_after)
190 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { 185 /* voltage, pcie lanes, etc.*/
191 radeon_pm_debug_check_in_vbl(rdev, false); 186 radeon_pm_misc(rdev);
192 radeon_set_memory_clock(rdev, mclk); 187
193 radeon_pm_debug_check_in_vbl(rdev, true); 188 /* set engine clock */
194 rdev->pm.current_mclk = mclk; 189 if (sclk != rdev->pm.current_sclk) {
195 DRM_DEBUG("Setting: m: %d\n", mclk); 190 radeon_pm_debug_check_in_vbl(rdev, false);
196 } 191 radeon_set_engine_clock(rdev, sclk);
197 radeon_pm_finish(rdev); 192 radeon_pm_debug_check_in_vbl(rdev, true);
198 } else { 193 rdev->pm.current_sclk = sclk;
199 /* set engine clock */ 194 DRM_DEBUG("Setting: e: %d\n", sclk);
200 if (sclk != rdev->pm.current_sclk) { 195 }
201 radeon_sync_with_vblank(rdev); 196
202 radeon_pm_prepare(rdev); 197 /* set memory clock */
203 radeon_set_engine_clock(rdev, sclk); 198 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
204 radeon_pm_finish(rdev); 199 radeon_pm_debug_check_in_vbl(rdev, false);
205 rdev->pm.current_sclk = sclk; 200 radeon_set_memory_clock(rdev, mclk);
206 DRM_DEBUG("Setting: e: %d\n", sclk); 201 radeon_pm_debug_check_in_vbl(rdev, true);
207 } 202 rdev->pm.current_mclk = mclk;
208 /* set memory clock */ 203 DRM_DEBUG("Setting: m: %d\n", mclk);
209 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
210 radeon_sync_with_vblank(rdev);
211 radeon_pm_prepare(rdev);
212 radeon_set_memory_clock(rdev, mclk);
213 radeon_pm_finish(rdev);
214 rdev->pm.current_mclk = mclk;
215 DRM_DEBUG("Setting: m: %d\n", mclk);
216 }
217 } 204 }
218 205
206 if (misc_after)
207 /* voltage, pcie lanes, etc.*/
208 radeon_pm_misc(rdev);
209
210 radeon_pm_finish(rdev);
211
219 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; 212 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
220 rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; 213 rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
221 } else 214 } else
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen
new file mode 100644
index 000000000000..b5c757f68d3c
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen
@@ -0,0 +1,611 @@
1evergreen 0x9400
20x00008040 WAIT_UNTIL
30x00008044 WAIT_UNTIL_POLL_CNTL
40x00008048 WAIT_UNTIL_POLL_MASK
50x0000804c WAIT_UNTIL_POLL_REFDATA
60x000088B0 VGT_VTX_VECT_EJECT_REG
70x000088C4 VGT_CACHE_INVALIDATION
80x000088D4 VGT_GS_VERTEX_REUSE
90x00008958 VGT_PRIMITIVE_TYPE
100x0000895C VGT_INDEX_TYPE
110x00008970 VGT_NUM_INDICES
120x00008974 VGT_NUM_INSTANCES
130x00008990 VGT_COMPUTE_DIM_X
140x00008994 VGT_COMPUTE_DIM_Y
150x00008998 VGT_COMPUTE_DIM_Z
160x0000899C VGT_COMPUTE_START_X
170x000089A0 VGT_COMPUTE_START_Y
180x000089A4 VGT_COMPUTE_START_Z
190x000089AC VGT_COMPUTE_THREAD_GOURP_SIZE
200x00008A14 PA_CL_ENHANCE
210x00008A60 PA_SC_LINE_STIPPLE_VALUE
220x00008B10 PA_SC_LINE_STIPPLE_STATE
230x00008BF0 PA_SC_ENHANCE
240x00008D8C SQ_DYN_GPR_CNTL_PS_FLUSH_REQ
250x00008C00 SQ_CONFIG
260x00008C04 SQ_GPR_RESOURCE_MGMT_1
270x00008C08 SQ_GPR_RESOURCE_MGMT_2
280x00008C0C SQ_GPR_RESOURCE_MGMT_3
290x00008C10 SQ_GLOBAL_GPR_RESOURCE_MGMT_1
300x00008C14 SQ_GLOBAL_GPR_RESOURCE_MGMT_2
310x00008C18 SQ_THREAD_RESOURCE_MGMT
320x00008C1C SQ_THREAD_RESOURCE_MGMT_2
330x00008C20 SQ_STACK_RESOURCE_MGMT_1
340x00008C24 SQ_STACK_RESOURCE_MGMT_2
350x00008C28 SQ_STACK_RESOURCE_MGMT_3
360x00008DF8 SQ_CONST_MEM_BASE
370x00008E48 SQ_EX_ALLOC_TABLE_SLOTS
380x00009100 SPI_CONFIG_CNTL
390x0000913C SPI_CONFIG_CNTL_1
400x00009700 VC_CNTL
410x00009714 VC_ENHANCE
420x00009830 DB_DEBUG
430x00009834 DB_DEBUG2
440x00009838 DB_DEBUG3
450x0000983C DB_DEBUG4
460x00009854 DB_WATERMARKS
470x0000A400 TD_PS_BORDER_COLOR_INDEX
480x0000A404 TD_PS_BORDER_COLOR_RED
490x0000A408 TD_PS_BORDER_COLOR_GREEN
500x0000A40C TD_PS_BORDER_COLOR_BLUE
510x0000A410 TD_PS_BORDER_COLOR_ALPHA
520x0000A414 TD_VS_BORDER_COLOR_INDEX
530x0000A418 TD_VS_BORDER_COLOR_RED
540x0000A41C TD_VS_BORDER_COLOR_GREEN
550x0000A420 TD_VS_BORDER_COLOR_BLUE
560x0000A424 TD_VS_BORDER_COLOR_ALPHA
570x0000A428 TD_GS_BORDER_COLOR_INDEX
580x0000A42C TD_GS_BORDER_COLOR_RED
590x0000A430 TD_GS_BORDER_COLOR_GREEN
600x0000A434 TD_GS_BORDER_COLOR_BLUE
610x0000A438 TD_GS_BORDER_COLOR_ALPHA
620x0000A43C TD_HS_BORDER_COLOR_INDEX
630x0000A440 TD_HS_BORDER_COLOR_RED
640x0000A444 TD_HS_BORDER_COLOR_GREEN
650x0000A448 TD_HS_BORDER_COLOR_BLUE
660x0000A44C TD_HS_BORDER_COLOR_ALPHA
670x0000A450 TD_LS_BORDER_COLOR_INDEX
680x0000A454 TD_LS_BORDER_COLOR_RED
690x0000A458 TD_LS_BORDER_COLOR_GREEN
700x0000A45C TD_LS_BORDER_COLOR_BLUE
710x0000A460 TD_LS_BORDER_COLOR_ALPHA
720x0000A464 TD_CS_BORDER_COLOR_INDEX
730x0000A468 TD_CS_BORDER_COLOR_RED
740x0000A46C TD_CS_BORDER_COLOR_GREEN
750x0000A470 TD_CS_BORDER_COLOR_BLUE
760x0000A474 TD_CS_BORDER_COLOR_ALPHA
770x00028000 DB_RENDER_CONTROL
780x00028004 DB_COUNT_CONTROL
790x0002800C DB_RENDER_OVERRIDE
800x00028010 DB_RENDER_OVERRIDE2
810x00028028 DB_STENCIL_CLEAR
820x0002802C DB_DEPTH_CLEAR
830x00028034 PA_SC_SCREEN_SCISSOR_BR
840x00028030 PA_SC_SCREEN_SCISSOR_TL
850x0002805C DB_DEPTH_SLICE
860x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
870x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
880x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
890x0002814C SQ_ALU_CONST_BUFFER_SIZE_PS_3
900x00028150 SQ_ALU_CONST_BUFFER_SIZE_PS_4
910x00028154 SQ_ALU_CONST_BUFFER_SIZE_PS_5
920x00028158 SQ_ALU_CONST_BUFFER_SIZE_PS_6
930x0002815C SQ_ALU_CONST_BUFFER_SIZE_PS_7
940x00028160 SQ_ALU_CONST_BUFFER_SIZE_PS_8
950x00028164 SQ_ALU_CONST_BUFFER_SIZE_PS_9
960x00028168 SQ_ALU_CONST_BUFFER_SIZE_PS_10
970x0002816C SQ_ALU_CONST_BUFFER_SIZE_PS_11
980x00028170 SQ_ALU_CONST_BUFFER_SIZE_PS_12
990x00028174 SQ_ALU_CONST_BUFFER_SIZE_PS_13
1000x00028178 SQ_ALU_CONST_BUFFER_SIZE_PS_14
1010x0002817C SQ_ALU_CONST_BUFFER_SIZE_PS_15
1020x00028180 SQ_ALU_CONST_BUFFER_SIZE_VS_0
1030x00028184 SQ_ALU_CONST_BUFFER_SIZE_VS_1
1040x00028188 SQ_ALU_CONST_BUFFER_SIZE_VS_2
1050x0002818C SQ_ALU_CONST_BUFFER_SIZE_VS_3
1060x00028190 SQ_ALU_CONST_BUFFER_SIZE_VS_4
1070x00028194 SQ_ALU_CONST_BUFFER_SIZE_VS_5
1080x00028198 SQ_ALU_CONST_BUFFER_SIZE_VS_6
1090x0002819C SQ_ALU_CONST_BUFFER_SIZE_VS_7
1100x000281A0 SQ_ALU_CONST_BUFFER_SIZE_VS_8
1110x000281A4 SQ_ALU_CONST_BUFFER_SIZE_VS_9
1120x000281A8 SQ_ALU_CONST_BUFFER_SIZE_VS_10
1130x000281AC SQ_ALU_CONST_BUFFER_SIZE_VS_11
1140x000281B0 SQ_ALU_CONST_BUFFER_SIZE_VS_12
1150x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13
1160x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14
1170x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15
1180x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0
1190x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1
1200x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2
1210x000281CC SQ_ALU_CONST_BUFFER_SIZE_GS_3
1220x000281D0 SQ_ALU_CONST_BUFFER_SIZE_GS_4
1230x000281D4 SQ_ALU_CONST_BUFFER_SIZE_GS_5
1240x000281D8 SQ_ALU_CONST_BUFFER_SIZE_GS_6
1250x000281DC SQ_ALU_CONST_BUFFER_SIZE_GS_7
1260x000281E0 SQ_ALU_CONST_BUFFER_SIZE_GS_8
1270x000281E4 SQ_ALU_CONST_BUFFER_SIZE_GS_9
1280x000281E8 SQ_ALU_CONST_BUFFER_SIZE_GS_10
1290x000281EC SQ_ALU_CONST_BUFFER_SIZE_GS_11
1300x000281F0 SQ_ALU_CONST_BUFFER_SIZE_GS_12
1310x000281F4 SQ_ALU_CONST_BUFFER_SIZE_GS_13
1320x000281F8 SQ_ALU_CONST_BUFFER_SIZE_GS_14
1330x000281FC SQ_ALU_CONST_BUFFER_SIZE_GS_15
1340x00028200 PA_SC_WINDOW_OFFSET
1350x00028204 PA_SC_WINDOW_SCISSOR_TL
1360x00028208 PA_SC_WINDOW_SCISSOR_BR
1370x0002820C PA_SC_CLIPRECT_RULE
1380x00028210 PA_SC_CLIPRECT_0_TL
1390x00028214 PA_SC_CLIPRECT_0_BR
1400x00028218 PA_SC_CLIPRECT_1_TL
1410x0002821C PA_SC_CLIPRECT_1_BR
1420x00028220 PA_SC_CLIPRECT_2_TL
1430x00028224 PA_SC_CLIPRECT_2_BR
1440x00028228 PA_SC_CLIPRECT_3_TL
1450x0002822C PA_SC_CLIPRECT_3_BR
1460x00028230 PA_SC_EDGERULE
1470x00028234 PA_SU_HARDWARE_SCREEN_OFFSET
1480x00028240 PA_SC_GENERIC_SCISSOR_TL
1490x00028244 PA_SC_GENERIC_SCISSOR_BR
1500x00028250 PA_SC_VPORT_SCISSOR_0_TL
1510x00028254 PA_SC_VPORT_SCISSOR_0_BR
1520x00028258 PA_SC_VPORT_SCISSOR_1_TL
1530x0002825C PA_SC_VPORT_SCISSOR_1_BR
1540x00028260 PA_SC_VPORT_SCISSOR_2_TL
1550x00028264 PA_SC_VPORT_SCISSOR_2_BR
1560x00028268 PA_SC_VPORT_SCISSOR_3_TL
1570x0002826C PA_SC_VPORT_SCISSOR_3_BR
1580x00028270 PA_SC_VPORT_SCISSOR_4_TL
1590x00028274 PA_SC_VPORT_SCISSOR_4_BR
1600x00028278 PA_SC_VPORT_SCISSOR_5_TL
1610x0002827C PA_SC_VPORT_SCISSOR_5_BR
1620x00028280 PA_SC_VPORT_SCISSOR_6_TL
1630x00028284 PA_SC_VPORT_SCISSOR_6_BR
1640x00028288 PA_SC_VPORT_SCISSOR_7_TL
1650x0002828C PA_SC_VPORT_SCISSOR_7_BR
1660x00028290 PA_SC_VPORT_SCISSOR_8_TL
1670x00028294 PA_SC_VPORT_SCISSOR_8_BR
1680x00028298 PA_SC_VPORT_SCISSOR_9_TL
1690x0002829C PA_SC_VPORT_SCISSOR_9_BR
1700x000282A0 PA_SC_VPORT_SCISSOR_10_TL
1710x000282A4 PA_SC_VPORT_SCISSOR_10_BR
1720x000282A8 PA_SC_VPORT_SCISSOR_11_TL
1730x000282AC PA_SC_VPORT_SCISSOR_11_BR
1740x000282B0 PA_SC_VPORT_SCISSOR_12_TL
1750x000282B4 PA_SC_VPORT_SCISSOR_12_BR
1760x000282B8 PA_SC_VPORT_SCISSOR_13_TL
1770x000282BC PA_SC_VPORT_SCISSOR_13_BR
1780x000282C0 PA_SC_VPORT_SCISSOR_14_TL
1790x000282C4 PA_SC_VPORT_SCISSOR_14_BR
1800x000282C8 PA_SC_VPORT_SCISSOR_15_TL
1810x000282CC PA_SC_VPORT_SCISSOR_15_BR
1820x000282D0 PA_SC_VPORT_ZMIN_0
1830x000282D4 PA_SC_VPORT_ZMAX_0
1840x000282D8 PA_SC_VPORT_ZMIN_1
1850x000282DC PA_SC_VPORT_ZMAX_1
1860x000282E0 PA_SC_VPORT_ZMIN_2
1870x000282E4 PA_SC_VPORT_ZMAX_2
1880x000282E8 PA_SC_VPORT_ZMIN_3
1890x000282EC PA_SC_VPORT_ZMAX_3
1900x000282F0 PA_SC_VPORT_ZMIN_4
1910x000282F4 PA_SC_VPORT_ZMAX_4
1920x000282F8 PA_SC_VPORT_ZMIN_5
1930x000282FC PA_SC_VPORT_ZMAX_5
1940x00028300 PA_SC_VPORT_ZMIN_6
1950x00028304 PA_SC_VPORT_ZMAX_6
1960x00028308 PA_SC_VPORT_ZMIN_7
1970x0002830C PA_SC_VPORT_ZMAX_7
1980x00028310 PA_SC_VPORT_ZMIN_8
1990x00028314 PA_SC_VPORT_ZMAX_8
2000x00028318 PA_SC_VPORT_ZMIN_9
2010x0002831C PA_SC_VPORT_ZMAX_9
2020x00028320 PA_SC_VPORT_ZMIN_10
2030x00028324 PA_SC_VPORT_ZMAX_10
2040x00028328 PA_SC_VPORT_ZMIN_11
2050x0002832C PA_SC_VPORT_ZMAX_11
2060x00028330 PA_SC_VPORT_ZMIN_12
2070x00028334 PA_SC_VPORT_ZMAX_12
2080x00028338 PA_SC_VPORT_ZMIN_13
2090x0002833C PA_SC_VPORT_ZMAX_13
2100x00028340 PA_SC_VPORT_ZMIN_14
2110x00028344 PA_SC_VPORT_ZMAX_14
2120x00028348 PA_SC_VPORT_ZMIN_15
2130x0002834C PA_SC_VPORT_ZMAX_15
2140x00028350 SX_MISC
2150x00028380 SQ_VTX_SEMANTIC_0
2160x00028384 SQ_VTX_SEMANTIC_1
2170x00028388 SQ_VTX_SEMANTIC_2
2180x0002838C SQ_VTX_SEMANTIC_3
2190x00028390 SQ_VTX_SEMANTIC_4
2200x00028394 SQ_VTX_SEMANTIC_5
2210x00028398 SQ_VTX_SEMANTIC_6
2220x0002839C SQ_VTX_SEMANTIC_7
2230x000283A0 SQ_VTX_SEMANTIC_8
2240x000283A4 SQ_VTX_SEMANTIC_9
2250x000283A8 SQ_VTX_SEMANTIC_10
2260x000283AC SQ_VTX_SEMANTIC_11
2270x000283B0 SQ_VTX_SEMANTIC_12
2280x000283B4 SQ_VTX_SEMANTIC_13
2290x000283B8 SQ_VTX_SEMANTIC_14
2300x000283BC SQ_VTX_SEMANTIC_15
2310x000283C0 SQ_VTX_SEMANTIC_16
2320x000283C4 SQ_VTX_SEMANTIC_17
2330x000283C8 SQ_VTX_SEMANTIC_18
2340x000283CC SQ_VTX_SEMANTIC_19
2350x000283D0 SQ_VTX_SEMANTIC_20
2360x000283D4 SQ_VTX_SEMANTIC_21
2370x000283D8 SQ_VTX_SEMANTIC_22
2380x000283DC SQ_VTX_SEMANTIC_23
2390x000283E0 SQ_VTX_SEMANTIC_24
2400x000283E4 SQ_VTX_SEMANTIC_25
2410x000283E8 SQ_VTX_SEMANTIC_26
2420x000283EC SQ_VTX_SEMANTIC_27
2430x000283F0 SQ_VTX_SEMANTIC_28
2440x000283F4 SQ_VTX_SEMANTIC_29
2450x000283F8 SQ_VTX_SEMANTIC_30
2460x000283FC SQ_VTX_SEMANTIC_31
2470x00028400 VGT_MAX_VTX_INDX
2480x00028404 VGT_MIN_VTX_INDX
2490x00028408 VGT_INDX_OFFSET
2500x0002840C VGT_MULTI_PRIM_IB_RESET_INDX
2510x00028410 SX_ALPHA_TEST_CONTROL
2520x00028414 CB_BLEND_RED
2530x00028418 CB_BLEND_GREEN
2540x0002841C CB_BLEND_BLUE
2550x00028420 CB_BLEND_ALPHA
2560x00028430 DB_STENCILREFMASK
2570x00028434 DB_STENCILREFMASK_BF
2580x00028438 SX_ALPHA_REF
2590x0002843C PA_CL_VPORT_XSCALE_0
2600x00028440 PA_CL_VPORT_XOFFSET_0
2610x00028444 PA_CL_VPORT_YSCALE_0
2620x00028448 PA_CL_VPORT_YOFFSET_0
2630x0002844C PA_CL_VPORT_ZSCALE_0
2640x00028450 PA_CL_VPORT_ZOFFSET_0
2650x00028454 PA_CL_VPORT_XSCALE_1
2660x00028458 PA_CL_VPORT_XOFFSET_1
2670x0002845C PA_CL_VPORT_YSCALE_1
2680x00028460 PA_CL_VPORT_YOFFSET_1
2690x00028464 PA_CL_VPORT_ZSCALE_1
2700x00028468 PA_CL_VPORT_ZOFFSET_1
2710x0002846C PA_CL_VPORT_XSCALE_2
2720x00028470 PA_CL_VPORT_XOFFSET_2
2730x00028474 PA_CL_VPORT_YSCALE_2
2740x00028478 PA_CL_VPORT_YOFFSET_2
2750x0002847C PA_CL_VPORT_ZSCALE_2
2760x00028480 PA_CL_VPORT_ZOFFSET_2
2770x00028484 PA_CL_VPORT_XSCALE_3
2780x00028488 PA_CL_VPORT_XOFFSET_3
2790x0002848C PA_CL_VPORT_YSCALE_3
2800x00028490 PA_CL_VPORT_YOFFSET_3
2810x00028494 PA_CL_VPORT_ZSCALE_3
2820x00028498 PA_CL_VPORT_ZOFFSET_3
2830x0002849C PA_CL_VPORT_XSCALE_4
2840x000284A0 PA_CL_VPORT_XOFFSET_4
2850x000284A4 PA_CL_VPORT_YSCALE_4
2860x000284A8 PA_CL_VPORT_YOFFSET_4
2870x000284AC PA_CL_VPORT_ZSCALE_4
2880x000284B0 PA_CL_VPORT_ZOFFSET_4
2890x000284B4 PA_CL_VPORT_XSCALE_5
2900x000284B8 PA_CL_VPORT_XOFFSET_5
2910x000284BC PA_CL_VPORT_YSCALE_5
2920x000284C0 PA_CL_VPORT_YOFFSET_5
2930x000284C4 PA_CL_VPORT_ZSCALE_5
2940x000284C8 PA_CL_VPORT_ZOFFSET_5
2950x000284CC PA_CL_VPORT_XSCALE_6
2960x000284D0 PA_CL_VPORT_XOFFSET_6
2970x000284D4 PA_CL_VPORT_YSCALE_6
2980x000284D8 PA_CL_VPORT_YOFFSET_6
2990x000284DC PA_CL_VPORT_ZSCALE_6
3000x000284E0 PA_CL_VPORT_ZOFFSET_6
3010x000284E4 PA_CL_VPORT_XSCALE_7
3020x000284E8 PA_CL_VPORT_XOFFSET_7
3030x000284EC PA_CL_VPORT_YSCALE_7
3040x000284F0 PA_CL_VPORT_YOFFSET_7
3050x000284F4 PA_CL_VPORT_ZSCALE_7
3060x000284F8 PA_CL_VPORT_ZOFFSET_7
3070x000284FC PA_CL_VPORT_XSCALE_8
3080x00028500 PA_CL_VPORT_XOFFSET_8
3090x00028504 PA_CL_VPORT_YSCALE_8
3100x00028508 PA_CL_VPORT_YOFFSET_8
3110x0002850C PA_CL_VPORT_ZSCALE_8
3120x00028510 PA_CL_VPORT_ZOFFSET_8
3130x00028514 PA_CL_VPORT_XSCALE_9
3140x00028518 PA_CL_VPORT_XOFFSET_9
3150x0002851C PA_CL_VPORT_YSCALE_9
3160x00028520 PA_CL_VPORT_YOFFSET_9
3170x00028524 PA_CL_VPORT_ZSCALE_9
3180x00028528 PA_CL_VPORT_ZOFFSET_9
3190x0002852C PA_CL_VPORT_XSCALE_10
3200x00028530 PA_CL_VPORT_XOFFSET_10
3210x00028534 PA_CL_VPORT_YSCALE_10
3220x00028538 PA_CL_VPORT_YOFFSET_10
3230x0002853C PA_CL_VPORT_ZSCALE_10
3240x00028540 PA_CL_VPORT_ZOFFSET_10
3250x00028544 PA_CL_VPORT_XSCALE_11
3260x00028548 PA_CL_VPORT_XOFFSET_11
3270x0002854C PA_CL_VPORT_YSCALE_11
3280x00028550 PA_CL_VPORT_YOFFSET_11
3290x00028554 PA_CL_VPORT_ZSCALE_11
3300x00028558 PA_CL_VPORT_ZOFFSET_11
3310x0002855C PA_CL_VPORT_XSCALE_12
3320x00028560 PA_CL_VPORT_XOFFSET_12
3330x00028564 PA_CL_VPORT_YSCALE_12
3340x00028568 PA_CL_VPORT_YOFFSET_12
3350x0002856C PA_CL_VPORT_ZSCALE_12
3360x00028570 PA_CL_VPORT_ZOFFSET_12
3370x00028574 PA_CL_VPORT_XSCALE_13
3380x00028578 PA_CL_VPORT_XOFFSET_13
3390x0002857C PA_CL_VPORT_YSCALE_13
3400x00028580 PA_CL_VPORT_YOFFSET_13
3410x00028584 PA_CL_VPORT_ZSCALE_13
3420x00028588 PA_CL_VPORT_ZOFFSET_13
3430x0002858C PA_CL_VPORT_XSCALE_14
3440x00028590 PA_CL_VPORT_XOFFSET_14
3450x00028594 PA_CL_VPORT_YSCALE_14
3460x00028598 PA_CL_VPORT_YOFFSET_14
3470x0002859C PA_CL_VPORT_ZSCALE_14
3480x000285A0 PA_CL_VPORT_ZOFFSET_14
3490x000285A4 PA_CL_VPORT_XSCALE_15
3500x000285A8 PA_CL_VPORT_XOFFSET_15
3510x000285AC PA_CL_VPORT_YSCALE_15
3520x000285B0 PA_CL_VPORT_YOFFSET_15
3530x000285B4 PA_CL_VPORT_ZSCALE_15
3540x000285B8 PA_CL_VPORT_ZOFFSET_15
3550x000285BC PA_CL_UCP_0_X
3560x000285C0 PA_CL_UCP_0_Y
3570x000285C4 PA_CL_UCP_0_Z
3580x000285C8 PA_CL_UCP_0_W
3590x000285CC PA_CL_UCP_1_X
3600x000285D0 PA_CL_UCP_1_Y
3610x000285D4 PA_CL_UCP_1_Z
3620x000285D8 PA_CL_UCP_1_W
3630x000285DC PA_CL_UCP_2_X
3640x000285E0 PA_CL_UCP_2_Y
3650x000285E4 PA_CL_UCP_2_Z
3660x000285E8 PA_CL_UCP_2_W
3670x000285EC PA_CL_UCP_3_X
3680x000285F0 PA_CL_UCP_3_Y
3690x000285F4 PA_CL_UCP_3_Z
3700x000285F8 PA_CL_UCP_3_W
3710x000285FC PA_CL_UCP_4_X
3720x00028600 PA_CL_UCP_4_Y
3730x00028604 PA_CL_UCP_4_Z
3740x00028608 PA_CL_UCP_4_W
3750x0002860C PA_CL_UCP_5_X
3760x00028610 PA_CL_UCP_5_Y
3770x00028614 PA_CL_UCP_5_Z
3780x00028618 PA_CL_UCP_5_W
3790x0002861C SPI_VS_OUT_ID_0
3800x00028620 SPI_VS_OUT_ID_1
3810x00028624 SPI_VS_OUT_ID_2
3820x00028628 SPI_VS_OUT_ID_3
3830x0002862C SPI_VS_OUT_ID_4
3840x00028630 SPI_VS_OUT_ID_5
3850x00028634 SPI_VS_OUT_ID_6
3860x00028638 SPI_VS_OUT_ID_7
3870x0002863C SPI_VS_OUT_ID_8
3880x00028640 SPI_VS_OUT_ID_9
3890x00028644 SPI_PS_INPUT_CNTL_0
3900x00028648 SPI_PS_INPUT_CNTL_1
3910x0002864C SPI_PS_INPUT_CNTL_2
3920x00028650 SPI_PS_INPUT_CNTL_3
3930x00028654 SPI_PS_INPUT_CNTL_4
3940x00028658 SPI_PS_INPUT_CNTL_5
3950x0002865C SPI_PS_INPUT_CNTL_6
3960x00028660 SPI_PS_INPUT_CNTL_7
3970x00028664 SPI_PS_INPUT_CNTL_8
3980x00028668 SPI_PS_INPUT_CNTL_9
3990x0002866C SPI_PS_INPUT_CNTL_10
4000x00028670 SPI_PS_INPUT_CNTL_11
4010x00028674 SPI_PS_INPUT_CNTL_12
4020x00028678 SPI_PS_INPUT_CNTL_13
4030x0002867C SPI_PS_INPUT_CNTL_14
4040x00028680 SPI_PS_INPUT_CNTL_15
4050x00028684 SPI_PS_INPUT_CNTL_16
4060x00028688 SPI_PS_INPUT_CNTL_17
4070x0002868C SPI_PS_INPUT_CNTL_18
4080x00028690 SPI_PS_INPUT_CNTL_19
4090x00028694 SPI_PS_INPUT_CNTL_20
4100x00028698 SPI_PS_INPUT_CNTL_21
4110x0002869C SPI_PS_INPUT_CNTL_22
4120x000286A0 SPI_PS_INPUT_CNTL_23
4130x000286A4 SPI_PS_INPUT_CNTL_24
4140x000286A8 SPI_PS_INPUT_CNTL_25
4150x000286AC SPI_PS_INPUT_CNTL_26
4160x000286B0 SPI_PS_INPUT_CNTL_27
4170x000286B4 SPI_PS_INPUT_CNTL_28
4180x000286B8 SPI_PS_INPUT_CNTL_29
4190x000286BC SPI_PS_INPUT_CNTL_30
4200x000286C0 SPI_PS_INPUT_CNTL_31
4210x000286C4 SPI_VS_OUT_CONFIG
4220x000286C8 SPI_THREAD_GROUPING
4230x000286CC SPI_PS_IN_CONTROL_0
4240x000286D0 SPI_PS_IN_CONTROL_1
4250x000286D4 SPI_INTERP_CONTROL_0
4260x000286D8 SPI_INPUT_Z
4270x000286DC SPI_FOG_CNTL
4280x000286E0 SPI_BARYC_CNTL
4290x000286E4 SPI_PS_IN_CONTROL_2
4300x000286E8 SPI_COMPUTE_INPUT_CNTL
4310x000286EC SPI_COMPUTE_NUM_THREAD_X
4320x000286F0 SPI_COMPUTE_NUM_THREAD_Y
4330x000286F4 SPI_COMPUTE_NUM_THREAD_Z
4340x000286F8 GDS_ADDR_SIZE
4350x00028780 CB_BLEND0_CONTROL
4360x00028784 CB_BLEND1_CONTROL
4370x00028788 CB_BLEND2_CONTROL
4380x0002878C CB_BLEND3_CONTROL
4390x00028790 CB_BLEND4_CONTROL
4400x00028794 CB_BLEND5_CONTROL
4410x00028798 CB_BLEND6_CONTROL
4420x0002879C CB_BLEND7_CONTROL
4430x000287CC CS_COPY_STATE
4440x000287D0 GFX_COPY_STATE
4450x000287D4 PA_CL_POINT_X_RAD
4460x000287D8 PA_CL_POINT_Y_RAD
4470x000287DC PA_CL_POINT_SIZE
4480x000287E0 PA_CL_POINT_CULL_RAD
4490x00028808 CB_COLOR_CONTROL
4500x0002880C DB_SHADER_CONTROL
4510x00028810 PA_CL_CLIP_CNTL
4520x00028814 PA_SU_SC_MODE_CNTL
4530x00028818 PA_CL_VTE_CNTL
4540x0002881C PA_CL_VS_OUT_CNTL
4550x00028820 PA_CL_NANINF_CNTL
4560x00028824 PA_SU_LINE_STIPPLE_CNTL
4570x00028828 PA_SU_LINE_STIPPLE_SCALE
4580x0002882C PA_SU_PRIM_FILTER_CNTL
4590x00028838 SQ_DYN_GPR_RESOURCE_LIMIT_1
4600x00028844 SQ_PGM_RESOURCES_PS
4610x00028848 SQ_PGM_RESOURCES_2_PS
4620x0002884C SQ_PGM_EXPORTS_PS
4630x0002885C SQ_PGM_RESOURCES_VS
4640x00028860 SQ_PGM_RESOURCES_2_VS
4650x00028878 SQ_PGM_RESOURCES_GS
4660x0002887C SQ_PGM_RESOURCES_2_GS
4670x00028890 SQ_PGM_RESOURCES_ES
4680x00028894 SQ_PGM_RESOURCES_2_ES
4690x000288A8 SQ_PGM_RESOURCES_FS
4700x000288BC SQ_PGM_RESOURCES_HS
4710x000288C0 SQ_PGM_RESOURCES_2_HS
4720x000288D0 SQ_PGM_RESOURCES_LS
4730x000288D4 SQ_PGM_RESOURCES_2_LS
4740x000288E8 SQ_LDS_ALLOC
4750x000288EC SQ_LDS_ALLOC_PS
4760x000288F0 SQ_VTX_SEMANTIC_CLEAR
4770x00028A00 PA_SU_POINT_SIZE
4780x00028A04 PA_SU_POINT_MINMAX
4790x00028A08 PA_SU_LINE_CNTL
4800x00028A0C PA_SC_LINE_STIPPLE
4810x00028A10 VGT_OUTPUT_PATH_CNTL
4820x00028A14 VGT_HOS_CNTL
4830x00028A18 VGT_HOS_MAX_TESS_LEVEL
4840x00028A1C VGT_HOS_MIN_TESS_LEVEL
4850x00028A20 VGT_HOS_REUSE_DEPTH
4860x00028A24 VGT_GROUP_PRIM_TYPE
4870x00028A28 VGT_GROUP_FIRST_DECR
4880x00028A2C VGT_GROUP_DECR
4890x00028A30 VGT_GROUP_VECT_0_CNTL
4900x00028A34 VGT_GROUP_VECT_1_CNTL
4910x00028A38 VGT_GROUP_VECT_0_FMT_CNTL
4920x00028A3C VGT_GROUP_VECT_1_FMT_CNTL
4930x00028A40 VGT_GS_MODE
4940x00028A48 PA_SC_MODE_CNTL_0
4950x00028A4C PA_SC_MODE_CNTL_1
4960x00028A50 VGT_ENHANCE
4970x00028A54 VGT_GS_PER_ES
4980x00028A58 VGT_ES_PER_GS
4990x00028A5C VGT_GS_PER_VS
5000x00028A6C VGT_GS_OUT_PRIM_TYPE
5010x00028A84 VGT_PRIMITIVEID_EN
5020x00028A94 VGT_MULTI_PRIM_IB_RESET_EN
5030x00028AA0 VGT_INSTANCE_STEP_RATE_0
5040x00028AA4 VGT_INSTANCE_STEP_RATE_1
5050x00028AB4 VGT_REUSE_OFF
5060x00028AB8 VGT_VTX_CNT_EN
5070x00028ABC DB_HTILE_SURFACE
5080x00028AC0 DB_SRESULTS_COMPARE_STATE0
5090x00028AC4 DB_SRESULTS_COMPARE_STATE1
5100x00028AC8 DB_PRELOAD_CONTROL
5110x00028B38 VGT_GS_MAX_VERT_OUT
5120x00028B54 VGT_SHADER_STAGES_EN
5130x00028B58 VGT_LS_HS_CONFIG
5140x00028B5C VGT_LS_SIZE
5150x00028B60 VGT_HS_SIZE
5160x00028B64 VGT_LS_HS_ALLOC
5170x00028B68 VGT_HS_PATCH_CONST
5180x00028B6C VGT_TF_PARAM
5190x00028B70 DB_ALPHA_TO_MASK
5200x00028B74 VGT_DISPATCH_INITIATOR
5210x00028B78 PA_SU_POLY_OFFSET_DB_FMT_CNTL
5220x00028B7C PA_SU_POLY_OFFSET_CLAMP
5230x00028B80 PA_SU_POLY_OFFSET_FRONT_SCALE
5240x00028B84 PA_SU_POLY_OFFSET_FRONT_OFFSET
5250x00028B88 PA_SU_POLY_OFFSET_BACK_SCALE
5260x00028B8C PA_SU_POLY_OFFSET_BACK_OFFSET
5270x00028B74 VGT_GS_INSTANCE_CNT
5280x00028C00 PA_SC_LINE_CNTL
5290x00028C08 PA_SU_VTX_CNTL
5300x00028C0C PA_CL_GB_VERT_CLIP_ADJ
5310x00028C10 PA_CL_GB_VERT_DISC_ADJ
5320x00028C14 PA_CL_GB_HORZ_CLIP_ADJ
5330x00028C18 PA_CL_GB_HORZ_DISC_ADJ
5340x00028C1C PA_SC_AA_SAMPLE_LOCS_0
5350x00028C20 PA_SC_AA_SAMPLE_LOCS_1
5360x00028C24 PA_SC_AA_SAMPLE_LOCS_2
5370x00028C28 PA_SC_AA_SAMPLE_LOCS_3
5380x00028C2C PA_SC_AA_SAMPLE_LOCS_4
5390x00028C30 PA_SC_AA_SAMPLE_LOCS_5
5400x00028C34 PA_SC_AA_SAMPLE_LOCS_6
5410x00028C38 PA_SC_AA_SAMPLE_LOCS_7
5420x00028C3C PA_SC_AA_MASK
5430x00028C8C CB_COLOR0_CLEAR_WORD0
5440x00028C90 CB_COLOR0_CLEAR_WORD1
5450x00028C94 CB_COLOR0_CLEAR_WORD2
5460x00028C98 CB_COLOR0_CLEAR_WORD3
5470x00028CC8 CB_COLOR1_CLEAR_WORD0
5480x00028CCC CB_COLOR1_CLEAR_WORD1
5490x00028CD0 CB_COLOR1_CLEAR_WORD2
5500x00028CD4 CB_COLOR1_CLEAR_WORD3
5510x00028D04 CB_COLOR2_CLEAR_WORD0
5520x00028D08 CB_COLOR2_CLEAR_WORD1
5530x00028D0C CB_COLOR2_CLEAR_WORD2
5540x00028D10 CB_COLOR2_CLEAR_WORD3
5550x00028D40 CB_COLOR3_CLEAR_WORD0
5560x00028D44 CB_COLOR3_CLEAR_WORD1
5570x00028D48 CB_COLOR3_CLEAR_WORD2
5580x00028D4C CB_COLOR3_CLEAR_WORD3
5590x00028D7C CB_COLOR4_CLEAR_WORD0
5600x00028D80 CB_COLOR4_CLEAR_WORD1
5610x00028D84 CB_COLOR4_CLEAR_WORD2
5620x00028D88 CB_COLOR4_CLEAR_WORD3
5630x00028DB8 CB_COLOR5_CLEAR_WORD0
5640x00028DBC CB_COLOR5_CLEAR_WORD1
5650x00028DC0 CB_COLOR5_CLEAR_WORD2
5660x00028DC4 CB_COLOR5_CLEAR_WORD3
5670x00028DF4 CB_COLOR6_CLEAR_WORD0
5680x00028DF8 CB_COLOR6_CLEAR_WORD1
5690x00028DFC CB_COLOR6_CLEAR_WORD2
5700x00028E00 CB_COLOR6_CLEAR_WORD3
5710x00028E30 CB_COLOR7_CLEAR_WORD0
5720x00028E34 CB_COLOR7_CLEAR_WORD1
5730x00028E38 CB_COLOR7_CLEAR_WORD2
5740x00028E3C CB_COLOR7_CLEAR_WORD3
5750x00028F80 SQ_ALU_CONST_BUFFER_SIZE_HS_0
5760x00028F84 SQ_ALU_CONST_BUFFER_SIZE_HS_1
5770x00028F88 SQ_ALU_CONST_BUFFER_SIZE_HS_2
5780x00028F8C SQ_ALU_CONST_BUFFER_SIZE_HS_3
5790x00028F90 SQ_ALU_CONST_BUFFER_SIZE_HS_4
5800x00028F94 SQ_ALU_CONST_BUFFER_SIZE_HS_5
5810x00028F98 SQ_ALU_CONST_BUFFER_SIZE_HS_6
5820x00028F9C SQ_ALU_CONST_BUFFER_SIZE_HS_7
5830x00028FA0 SQ_ALU_CONST_BUFFER_SIZE_HS_8
5840x00028FA4 SQ_ALU_CONST_BUFFER_SIZE_HS_9
5850x00028FA8 SQ_ALU_CONST_BUFFER_SIZE_HS_10
5860x00028FAC SQ_ALU_CONST_BUFFER_SIZE_HS_11
5870x00028FB0 SQ_ALU_CONST_BUFFER_SIZE_HS_12
5880x00028FB4 SQ_ALU_CONST_BUFFER_SIZE_HS_13
5890x00028FB8 SQ_ALU_CONST_BUFFER_SIZE_HS_14
5900x00028FBC SQ_ALU_CONST_BUFFER_SIZE_HS_15
5910x00028FC0 SQ_ALU_CONST_BUFFER_SIZE_LS_0
5920x00028FC4 SQ_ALU_CONST_BUFFER_SIZE_LS_1
5930x00028FC8 SQ_ALU_CONST_BUFFER_SIZE_LS_2
5940x00028FCC SQ_ALU_CONST_BUFFER_SIZE_LS_3
5950x00028FD0 SQ_ALU_CONST_BUFFER_SIZE_LS_4
5960x00028FD4 SQ_ALU_CONST_BUFFER_SIZE_LS_5
5970x00028FD8 SQ_ALU_CONST_BUFFER_SIZE_LS_6
5980x00028FDC SQ_ALU_CONST_BUFFER_SIZE_LS_7
5990x00028FE0 SQ_ALU_CONST_BUFFER_SIZE_LS_8
6000x00028FE4 SQ_ALU_CONST_BUFFER_SIZE_LS_9
6010x00028FE8 SQ_ALU_CONST_BUFFER_SIZE_LS_10
6020x00028FEC SQ_ALU_CONST_BUFFER_SIZE_LS_11
6030x00028FF0 SQ_ALU_CONST_BUFFER_SIZE_LS_12
6040x00028FF4 SQ_ALU_CONST_BUFFER_SIZE_LS_13
6050x00028FF8 SQ_ALU_CONST_BUFFER_SIZE_LS_14
6060x00028FFC SQ_ALU_CONST_BUFFER_SIZE_LS_15
6070x0003CFF0 SQ_VTX_BASE_VTX_LOC
6080x0003CFF4 SQ_VTX_START_INST_LOC
6090x0003FF00 SQ_TEX_SAMPLER_CLEAR
6100x0003FF04 SQ_TEX_RESOURCE_CLEAR
6110x0003FF08 SQ_LOOP_BOOL_CLEAR
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 79887cac5b54..7bb4c3e52f3b 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -74,7 +74,8 @@ void rs600_pm_misc(struct radeon_device *rdev)
74 if (voltage->delay) 74 if (voltage->delay)
75 udelay(voltage->delay); 75 udelay(voltage->delay);
76 } 76 }
77 } 77 } else if (voltage->type == VOLTAGE_VDDC)
78 radeon_atom_set_voltage(rdev, voltage->vddc_id);
78 79
79 dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); 80 dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH);
80 dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf); 81 dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 253f24aec031..33952da65340 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -44,7 +44,12 @@ void rv770_fini(struct radeon_device *rdev);
44 44
45void rv770_pm_misc(struct radeon_device *rdev) 45void rv770_pm_misc(struct radeon_device *rdev)
46{ 46{
47 int requested_index = rdev->pm.requested_power_state_index;
48 struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
49 struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
47 50
51 if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
52 radeon_atom_set_voltage(rdev, voltage->voltage);
48} 53}
49 54
50/* 55/*
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 0d9a42c2394f..ef910694bd63 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -77,7 +77,7 @@ struct ttm_page_pool {
77/** 77/**
78 * Limits for the pool. They are handled without locks because only place where 78 * Limits for the pool. They are handled without locks because only place where
79 * they may change is in sysfs store. They won't have immediate effect anyway 79 * they may change is in sysfs store. They won't have immediate effect anyway
80 * so forcing serialiazation to access them is pointless. 80 * so forcing serialization to access them is pointless.
81 */ 81 */
82 82
83struct ttm_pool_opts { 83struct ttm_pool_opts {
@@ -165,16 +165,18 @@ static ssize_t ttm_pool_store(struct kobject *kobj,
165 m->options.small = val; 165 m->options.small = val;
166 else if (attr == &ttm_page_pool_alloc_size) { 166 else if (attr == &ttm_page_pool_alloc_size) {
167 if (val > NUM_PAGES_TO_ALLOC*8) { 167 if (val > NUM_PAGES_TO_ALLOC*8) {
168 printk(KERN_ERR "[ttm] Setting allocation size to %lu " 168 printk(KERN_ERR TTM_PFX
169 "is not allowed. Recomended size is " 169 "Setting allocation size to %lu "
170 "%lu\n", 170 "is not allowed. Recommended size is "
171 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7), 171 "%lu\n",
172 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10)); 172 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7),
173 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
173 return size; 174 return size;
174 } else if (val > NUM_PAGES_TO_ALLOC) { 175 } else if (val > NUM_PAGES_TO_ALLOC) {
175 printk(KERN_WARNING "[ttm] Setting allocation size to " 176 printk(KERN_WARNING TTM_PFX
176 "larger than %lu is not recomended.\n", 177 "Setting allocation size to "
177 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10)); 178 "larger than %lu is not recommended.\n",
179 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
178 } 180 }
179 m->options.alloc_size = val; 181 m->options.alloc_size = val;
180 } 182 }
@@ -277,7 +279,7 @@ static void ttm_pages_put(struct page *pages[], unsigned npages)
277{ 279{
278 unsigned i; 280 unsigned i;
279 if (set_pages_array_wb(pages, npages)) 281 if (set_pages_array_wb(pages, npages))
280 printk(KERN_ERR "[ttm] Failed to set %d pages to wb!\n", 282 printk(KERN_ERR TTM_PFX "Failed to set %d pages to wb!\n",
281 npages); 283 npages);
282 for (i = 0; i < npages; ++i) 284 for (i = 0; i < npages; ++i)
283 __free_page(pages[i]); 285 __free_page(pages[i]);
@@ -313,7 +315,8 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
313 pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), 315 pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
314 GFP_KERNEL); 316 GFP_KERNEL);
315 if (!pages_to_free) { 317 if (!pages_to_free) {
316 printk(KERN_ERR "Failed to allocate memory for pool free operation.\n"); 318 printk(KERN_ERR TTM_PFX
319 "Failed to allocate memory for pool free operation.\n");
317 return 0; 320 return 0;
318 } 321 }
319 322
@@ -390,7 +393,7 @@ static int ttm_pool_get_num_unused_pages(void)
390} 393}
391 394
392/** 395/**
393 * Calback for mm to request pool to reduce number of page held. 396 * Callback for mm to request pool to reduce number of page held.
394 */ 397 */
395static int ttm_pool_mm_shrink(int shrink_pages, gfp_t gfp_mask) 398static int ttm_pool_mm_shrink(int shrink_pages, gfp_t gfp_mask)
396{ 399{
@@ -433,14 +436,16 @@ static int ttm_set_pages_caching(struct page **pages,
433 case tt_uncached: 436 case tt_uncached:
434 r = set_pages_array_uc(pages, cpages); 437 r = set_pages_array_uc(pages, cpages);
435 if (r) 438 if (r)
436 printk(KERN_ERR "[ttm] Failed to set %d pages to uc!\n", 439 printk(KERN_ERR TTM_PFX
437 cpages); 440 "Failed to set %d pages to uc!\n",
441 cpages);
438 break; 442 break;
439 case tt_wc: 443 case tt_wc:
440 r = set_pages_array_wc(pages, cpages); 444 r = set_pages_array_wc(pages, cpages);
441 if (r) 445 if (r)
442 printk(KERN_ERR "[ttm] Failed to set %d pages to wc!\n", 446 printk(KERN_ERR TTM_PFX
443 cpages); 447 "Failed to set %d pages to wc!\n",
448 cpages);
444 break; 449 break;
445 default: 450 default:
446 break; 451 break;
@@ -458,7 +463,7 @@ static void ttm_handle_caching_state_failure(struct list_head *pages,
458 struct page **failed_pages, unsigned cpages) 463 struct page **failed_pages, unsigned cpages)
459{ 464{
460 unsigned i; 465 unsigned i;
461 /* Failed pages has to be reed */ 466 /* Failed pages have to be freed */
462 for (i = 0; i < cpages; ++i) { 467 for (i = 0; i < cpages; ++i) {
463 list_del(&failed_pages[i]->lru); 468 list_del(&failed_pages[i]->lru);
464 __free_page(failed_pages[i]); 469 __free_page(failed_pages[i]);
@@ -485,7 +490,8 @@ static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags,
485 caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); 490 caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL);
486 491
487 if (!caching_array) { 492 if (!caching_array) {
488 printk(KERN_ERR "[ttm] unable to allocate table for new pages."); 493 printk(KERN_ERR TTM_PFX
494 "Unable to allocate table for new pages.");
489 return -ENOMEM; 495 return -ENOMEM;
490 } 496 }
491 497
@@ -493,12 +499,13 @@ static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags,
493 p = alloc_page(gfp_flags); 499 p = alloc_page(gfp_flags);
494 500
495 if (!p) { 501 if (!p) {
496 printk(KERN_ERR "[ttm] unable to get page %u\n", i); 502 printk(KERN_ERR TTM_PFX "Unable to get page %u.\n", i);
497 503
498 /* store already allocated pages in the pool after 504 /* store already allocated pages in the pool after
499 * setting the caching state */ 505 * setting the caching state */
500 if (cpages) { 506 if (cpages) {
501 r = ttm_set_pages_caching(caching_array, cstate, cpages); 507 r = ttm_set_pages_caching(caching_array,
508 cstate, cpages);
502 if (r) 509 if (r)
503 ttm_handle_caching_state_failure(pages, 510 ttm_handle_caching_state_failure(pages,
504 ttm_flags, cstate, 511 ttm_flags, cstate,
@@ -590,7 +597,8 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool,
590 ++pool->nrefills; 597 ++pool->nrefills;
591 pool->npages += alloc_size; 598 pool->npages += alloc_size;
592 } else { 599 } else {
593 printk(KERN_ERR "[ttm] Failed to fill pool (%p).", pool); 600 printk(KERN_ERR TTM_PFX
601 "Failed to fill pool (%p).", pool);
594 /* If we have any pages left put them to the pool. */ 602 /* If we have any pages left put them to the pool. */
595 list_for_each_entry(p, &pool->list, lru) { 603 list_for_each_entry(p, &pool->list, lru) {
596 ++cpages; 604 ++cpages;
@@ -671,13 +679,14 @@ int ttm_get_pages(struct list_head *pages, int flags,
671 if (flags & TTM_PAGE_FLAG_DMA32) 679 if (flags & TTM_PAGE_FLAG_DMA32)
672 gfp_flags |= GFP_DMA32; 680 gfp_flags |= GFP_DMA32;
673 else 681 else
674 gfp_flags |= __GFP_HIGHMEM; 682 gfp_flags |= GFP_HIGHUSER;
675 683
676 for (r = 0; r < count; ++r) { 684 for (r = 0; r < count; ++r) {
677 p = alloc_page(gfp_flags); 685 p = alloc_page(gfp_flags);
678 if (!p) { 686 if (!p) {
679 687
680 printk(KERN_ERR "[ttm] unable to allocate page."); 688 printk(KERN_ERR TTM_PFX
689 "Unable to allocate page.");
681 return -ENOMEM; 690 return -ENOMEM;
682 } 691 }
683 692
@@ -709,8 +718,9 @@ int ttm_get_pages(struct list_head *pages, int flags,
709 if (r) { 718 if (r) {
710 /* If there is any pages in the list put them back to 719 /* If there is any pages in the list put them back to
711 * the pool. */ 720 * the pool. */
712 printk(KERN_ERR "[ttm] Failed to allocate extra pages " 721 printk(KERN_ERR TTM_PFX
713 "for large request."); 722 "Failed to allocate extra pages "
723 "for large request.");
714 ttm_put_pages(pages, 0, flags, cstate); 724 ttm_put_pages(pages, 0, flags, cstate);
715 return r; 725 return r;
716 } 726 }
@@ -778,7 +788,7 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
778 if (atomic_add_return(1, &_manager.page_alloc_inited) > 1) 788 if (atomic_add_return(1, &_manager.page_alloc_inited) > 1)
779 return 0; 789 return 0;
780 790
781 printk(KERN_INFO "[ttm] Initializing pool allocator.\n"); 791 printk(KERN_INFO TTM_PFX "Initializing pool allocator.\n");
782 792
783 ttm_page_pool_init_locked(&_manager.wc_pool, GFP_HIGHUSER, "wc"); 793 ttm_page_pool_init_locked(&_manager.wc_pool, GFP_HIGHUSER, "wc");
784 794
@@ -813,7 +823,7 @@ void ttm_page_alloc_fini()
813 if (atomic_sub_return(1, &_manager.page_alloc_inited) > 0) 823 if (atomic_sub_return(1, &_manager.page_alloc_inited) > 0)
814 return; 824 return;
815 825
816 printk(KERN_INFO "[ttm] Finilizing pool allocator.\n"); 826 printk(KERN_INFO TTM_PFX "Finalizing pool allocator.\n");
817 ttm_pool_mm_shrink_fini(&_manager); 827 ttm_pool_mm_shrink_fini(&_manager);
818 828
819 for (i = 0; i < NUM_POOLS; ++i) 829 for (i = 0; i < NUM_POOLS; ++i)
diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index 1a3cb6816d1c..4505e17df3f5 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -4,6 +4,6 @@ ccflags-y := -Iinclude/drm
4vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ 4vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
5 vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \ 5 vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \
6 vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \ 6 vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
7 vmwgfx_overlay.o 7 vmwgfx_overlay.o vmwgfx_fence.o
8 8
9obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o 9obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 0c9c0811f42d..b793c8c9acb3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -88,6 +88,9 @@
88#define DRM_IOCTL_VMW_FENCE_WAIT \ 88#define DRM_IOCTL_VMW_FENCE_WAIT \
89 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT, \ 89 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT, \
90 struct drm_vmw_fence_wait_arg) 90 struct drm_vmw_fence_wait_arg)
91#define DRM_IOCTL_VMW_UPDATE_LAYOUT \
92 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT, \
93 struct drm_vmw_update_layout_arg)
91 94
92 95
93/** 96/**
@@ -135,7 +138,9 @@ static struct drm_ioctl_desc vmw_ioctls[] = {
135 VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, 138 VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl,
136 DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), 139 DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED),
137 VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, 140 VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl,
138 DRM_AUTH | DRM_UNLOCKED) 141 DRM_AUTH | DRM_UNLOCKED),
142 VMW_IOCTL_DEF(DRM_IOCTL_VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl,
143 DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED)
139}; 144};
140 145
141static struct pci_device_id vmw_pci_id_list[] = { 146static struct pci_device_id vmw_pci_id_list[] = {
@@ -318,6 +323,15 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
318 goto out_err3; 323 goto out_err3;
319 } 324 }
320 325
326 /* Need mmio memory to check for fifo pitchlock cap. */
327 if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) &&
328 !(dev_priv->capabilities & SVGA_CAP_PITCHLOCK) &&
329 !vmw_fifo_have_pitchlock(dev_priv)) {
330 ret = -ENOSYS;
331 DRM_ERROR("Hardware has no pitchlock\n");
332 goto out_err4;
333 }
334
321 dev_priv->tdev = ttm_object_device_init 335 dev_priv->tdev = ttm_object_device_init
322 (dev_priv->mem_global_ref.object, 12); 336 (dev_priv->mem_global_ref.object, 12);
323 337
@@ -399,8 +413,6 @@ static int vmw_driver_unload(struct drm_device *dev)
399{ 413{
400 struct vmw_private *dev_priv = vmw_priv(dev); 414 struct vmw_private *dev_priv = vmw_priv(dev);
401 415
402 DRM_INFO(VMWGFX_DRIVER_NAME " unload.\n");
403
404 unregister_pm_notifier(&dev_priv->pm_nb); 416 unregister_pm_notifier(&dev_priv->pm_nb);
405 417
406 vmw_fb_close(dev_priv); 418 vmw_fb_close(dev_priv);
@@ -546,7 +558,6 @@ static int vmw_master_create(struct drm_device *dev,
546{ 558{
547 struct vmw_master *vmaster; 559 struct vmw_master *vmaster;
548 560
549 DRM_INFO("Master create.\n");
550 vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL); 561 vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
551 if (unlikely(vmaster == NULL)) 562 if (unlikely(vmaster == NULL))
552 return -ENOMEM; 563 return -ENOMEM;
@@ -563,7 +574,6 @@ static void vmw_master_destroy(struct drm_device *dev,
563{ 574{
564 struct vmw_master *vmaster = vmw_master(master); 575 struct vmw_master *vmaster = vmw_master(master);
565 576
566 DRM_INFO("Master destroy.\n");
567 master->driver_priv = NULL; 577 master->driver_priv = NULL;
568 kfree(vmaster); 578 kfree(vmaster);
569} 579}
@@ -579,8 +589,6 @@ static int vmw_master_set(struct drm_device *dev,
579 struct vmw_master *vmaster = vmw_master(file_priv->master); 589 struct vmw_master *vmaster = vmw_master(file_priv->master);
580 int ret = 0; 590 int ret = 0;
581 591
582 DRM_INFO("Master set.\n");
583
584 if (active) { 592 if (active) {
585 BUG_ON(active != &dev_priv->fbdev_master); 593 BUG_ON(active != &dev_priv->fbdev_master);
586 ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); 594 ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
@@ -622,8 +630,6 @@ static void vmw_master_drop(struct drm_device *dev,
622 struct vmw_master *vmaster = vmw_master(file_priv->master); 630 struct vmw_master *vmaster = vmw_master(file_priv->master);
623 int ret; 631 int ret;
624 632
625 DRM_INFO("Master drop.\n");
626
627 /** 633 /**
628 * Make sure the master doesn't disappear while we have 634 * Make sure the master doesn't disappear while we have
629 * it locked. 635 * it locked.
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 356dc935ec13..eaad52095339 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -41,12 +41,13 @@
41 41
42#define VMWGFX_DRIVER_DATE "20100209" 42#define VMWGFX_DRIVER_DATE "20100209"
43#define VMWGFX_DRIVER_MAJOR 1 43#define VMWGFX_DRIVER_MAJOR 1
44#define VMWGFX_DRIVER_MINOR 0 44#define VMWGFX_DRIVER_MINOR 2
45#define VMWGFX_DRIVER_PATCHLEVEL 0 45#define VMWGFX_DRIVER_PATCHLEVEL 0
46#define VMWGFX_FILE_PAGE_OFFSET 0x00100000 46#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
47#define VMWGFX_FIFO_STATIC_SIZE (1024*1024) 47#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
48#define VMWGFX_MAX_RELOCATIONS 2048 48#define VMWGFX_MAX_RELOCATIONS 2048
49#define VMWGFX_MAX_GMRS 2048 49#define VMWGFX_MAX_GMRS 2048
50#define VMWGFX_MAX_DISPLAYS 16
50 51
51struct vmw_fpriv { 52struct vmw_fpriv {
52 struct drm_master *locked_master; 53 struct drm_master *locked_master;
@@ -102,6 +103,13 @@ struct vmw_surface {
102 struct vmw_cursor_snooper snooper; 103 struct vmw_cursor_snooper snooper;
103}; 104};
104 105
106struct vmw_fence_queue {
107 struct list_head head;
108 struct timespec lag;
109 struct timespec lag_time;
110 spinlock_t lock;
111};
112
105struct vmw_fifo_state { 113struct vmw_fifo_state {
106 unsigned long reserved_size; 114 unsigned long reserved_size;
107 __le32 *dynamic_buffer; 115 __le32 *dynamic_buffer;
@@ -115,6 +123,7 @@ struct vmw_fifo_state {
115 uint32_t capabilities; 123 uint32_t capabilities;
116 struct mutex fifo_mutex; 124 struct mutex fifo_mutex;
117 struct rw_semaphore rwsem; 125 struct rw_semaphore rwsem;
126 struct vmw_fence_queue fence_queue;
118}; 127};
119 128
120struct vmw_relocation { 129struct vmw_relocation {
@@ -144,6 +153,14 @@ struct vmw_master {
144 struct ttm_lock lock; 153 struct ttm_lock lock;
145}; 154};
146 155
156struct vmw_vga_topology_state {
157 uint32_t width;
158 uint32_t height;
159 uint32_t primary;
160 uint32_t pos_x;
161 uint32_t pos_y;
162};
163
147struct vmw_private { 164struct vmw_private {
148 struct ttm_bo_device bdev; 165 struct ttm_bo_device bdev;
149 struct ttm_bo_global_ref bo_global_ref; 166 struct ttm_bo_global_ref bo_global_ref;
@@ -171,14 +188,19 @@ struct vmw_private {
171 * VGA registers. 188 * VGA registers.
172 */ 189 */
173 190
191 struct vmw_vga_topology_state vga_save[VMWGFX_MAX_DISPLAYS];
174 uint32_t vga_width; 192 uint32_t vga_width;
175 uint32_t vga_height; 193 uint32_t vga_height;
176 uint32_t vga_depth; 194 uint32_t vga_depth;
177 uint32_t vga_bpp; 195 uint32_t vga_bpp;
178 uint32_t vga_pseudo; 196 uint32_t vga_pseudo;
179 uint32_t vga_red_mask; 197 uint32_t vga_red_mask;
180 uint32_t vga_blue_mask;
181 uint32_t vga_green_mask; 198 uint32_t vga_green_mask;
199 uint32_t vga_blue_mask;
200 uint32_t vga_bpl;
201 uint32_t vga_pitchlock;
202
203 uint32_t num_displays;
182 204
183 /* 205 /*
184 * Framebuffer info. 206 * Framebuffer info.
@@ -393,6 +415,7 @@ extern int vmw_fifo_send_fence(struct vmw_private *dev_priv,
393extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason); 415extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason);
394extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma); 416extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma);
395extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv); 417extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv);
418extern bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv);
396 419
397/** 420/**
398 * TTM glue - vmwgfx_ttm_glue.c 421 * TTM glue - vmwgfx_ttm_glue.c
@@ -441,6 +464,23 @@ extern int vmw_fallback_wait(struct vmw_private *dev_priv,
441 uint32_t sequence, 464 uint32_t sequence,
442 bool interruptible, 465 bool interruptible,
443 unsigned long timeout); 466 unsigned long timeout);
467extern void vmw_update_sequence(struct vmw_private *dev_priv,
468 struct vmw_fifo_state *fifo_state);
469
470
471/**
472 * Rudimentary fence objects currently used only for throttling -
473 * vmwgfx_fence.c
474 */
475
476extern void vmw_fence_queue_init(struct vmw_fence_queue *queue);
477extern void vmw_fence_queue_takedown(struct vmw_fence_queue *queue);
478extern int vmw_fence_push(struct vmw_fence_queue *queue,
479 uint32_t sequence);
480extern int vmw_fence_pull(struct vmw_fence_queue *queue,
481 uint32_t signaled_sequence);
482extern int vmw_wait_lag(struct vmw_private *dev_priv,
483 struct vmw_fence_queue *queue, uint32_t us);
444 484
445/** 485/**
446 * Kernel framebuffer - vmwgfx_fb.c 486 * Kernel framebuffer - vmwgfx_fb.c
@@ -466,6 +506,11 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
466 struct ttm_object_file *tfile, 506 struct ttm_object_file *tfile,
467 struct ttm_buffer_object *bo, 507 struct ttm_buffer_object *bo,
468 SVGA3dCmdHeader *header); 508 SVGA3dCmdHeader *header);
509void vmw_kms_write_svga(struct vmw_private *vmw_priv,
510 unsigned width, unsigned height, unsigned pitch,
511 unsigned bbp, unsigned depth);
512int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
513 struct drm_file *file_priv);
469 514
470/** 515/**
471 * Overlay control - vmwgfx_overlay.c 516 * Overlay control - vmwgfx_overlay.c
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index dbd36b8910cf..bdd67cf83315 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -669,6 +669,15 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
669 goto out_err; 669 goto out_err;
670 670
671 vmw_apply_relocations(sw_context); 671 vmw_apply_relocations(sw_context);
672
673 if (arg->throttle_us) {
674 ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.fence_queue,
675 arg->throttle_us);
676
677 if (unlikely(ret != 0))
678 goto out_err;
679 }
680
672 vmw_fifo_commit(dev_priv, arg->command_size); 681 vmw_fifo_commit(dev_priv, arg->command_size);
673 682
674 ret = vmw_fifo_send_fence(dev_priv, &sequence); 683 ret = vmw_fifo_send_fence(dev_priv, &sequence);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 7421aaad8d09..b0866f04ec76 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -132,16 +132,14 @@ static int vmw_fb_check_var(struct fb_var_screeninfo *var,
132 return -EINVAL; 132 return -EINVAL;
133 } 133 }
134 134
135 /* without multimon its hard to resize */ 135 if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) &&
136 if (!(vmw_priv->capabilities & SVGA_CAP_MULTIMON) && 136 (var->xoffset != 0 || var->yoffset != 0)) {
137 (var->xres != par->max_width || 137 DRM_ERROR("Can not handle panning without display topology\n");
138 var->yres != par->max_height)) {
139 DRM_ERROR("Tried to resize, but we don't have multimon\n");
140 return -EINVAL; 138 return -EINVAL;
141 } 139 }
142 140
143 if (var->xres > par->max_width || 141 if ((var->xoffset + var->xres) > par->max_width ||
144 var->yres > par->max_height) { 142 (var->yoffset + var->yres) > par->max_height) {
145 DRM_ERROR("Requested geom can not fit in framebuffer\n"); 143 DRM_ERROR("Requested geom can not fit in framebuffer\n");
146 return -EINVAL; 144 return -EINVAL;
147 } 145 }
@@ -154,27 +152,11 @@ static int vmw_fb_set_par(struct fb_info *info)
154 struct vmw_fb_par *par = info->par; 152 struct vmw_fb_par *par = info->par;
155 struct vmw_private *vmw_priv = par->vmw_priv; 153 struct vmw_private *vmw_priv = par->vmw_priv;
156 154
157 if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { 155 vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres,
158 vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); 156 info->fix.line_length,
159 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); 157 par->bpp, par->depth);
160 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); 158 if (vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) {
161 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
162 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
163 vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0);
164 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
165 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
166
167 vmw_write(vmw_priv, SVGA_REG_ENABLE, 1);
168 vmw_write(vmw_priv, SVGA_REG_WIDTH, par->max_width);
169 vmw_write(vmw_priv, SVGA_REG_HEIGHT, par->max_height);
170 vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, par->bpp);
171 vmw_write(vmw_priv, SVGA_REG_DEPTH, par->depth);
172 vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
173 vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
174 vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
175
176 /* TODO check if pitch and offset changes */ 159 /* TODO check if pitch and offset changes */
177
178 vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); 160 vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
179 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); 161 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
180 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); 162 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
@@ -183,13 +165,13 @@ static int vmw_fb_set_par(struct fb_info *info)
183 vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres); 165 vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres);
184 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); 166 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres);
185 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); 167 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
186 } else {
187 vmw_write(vmw_priv, SVGA_REG_WIDTH, info->var.xres);
188 vmw_write(vmw_priv, SVGA_REG_HEIGHT, info->var.yres);
189
190 /* TODO check if pitch and offset changes */
191 } 168 }
192 169
170 /* This is really helpful since if this fails the user
171 * can probably not see anything on the screen.
172 */
173 WARN_ON(vmw_read(vmw_priv, SVGA_REG_FB_OFFSET) != 0);
174
193 return 0; 175 return 0;
194} 176}
195 177
@@ -416,48 +398,23 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
416 unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size; 398 unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size;
417 int ret; 399 int ret;
418 400
401 /* XXX These shouldn't be hardcoded. */
419 initial_width = 800; 402 initial_width = 800;
420 initial_height = 600; 403 initial_height = 600;
421 404
422 fb_bbp = 32; 405 fb_bbp = 32;
423 fb_depth = 24; 406 fb_depth = 24;
424 407
425 if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { 408 /* XXX As shouldn't these be as well. */
426 fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); 409 fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
427 fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); 410 fb_height = min(vmw_priv->fb_max_height, (unsigned)2048);
428 } else {
429 fb_width = min(vmw_priv->fb_max_width, initial_width);
430 fb_height = min(vmw_priv->fb_max_height, initial_height);
431 }
432 411
433 initial_width = min(fb_width, initial_width); 412 initial_width = min(fb_width, initial_width);
434 initial_height = min(fb_height, initial_height); 413 initial_height = min(fb_height, initial_height);
435 414
436 vmw_write(vmw_priv, SVGA_REG_WIDTH, fb_width); 415 fb_pitch = fb_width * fb_bbp / 8;
437 vmw_write(vmw_priv, SVGA_REG_HEIGHT, fb_height); 416 fb_size = fb_pitch * fb_height;
438 vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, fb_bbp);
439 vmw_write(vmw_priv, SVGA_REG_DEPTH, fb_depth);
440 vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
441 vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
442 vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
443
444 fb_size = vmw_read(vmw_priv, SVGA_REG_FB_SIZE);
445 fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET); 417 fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET);
446 fb_pitch = vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE);
447
448 DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_WIDTH));
449 DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_HEIGHT));
450 DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_WIDTH));
451 DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_HEIGHT));
452 DRM_DEBUG("bpp %u\n", vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL));
453 DRM_DEBUG("depth %u\n", vmw_read(vmw_priv, SVGA_REG_DEPTH));
454 DRM_DEBUG("bpl %u\n", vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE));
455 DRM_DEBUG("r mask %08x\n", vmw_read(vmw_priv, SVGA_REG_RED_MASK));
456 DRM_DEBUG("g mask %08x\n", vmw_read(vmw_priv, SVGA_REG_GREEN_MASK));
457 DRM_DEBUG("b mask %08x\n", vmw_read(vmw_priv, SVGA_REG_BLUE_MASK));
458 DRM_DEBUG("fb_offset 0x%08x\n", fb_offset);
459 DRM_DEBUG("fb_pitch %u\n", fb_pitch);
460 DRM_DEBUG("fb_size %u kiB\n", fb_size / 1024);
461 418
462 info = framebuffer_alloc(sizeof(*par), device); 419 info = framebuffer_alloc(sizeof(*par), device);
463 if (!info) 420 if (!info)
@@ -659,6 +616,10 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv,
659 goto err_unlock; 616 goto err_unlock;
660 617
661 ret = ttm_bo_validate(bo, &ne_placement, false, false, false); 618 ret = ttm_bo_validate(bo, &ne_placement, false, false, false);
619
620 /* Could probably bug on */
621 WARN_ON(bo->offset != 0);
622
662 ttm_bo_unreserve(bo); 623 ttm_bo_unreserve(bo);
663err_unlock: 624err_unlock:
664 ttm_write_unlock(&vmw_priv->active_master->lock); 625 ttm_write_unlock(&vmw_priv->active_master->lock);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
new file mode 100644
index 000000000000..61eacc1b5ca3
--- /dev/null
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -0,0 +1,173 @@
1/**************************************************************************
2 *
3 * Copyright (C) 2010 VMware, Inc., Palo Alto, CA., USA
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#include "vmwgfx_drv.h"
30
31struct vmw_fence {
32 struct list_head head;
33 uint32_t sequence;
34 struct timespec submitted;
35};
36
37void vmw_fence_queue_init(struct vmw_fence_queue *queue)
38{
39 INIT_LIST_HEAD(&queue->head);
40 queue->lag = ns_to_timespec(0);
41 getrawmonotonic(&queue->lag_time);
42 spin_lock_init(&queue->lock);
43}
44
45void vmw_fence_queue_takedown(struct vmw_fence_queue *queue)
46{
47 struct vmw_fence *fence, *next;
48
49 spin_lock(&queue->lock);
50 list_for_each_entry_safe(fence, next, &queue->head, head) {
51 kfree(fence);
52 }
53 spin_unlock(&queue->lock);
54}
55
56int vmw_fence_push(struct vmw_fence_queue *queue,
57 uint32_t sequence)
58{
59 struct vmw_fence *fence = kmalloc(sizeof(*fence), GFP_KERNEL);
60
61 if (unlikely(!fence))
62 return -ENOMEM;
63
64 fence->sequence = sequence;
65 getrawmonotonic(&fence->submitted);
66 spin_lock(&queue->lock);
67 list_add_tail(&fence->head, &queue->head);
68 spin_unlock(&queue->lock);
69
70 return 0;
71}
72
73int vmw_fence_pull(struct vmw_fence_queue *queue,
74 uint32_t signaled_sequence)
75{
76 struct vmw_fence *fence, *next;
77 struct timespec now;
78 bool updated = false;
79
80 spin_lock(&queue->lock);
81 getrawmonotonic(&now);
82
83 if (list_empty(&queue->head)) {
84 queue->lag = ns_to_timespec(0);
85 queue->lag_time = now;
86 updated = true;
87 goto out_unlock;
88 }
89
90 list_for_each_entry_safe(fence, next, &queue->head, head) {
91 if (signaled_sequence - fence->sequence > (1 << 30))
92 continue;
93
94 queue->lag = timespec_sub(now, fence->submitted);
95 queue->lag_time = now;
96 updated = true;
97 list_del(&fence->head);
98 kfree(fence);
99 }
100
101out_unlock:
102 spin_unlock(&queue->lock);
103
104 return (updated) ? 0 : -EBUSY;
105}
106
107static struct timespec vmw_timespec_add(struct timespec t1,
108 struct timespec t2)
109{
110 t1.tv_sec += t2.tv_sec;
111 t1.tv_nsec += t2.tv_nsec;
112 if (t1.tv_nsec >= 1000000000L) {
113 t1.tv_sec += 1;
114 t1.tv_nsec -= 1000000000L;
115 }
116
117 return t1;
118}
119
120static struct timespec vmw_fifo_lag(struct vmw_fence_queue *queue)
121{
122 struct timespec now;
123
124 spin_lock(&queue->lock);
125 getrawmonotonic(&now);
126 queue->lag = vmw_timespec_add(queue->lag,
127 timespec_sub(now, queue->lag_time));
128 queue->lag_time = now;
129 spin_unlock(&queue->lock);
130 return queue->lag;
131}
132
133
134static bool vmw_lag_lt(struct vmw_fence_queue *queue,
135 uint32_t us)
136{
137 struct timespec lag, cond;
138
139 cond = ns_to_timespec((s64) us * 1000);
140 lag = vmw_fifo_lag(queue);
141 return (timespec_compare(&lag, &cond) < 1);
142}
143
144int vmw_wait_lag(struct vmw_private *dev_priv,
145 struct vmw_fence_queue *queue, uint32_t us)
146{
147 struct vmw_fence *fence;
148 uint32_t sequence;
149 int ret;
150
151 while (!vmw_lag_lt(queue, us)) {
152 spin_lock(&queue->lock);
153 if (list_empty(&queue->head))
154 sequence = atomic_read(&dev_priv->fence_seq);
155 else {
156 fence = list_first_entry(&queue->head,
157 struct vmw_fence, head);
158 sequence = fence->sequence;
159 }
160 spin_unlock(&queue->lock);
161
162 ret = vmw_wait_fence(dev_priv, false, sequence, true,
163 3*HZ);
164
165 if (unlikely(ret != 0))
166 return ret;
167
168 (void) vmw_fence_pull(queue, sequence);
169 }
170 return 0;
171}
172
173
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
index 39d43a01d846..e6a1eb7ea954 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
@@ -34,6 +34,9 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv)
34 __le32 __iomem *fifo_mem = dev_priv->mmio_virt; 34 __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
35 uint32_t fifo_min, hwversion; 35 uint32_t fifo_min, hwversion;
36 36
37 if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO))
38 return false;
39
37 fifo_min = ioread32(fifo_mem + SVGA_FIFO_MIN); 40 fifo_min = ioread32(fifo_mem + SVGA_FIFO_MIN);
38 if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int)) 41 if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int))
39 return false; 42 return false;
@@ -48,6 +51,21 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv)
48 return true; 51 return true;
49} 52}
50 53
54bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv)
55{
56 __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
57 uint32_t caps;
58
59 if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO))
60 return false;
61
62 caps = ioread32(fifo_mem + SVGA_FIFO_CAPABILITIES);
63 if (caps & SVGA_FIFO_CAP_PITCHLOCK)
64 return true;
65
66 return false;
67}
68
51int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) 69int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
52{ 70{
53 __le32 __iomem *fifo_mem = dev_priv->mmio_virt; 71 __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
@@ -120,7 +138,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
120 138
121 atomic_set(&dev_priv->fence_seq, dev_priv->last_read_sequence); 139 atomic_set(&dev_priv->fence_seq, dev_priv->last_read_sequence);
122 iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE); 140 iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE);
123 141 vmw_fence_queue_init(&fifo->fence_queue);
124 return vmw_fifo_send_fence(dev_priv, &dummy); 142 return vmw_fifo_send_fence(dev_priv, &dummy);
125out_err: 143out_err:
126 vfree(fifo->static_buffer); 144 vfree(fifo->static_buffer);
@@ -159,6 +177,7 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
159 dev_priv->enable_state); 177 dev_priv->enable_state);
160 178
161 mutex_unlock(&dev_priv->hw_mutex); 179 mutex_unlock(&dev_priv->hw_mutex);
180 vmw_fence_queue_takedown(&fifo->fence_queue);
162 181
163 if (likely(fifo->last_buffer != NULL)) { 182 if (likely(fifo->last_buffer != NULL)) {
164 vfree(fifo->last_buffer); 183 vfree(fifo->last_buffer);
@@ -484,6 +503,8 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence)
484 fifo_state->last_buffer_add = true; 503 fifo_state->last_buffer_add = true;
485 vmw_fifo_commit(dev_priv, bytes); 504 vmw_fifo_commit(dev_priv, bytes);
486 fifo_state->last_buffer_add = false; 505 fifo_state->last_buffer_add = false;
506 (void) vmw_fence_push(&fifo_state->fence_queue, *sequence);
507 vmw_update_sequence(dev_priv, fifo_state);
487 508
488out_err: 509out_err:
489 return ret; 510 return ret;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
index 4d7cb5393860..e92298a6a383 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
@@ -64,22 +64,33 @@ static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t sequence)
64 return (busy == 0); 64 return (busy == 0);
65} 65}
66 66
67void vmw_update_sequence(struct vmw_private *dev_priv,
68 struct vmw_fifo_state *fifo_state)
69{
70 __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
71
72 uint32_t sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE);
73
74 if (dev_priv->last_read_sequence != sequence) {
75 dev_priv->last_read_sequence = sequence;
76 vmw_fence_pull(&fifo_state->fence_queue, sequence);
77 }
78}
67 79
68bool vmw_fence_signaled(struct vmw_private *dev_priv, 80bool vmw_fence_signaled(struct vmw_private *dev_priv,
69 uint32_t sequence) 81 uint32_t sequence)
70{ 82{
71 __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
72 struct vmw_fifo_state *fifo_state; 83 struct vmw_fifo_state *fifo_state;
73 bool ret; 84 bool ret;
74 85
75 if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP)) 86 if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP))
76 return true; 87 return true;
77 88
78 dev_priv->last_read_sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE); 89 fifo_state = &dev_priv->fifo;
90 vmw_update_sequence(dev_priv, fifo_state);
79 if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP)) 91 if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP))
80 return true; 92 return true;
81 93
82 fifo_state = &dev_priv->fifo;
83 if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE) && 94 if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE) &&
84 vmw_fifo_idle(dev_priv, sequence)) 95 vmw_fifo_idle(dev_priv, sequence))
85 return true; 96 return true;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index bbc7c4c30bc7..f1d626112415 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -30,6 +30,8 @@
30/* Might need a hrtimer here? */ 30/* Might need a hrtimer here? */
31#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) 31#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
32 32
33static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb);
34static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb);
33 35
34void vmw_display_unit_cleanup(struct vmw_display_unit *du) 36void vmw_display_unit_cleanup(struct vmw_display_unit *du)
35{ 37{
@@ -326,6 +328,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb,
326struct vmw_framebuffer_surface { 328struct vmw_framebuffer_surface {
327 struct vmw_framebuffer base; 329 struct vmw_framebuffer base;
328 struct vmw_surface *surface; 330 struct vmw_surface *surface;
331 struct vmw_dma_buffer *buffer;
329 struct delayed_work d_work; 332 struct delayed_work d_work;
330 struct mutex work_lock; 333 struct mutex work_lock;
331 bool present_fs; 334 bool present_fs;
@@ -500,8 +503,8 @@ int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
500 vfbs->base.base.depth = 24; 503 vfbs->base.base.depth = 24;
501 vfbs->base.base.width = width; 504 vfbs->base.base.width = width;
502 vfbs->base.base.height = height; 505 vfbs->base.base.height = height;
503 vfbs->base.pin = NULL; 506 vfbs->base.pin = &vmw_surface_dmabuf_pin;
504 vfbs->base.unpin = NULL; 507 vfbs->base.unpin = &vmw_surface_dmabuf_unpin;
505 vfbs->surface = surface; 508 vfbs->surface = surface;
506 mutex_init(&vfbs->work_lock); 509 mutex_init(&vfbs->work_lock);
507 INIT_DELAYED_WORK(&vfbs->d_work, &vmw_framebuffer_present_fs_callback); 510 INIT_DELAYED_WORK(&vfbs->d_work, &vmw_framebuffer_present_fs_callback);
@@ -589,6 +592,40 @@ static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = {
589 .create_handle = vmw_framebuffer_create_handle, 592 .create_handle = vmw_framebuffer_create_handle,
590}; 593};
591 594
595static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb)
596{
597 struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
598 struct vmw_framebuffer_surface *vfbs =
599 vmw_framebuffer_to_vfbs(&vfb->base);
600 unsigned long size = vfbs->base.base.pitch * vfbs->base.base.height;
601 int ret;
602
603 vfbs->buffer = kzalloc(sizeof(*vfbs->buffer), GFP_KERNEL);
604 if (unlikely(vfbs->buffer == NULL))
605 return -ENOMEM;
606
607 vmw_overlay_pause_all(dev_priv);
608 ret = vmw_dmabuf_init(dev_priv, vfbs->buffer, size,
609 &vmw_vram_ne_placement,
610 false, &vmw_dmabuf_bo_free);
611 vmw_overlay_resume_all(dev_priv);
612
613 return ret;
614}
615
616static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb)
617{
618 struct ttm_buffer_object *bo;
619 struct vmw_framebuffer_surface *vfbs =
620 vmw_framebuffer_to_vfbs(&vfb->base);
621
622 bo = &vfbs->buffer->base;
623 ttm_bo_unref(&bo);
624 vfbs->buffer = NULL;
625
626 return 0;
627}
628
592static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb) 629static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb)
593{ 630{
594 struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); 631 struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
@@ -596,33 +633,15 @@ static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb)
596 vmw_framebuffer_to_vfbd(&vfb->base); 633 vmw_framebuffer_to_vfbd(&vfb->base);
597 int ret; 634 int ret;
598 635
636
599 vmw_overlay_pause_all(dev_priv); 637 vmw_overlay_pause_all(dev_priv);
600 638
601 ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer); 639 ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer);
602 640
603 if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
604 vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
605 vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, 0);
606 vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
607 vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
608 vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
609 vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0);
610 vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
611 vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
612
613 vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
614 vmw_write(dev_priv, SVGA_REG_WIDTH, vfb->base.width);
615 vmw_write(dev_priv, SVGA_REG_HEIGHT, vfb->base.height);
616 vmw_write(dev_priv, SVGA_REG_BITS_PER_PIXEL, vfb->base.bits_per_pixel);
617 vmw_write(dev_priv, SVGA_REG_DEPTH, vfb->base.depth);
618 vmw_write(dev_priv, SVGA_REG_RED_MASK, 0x00ff0000);
619 vmw_write(dev_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
620 vmw_write(dev_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
621 } else
622 WARN_ON(true);
623
624 vmw_overlay_resume_all(dev_priv); 641 vmw_overlay_resume_all(dev_priv);
625 642
643 WARN_ON(ret != 0);
644
626 return 0; 645 return 0;
627} 646}
628 647
@@ -668,7 +687,7 @@ int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
668 687
669 /* XXX get the first 3 from the surface info */ 688 /* XXX get the first 3 from the surface info */
670 vfbd->base.base.bits_per_pixel = 32; 689 vfbd->base.base.bits_per_pixel = 32;
671 vfbd->base.base.pitch = width * 32 / 4; 690 vfbd->base.base.pitch = width * vfbd->base.base.bits_per_pixel / 8;
672 vfbd->base.base.depth = 24; 691 vfbd->base.base.depth = 24;
673 vfbd->base.base.width = width; 692 vfbd->base.base.width = width;
674 vfbd->base.base.height = height; 693 vfbd->base.base.height = height;
@@ -765,8 +784,9 @@ int vmw_kms_init(struct vmw_private *dev_priv)
765 dev->mode_config.funcs = &vmw_kms_funcs; 784 dev->mode_config.funcs = &vmw_kms_funcs;
766 dev->mode_config.min_width = 1; 785 dev->mode_config.min_width = 1;
767 dev->mode_config.min_height = 1; 786 dev->mode_config.min_height = 1;
768 dev->mode_config.max_width = dev_priv->fb_max_width; 787 /* assumed largest fb size */
769 dev->mode_config.max_height = dev_priv->fb_max_height; 788 dev->mode_config.max_width = 8192;
789 dev->mode_config.max_height = 8192;
770 790
771 ret = vmw_kms_init_legacy_display_system(dev_priv); 791 ret = vmw_kms_init_legacy_display_system(dev_priv);
772 792
@@ -826,49 +846,140 @@ out:
826 return ret; 846 return ret;
827} 847}
828 848
849void vmw_kms_write_svga(struct vmw_private *vmw_priv,
850 unsigned width, unsigned height, unsigned pitch,
851 unsigned bbp, unsigned depth)
852{
853 if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
854 vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch);
855 else if (vmw_fifo_have_pitchlock(vmw_priv))
856 iowrite32(pitch, vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
857 vmw_write(vmw_priv, SVGA_REG_WIDTH, width);
858 vmw_write(vmw_priv, SVGA_REG_HEIGHT, height);
859 vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bbp);
860 vmw_write(vmw_priv, SVGA_REG_DEPTH, depth);
861 vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
862 vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
863 vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
864}
865
829int vmw_kms_save_vga(struct vmw_private *vmw_priv) 866int vmw_kms_save_vga(struct vmw_private *vmw_priv)
830{ 867{
831 /* 868 struct vmw_vga_topology_state *save;
832 * setup a single multimon monitor with the size 869 uint32_t i;
833 * of 0x0, this stops the UI from resizing when we
834 * change the framebuffer size
835 */
836 if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
837 vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
838 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
839 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
840 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
841 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
842 vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0);
843 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
844 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
845 }
846 870
847 vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH); 871 vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH);
848 vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT); 872 vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT);
849 vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
850 vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH); 873 vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH);
874 vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
851 vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR); 875 vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR);
852 vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK); 876 vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK);
853 vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK);
854 vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK); 877 vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK);
878 vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK);
879 if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
880 vmw_priv->vga_pitchlock =
881 vmw_read(vmw_priv, SVGA_REG_PITCHLOCK);
882 else if (vmw_fifo_have_pitchlock(vmw_priv))
883 vmw_priv->vga_pitchlock = ioread32(vmw_priv->mmio_virt +
884 SVGA_FIFO_PITCHLOCK);
885
886 if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
887 return 0;
855 888
889 vmw_priv->num_displays = vmw_read(vmw_priv,
890 SVGA_REG_NUM_GUEST_DISPLAYS);
891
892 for (i = 0; i < vmw_priv->num_displays; ++i) {
893 save = &vmw_priv->vga_save[i];
894 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
895 save->primary = vmw_read(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY);
896 save->pos_x = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_X);
897 save->pos_y = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y);
898 save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
899 save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
900 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
901 }
856 return 0; 902 return 0;
857} 903}
858 904
859int vmw_kms_restore_vga(struct vmw_private *vmw_priv) 905int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
860{ 906{
907 struct vmw_vga_topology_state *save;
908 uint32_t i;
909
861 vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width); 910 vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width);
862 vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height); 911 vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height);
863 vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
864 vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth); 912 vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth);
913 vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
865 vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo); 914 vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo);
866 vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask); 915 vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask);
867 vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask); 916 vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask);
868 vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, vmw_priv->vga_blue_mask); 917 vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, vmw_priv->vga_blue_mask);
918 if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
919 vmw_write(vmw_priv, SVGA_REG_PITCHLOCK,
920 vmw_priv->vga_pitchlock);
921 else if (vmw_fifo_have_pitchlock(vmw_priv))
922 iowrite32(vmw_priv->vga_pitchlock,
923 vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
924
925 if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
926 return 0;
869 927
870 /* TODO check for multimon */ 928 for (i = 0; i < vmw_priv->num_displays; ++i) {
871 vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0); 929 save = &vmw_priv->vga_save[i];
930 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
931 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, save->primary);
932 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, save->pos_x);
933 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, save->pos_y);
934 vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, save->width);
935 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, save->height);
936 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
937 }
872 938
873 return 0; 939 return 0;
874} 940}
941
942int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
943 struct drm_file *file_priv)
944{
945 struct vmw_private *dev_priv = vmw_priv(dev);
946 struct drm_vmw_update_layout_arg *arg =
947 (struct drm_vmw_update_layout_arg *)data;
948 struct vmw_master *vmaster = vmw_master(file_priv->master);
949 void __user *user_rects;
950 struct drm_vmw_rect *rects;
951 unsigned rects_size;
952 int ret;
953
954 ret = ttm_read_lock(&vmaster->lock, true);
955 if (unlikely(ret != 0))
956 return ret;
957
958 if (!arg->num_outputs) {
959 struct drm_vmw_rect def_rect = {0, 0, 800, 600};
960 vmw_kms_ldu_update_layout(dev_priv, 1, &def_rect);
961 goto out_unlock;
962 }
963
964 rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
965 rects = kzalloc(rects_size, GFP_KERNEL);
966 if (unlikely(!rects)) {
967 ret = -ENOMEM;
968 goto out_unlock;
969 }
970
971 user_rects = (void __user *)(unsigned long)arg->rects;
972 ret = copy_from_user(rects, user_rects, rects_size);
973 if (unlikely(ret != 0)) {
974 DRM_ERROR("Failed to get rects.\n");
975 goto out_free;
976 }
977
978 vmw_kms_ldu_update_layout(dev_priv, arg->num_outputs, rects);
979
980out_free:
981 kfree(rects);
982out_unlock:
983 ttm_read_unlock(&vmaster->lock);
984 return ret;
985}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 8b95249f0531..8a398a0339b6 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -94,9 +94,11 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
94int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); 94int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
95 95
96/* 96/*
97 * Legacy display unit functions - vmwgfx_ldu.h 97 * Legacy display unit functions - vmwgfx_ldu.c
98 */ 98 */
99int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv); 99int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv);
100int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv); 100int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv);
101int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num,
102 struct drm_vmw_rect *rects);
101 103
102#endif 104#endif
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index 90891593bf6c..cfaf690a5b2f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -38,6 +38,7 @@ struct vmw_legacy_display {
38 struct list_head active; 38 struct list_head active;
39 39
40 unsigned num_active; 40 unsigned num_active;
41 unsigned last_num_active;
41 42
42 struct vmw_framebuffer *fb; 43 struct vmw_framebuffer *fb;
43}; 44};
@@ -48,9 +49,12 @@ struct vmw_legacy_display {
48struct vmw_legacy_display_unit { 49struct vmw_legacy_display_unit {
49 struct vmw_display_unit base; 50 struct vmw_display_unit base;
50 51
51 struct list_head active; 52 unsigned pref_width;
53 unsigned pref_height;
54 bool pref_active;
55 struct drm_display_mode *pref_mode;
52 56
53 unsigned unit; 57 struct list_head active;
54}; 58};
55 59
56static void vmw_ldu_destroy(struct vmw_legacy_display_unit *ldu) 60static void vmw_ldu_destroy(struct vmw_legacy_display_unit *ldu)
@@ -88,23 +92,44 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
88{ 92{
89 struct vmw_legacy_display *lds = dev_priv->ldu_priv; 93 struct vmw_legacy_display *lds = dev_priv->ldu_priv;
90 struct vmw_legacy_display_unit *entry; 94 struct vmw_legacy_display_unit *entry;
91 struct drm_crtc *crtc; 95 struct drm_framebuffer *fb = NULL;
96 struct drm_crtc *crtc = NULL;
92 int i = 0; 97 int i = 0;
93 98
94 /* to stop the screen from changing size on resize */ 99 /* If there is no display topology the host just assumes
95 vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0); 100 * that the guest will set the same layout as the host.
96 for (i = 0; i < lds->num_active; i++) { 101 */
97 vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i); 102 if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)) {
98 vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i); 103 int w = 0, h = 0;
99 vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0); 104 list_for_each_entry(entry, &lds->active, active) {
100 vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); 105 crtc = &entry->base.crtc;
101 vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0); 106 w = max(w, crtc->x + crtc->mode.hdisplay);
102 vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0); 107 h = max(h, crtc->y + crtc->mode.vdisplay);
103 vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); 108 i++;
109 }
110
111 if (crtc == NULL)
112 return 0;
113 fb = entry->base.crtc.fb;
114
115 vmw_kms_write_svga(dev_priv, w, h, fb->pitch,
116 fb->bits_per_pixel, fb->depth);
117
118 return 0;
104 } 119 }
105 120
106 /* Now set the mode */ 121 if (!list_empty(&lds->active)) {
107 vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, lds->num_active); 122 entry = list_entry(lds->active.next, typeof(*entry), active);
123 fb = entry->base.crtc.fb;
124
125 vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitch,
126 fb->bits_per_pixel, fb->depth);
127 }
128
129 /* Make sure we always show something. */
130 vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS,
131 lds->num_active ? lds->num_active : 1);
132
108 i = 0; 133 i = 0;
109 list_for_each_entry(entry, &lds->active, active) { 134 list_for_each_entry(entry, &lds->active, active) {
110 crtc = &entry->base.crtc; 135 crtc = &entry->base.crtc;
@@ -120,6 +145,10 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
120 i++; 145 i++;
121 } 146 }
122 147
148 BUG_ON(i != lds->num_active);
149
150 lds->last_num_active = lds->num_active;
151
123 return 0; 152 return 0;
124} 153}
125 154
@@ -130,6 +159,7 @@ static int vmw_ldu_del_active(struct vmw_private *vmw_priv,
130 if (list_empty(&ldu->active)) 159 if (list_empty(&ldu->active))
131 return 0; 160 return 0;
132 161
162 /* Must init otherwise list_empty(&ldu->active) will not work. */
133 list_del_init(&ldu->active); 163 list_del_init(&ldu->active);
134 if (--(ld->num_active) == 0) { 164 if (--(ld->num_active) == 0) {
135 BUG_ON(!ld->fb); 165 BUG_ON(!ld->fb);
@@ -149,24 +179,29 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv,
149 struct vmw_legacy_display_unit *entry; 179 struct vmw_legacy_display_unit *entry;
150 struct list_head *at; 180 struct list_head *at;
151 181
182 BUG_ON(!ld->num_active && ld->fb);
183 if (vfb != ld->fb) {
184 if (ld->fb && ld->fb->unpin)
185 ld->fb->unpin(ld->fb);
186 if (vfb->pin)
187 vfb->pin(vfb);
188 ld->fb = vfb;
189 }
190
152 if (!list_empty(&ldu->active)) 191 if (!list_empty(&ldu->active))
153 return 0; 192 return 0;
154 193
155 at = &ld->active; 194 at = &ld->active;
156 list_for_each_entry(entry, &ld->active, active) { 195 list_for_each_entry(entry, &ld->active, active) {
157 if (entry->unit > ldu->unit) 196 if (entry->base.unit > ldu->base.unit)
158 break; 197 break;
159 198
160 at = &entry->active; 199 at = &entry->active;
161 } 200 }
162 201
163 list_add(&ldu->active, at); 202 list_add(&ldu->active, at);
164 if (ld->num_active++ == 0) { 203
165 BUG_ON(ld->fb); 204 ld->num_active++;
166 if (vfb->pin)
167 vfb->pin(vfb);
168 ld->fb = vfb;
169 }
170 205
171 return 0; 206 return 0;
172} 207}
@@ -208,6 +243,8 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
208 243
209 /* ldu only supports one fb active at the time */ 244 /* ldu only supports one fb active at the time */
210 if (dev_priv->ldu_priv->fb && vfb && 245 if (dev_priv->ldu_priv->fb && vfb &&
246 !(dev_priv->ldu_priv->num_active == 1 &&
247 !list_empty(&ldu->active)) &&
211 dev_priv->ldu_priv->fb != vfb) { 248 dev_priv->ldu_priv->fb != vfb) {
212 DRM_ERROR("Multiple framebuffers not supported\n"); 249 DRM_ERROR("Multiple framebuffers not supported\n");
213 return -EINVAL; 250 return -EINVAL;
@@ -300,8 +337,7 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector)
300static enum drm_connector_status 337static enum drm_connector_status
301 vmw_ldu_connector_detect(struct drm_connector *connector) 338 vmw_ldu_connector_detect(struct drm_connector *connector)
302{ 339{
303 /* XXX vmwctrl should control connection status */ 340 if (vmw_connector_to_ldu(connector)->pref_active)
304 if (vmw_connector_to_ldu(connector)->base.unit == 0)
305 return connector_status_connected; 341 return connector_status_connected;
306 return connector_status_disconnected; 342 return connector_status_disconnected;
307} 343}
@@ -312,10 +348,9 @@ static struct drm_display_mode vmw_ldu_connector_builtin[] = {
312 752, 800, 0, 480, 489, 492, 525, 0, 348 752, 800, 0, 480, 489, 492, 525, 0,
313 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, 349 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
314 /* 800x600@60Hz */ 350 /* 800x600@60Hz */
315 { DRM_MODE("800x600", 351 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
316 DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 352 968, 1056, 0, 600, 601, 605, 628, 0,
317 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 353 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
318 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
319 /* 1024x768@60Hz */ 354 /* 1024x768@60Hz */
320 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, 355 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
321 1184, 1344, 0, 768, 771, 777, 806, 0, 356 1184, 1344, 0, 768, 771, 777, 806, 0,
@@ -387,10 +422,34 @@ static struct drm_display_mode vmw_ldu_connector_builtin[] = {
387static int vmw_ldu_connector_fill_modes(struct drm_connector *connector, 422static int vmw_ldu_connector_fill_modes(struct drm_connector *connector,
388 uint32_t max_width, uint32_t max_height) 423 uint32_t max_width, uint32_t max_height)
389{ 424{
425 struct vmw_legacy_display_unit *ldu = vmw_connector_to_ldu(connector);
390 struct drm_device *dev = connector->dev; 426 struct drm_device *dev = connector->dev;
391 struct drm_display_mode *mode = NULL; 427 struct drm_display_mode *mode = NULL;
428 struct drm_display_mode prefmode = { DRM_MODE("preferred",
429 DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
430 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
431 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
432 };
392 int i; 433 int i;
393 434
435 /* Add preferred mode */
436 {
437 mode = drm_mode_duplicate(dev, &prefmode);
438 if (!mode)
439 return 0;
440 mode->hdisplay = ldu->pref_width;
441 mode->vdisplay = ldu->pref_height;
442 mode->vrefresh = drm_mode_vrefresh(mode);
443 drm_mode_probed_add(connector, mode);
444
445 if (ldu->pref_mode) {
446 list_del_init(&ldu->pref_mode->head);
447 drm_mode_destroy(dev, ldu->pref_mode);
448 }
449
450 ldu->pref_mode = mode;
451 }
452
394 for (i = 0; vmw_ldu_connector_builtin[i].type != 0; i++) { 453 for (i = 0; vmw_ldu_connector_builtin[i].type != 0; i++) {
395 if (vmw_ldu_connector_builtin[i].hdisplay > max_width || 454 if (vmw_ldu_connector_builtin[i].hdisplay > max_width ||
396 vmw_ldu_connector_builtin[i].vdisplay > max_height) 455 vmw_ldu_connector_builtin[i].vdisplay > max_height)
@@ -443,18 +502,21 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
443 if (!ldu) 502 if (!ldu)
444 return -ENOMEM; 503 return -ENOMEM;
445 504
446 ldu->unit = unit; 505 ldu->base.unit = unit;
447 crtc = &ldu->base.crtc; 506 crtc = &ldu->base.crtc;
448 encoder = &ldu->base.encoder; 507 encoder = &ldu->base.encoder;
449 connector = &ldu->base.connector; 508 connector = &ldu->base.connector;
450 509
510 INIT_LIST_HEAD(&ldu->active);
511
512 ldu->pref_active = (unit == 0);
513 ldu->pref_width = 800;
514 ldu->pref_height = 600;
515 ldu->pref_mode = NULL;
516
451 drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, 517 drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
452 DRM_MODE_CONNECTOR_LVDS); 518 DRM_MODE_CONNECTOR_LVDS);
453 /* Initial status */ 519 connector->status = vmw_ldu_connector_detect(connector);
454 if (unit == 0)
455 connector->status = connector_status_connected;
456 else
457 connector->status = connector_status_disconnected;
458 520
459 drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, 521 drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
460 DRM_MODE_ENCODER_LVDS); 522 DRM_MODE_ENCODER_LVDS);
@@ -462,8 +524,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
462 encoder->possible_crtcs = (1 << unit); 524 encoder->possible_crtcs = (1 << unit);
463 encoder->possible_clones = 0; 525 encoder->possible_clones = 0;
464 526
465 INIT_LIST_HEAD(&ldu->active);
466
467 drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs); 527 drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs);
468 528
469 drm_connector_attach_property(connector, 529 drm_connector_attach_property(connector,
@@ -487,18 +547,22 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
487 547
488 INIT_LIST_HEAD(&dev_priv->ldu_priv->active); 548 INIT_LIST_HEAD(&dev_priv->ldu_priv->active);
489 dev_priv->ldu_priv->num_active = 0; 549 dev_priv->ldu_priv->num_active = 0;
550 dev_priv->ldu_priv->last_num_active = 0;
490 dev_priv->ldu_priv->fb = NULL; 551 dev_priv->ldu_priv->fb = NULL;
491 552
492 drm_mode_create_dirty_info_property(dev_priv->dev); 553 drm_mode_create_dirty_info_property(dev_priv->dev);
493 554
494 vmw_ldu_init(dev_priv, 0); 555 vmw_ldu_init(dev_priv, 0);
495 vmw_ldu_init(dev_priv, 1); 556 /* for old hardware without multimon only enable one display */
496 vmw_ldu_init(dev_priv, 2); 557 if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
497 vmw_ldu_init(dev_priv, 3); 558 vmw_ldu_init(dev_priv, 1);
498 vmw_ldu_init(dev_priv, 4); 559 vmw_ldu_init(dev_priv, 2);
499 vmw_ldu_init(dev_priv, 5); 560 vmw_ldu_init(dev_priv, 3);
500 vmw_ldu_init(dev_priv, 6); 561 vmw_ldu_init(dev_priv, 4);
501 vmw_ldu_init(dev_priv, 7); 562 vmw_ldu_init(dev_priv, 5);
563 vmw_ldu_init(dev_priv, 6);
564 vmw_ldu_init(dev_priv, 7);
565 }
502 566
503 return 0; 567 return 0;
504} 568}
@@ -514,3 +578,42 @@ int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv)
514 578
515 return 0; 579 return 0;
516} 580}
581
582int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num,
583 struct drm_vmw_rect *rects)
584{
585 struct drm_device *dev = dev_priv->dev;
586 struct vmw_legacy_display_unit *ldu;
587 struct drm_connector *con;
588 int i;
589
590 mutex_lock(&dev->mode_config.mutex);
591
592#if 0
593 DRM_INFO("%s: new layout ", __func__);
594 for (i = 0; i < (int)num; i++)
595 DRM_INFO("(%i, %i %ux%u) ", rects[i].x, rects[i].y,
596 rects[i].w, rects[i].h);
597 DRM_INFO("\n");
598#else
599 (void)i;
600#endif
601
602 list_for_each_entry(con, &dev->mode_config.connector_list, head) {
603 ldu = vmw_connector_to_ldu(con);
604 if (num > ldu->base.unit) {
605 ldu->pref_width = rects[ldu->base.unit].w;
606 ldu->pref_height = rects[ldu->base.unit].h;
607 ldu->pref_active = true;
608 } else {
609 ldu->pref_width = 800;
610 ldu->pref_height = 600;
611 ldu->pref_active = false;
612 }
613 con->status = vmw_ldu_connector_detect(con);
614 }
615
616 mutex_unlock(&dev->mode_config.mutex);
617
618 return 0;
619}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
index ad566c85b075..df2036ed18d5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
@@ -358,6 +358,8 @@ static int vmw_overlay_update_stream(struct vmw_private *dev_priv,
358 if (stream->buf != buf) 358 if (stream->buf != buf)
359 stream->buf = vmw_dmabuf_reference(buf); 359 stream->buf = vmw_dmabuf_reference(buf);
360 stream->saved = *arg; 360 stream->saved = *arg;
361 /* stream is no longer stopped/paused */
362 stream->paused = false;
361 363
362 return 0; 364 return 0;
363} 365}
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 441e38c95a85..b87569e96b16 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -1,12 +1,32 @@
1/* 1/*
2 * vgaarb.c 2 * vgaarb.c: Implements the VGA arbitration. For details refer to
3 * Documentation/vgaarbiter.txt
4 *
3 * 5 *
4 * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> 6 * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com> 7 * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com>
6 * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org> 8 * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org>
7 * 9 *
8 * Implements the VGA arbitration. For details refer to 10 * Permission is hereby granted, free of charge, to any person obtaining a
9 * Documentation/vgaarbiter.txt 11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice (including the next
18 * paragraph) shall be included in all copies or substantial portions of the
19 * Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS
28 * IN THE SOFTWARE.
29 *
10 */ 30 */
11 31
12#include <linux/module.h> 32#include <linux/module.h>
@@ -155,8 +175,8 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
155 (vgadev->decodes & VGA_RSRC_LEGACY_MEM)) 175 (vgadev->decodes & VGA_RSRC_LEGACY_MEM))
156 rsrc |= VGA_RSRC_LEGACY_MEM; 176 rsrc |= VGA_RSRC_LEGACY_MEM;
157 177
158 pr_devel("%s: %d\n", __func__, rsrc); 178 pr_debug("%s: %d\n", __func__, rsrc);
159 pr_devel("%s: owns: %d\n", __func__, vgadev->owns); 179 pr_debug("%s: owns: %d\n", __func__, vgadev->owns);
160 180
161 /* Check what resources we need to acquire */ 181 /* Check what resources we need to acquire */
162 wants = rsrc & ~vgadev->owns; 182 wants = rsrc & ~vgadev->owns;
@@ -268,7 +288,7 @@ static void __vga_put(struct vga_device *vgadev, unsigned int rsrc)
268{ 288{
269 unsigned int old_locks = vgadev->locks; 289 unsigned int old_locks = vgadev->locks;
270 290
271 pr_devel("%s\n", __func__); 291 pr_debug("%s\n", __func__);
272 292
273 /* Update our counters, and account for equivalent legacy resources 293 /* Update our counters, and account for equivalent legacy resources
274 * if we decode them 294 * if we decode them
@@ -575,6 +595,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev,
575 else 595 else
576 vga_decode_count--; 596 vga_decode_count--;
577 } 597 }
598 pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count);
578} 599}
579 600
580void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) 601void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace)
@@ -831,7 +852,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
831 curr_pos += 5; 852 curr_pos += 5;
832 remaining -= 5; 853 remaining -= 5;
833 854
834 pr_devel("client 0x%p called 'lock'\n", priv); 855 pr_debug("client 0x%p called 'lock'\n", priv);
835 856
836 if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { 857 if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
837 ret_val = -EPROTO; 858 ret_val = -EPROTO;
@@ -867,7 +888,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
867 curr_pos += 7; 888 curr_pos += 7;
868 remaining -= 7; 889 remaining -= 7;
869 890
870 pr_devel("client 0x%p called 'unlock'\n", priv); 891 pr_debug("client 0x%p called 'unlock'\n", priv);
871 892
872 if (strncmp(curr_pos, "all", 3) == 0) 893 if (strncmp(curr_pos, "all", 3) == 0)
873 io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; 894 io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
@@ -917,7 +938,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
917 curr_pos += 8; 938 curr_pos += 8;
918 remaining -= 8; 939 remaining -= 8;
919 940
920 pr_devel("client 0x%p called 'trylock'\n", priv); 941 pr_debug("client 0x%p called 'trylock'\n", priv);
921 942
922 if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { 943 if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
923 ret_val = -EPROTO; 944 ret_val = -EPROTO;
@@ -961,7 +982,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
961 982
962 curr_pos += 7; 983 curr_pos += 7;
963 remaining -= 7; 984 remaining -= 7;
964 pr_devel("client 0x%p called 'target'\n", priv); 985 pr_debug("client 0x%p called 'target'\n", priv);
965 /* if target is default */ 986 /* if target is default */
966 if (!strncmp(curr_pos, "default", 7)) 987 if (!strncmp(curr_pos, "default", 7))
967 pdev = pci_dev_get(vga_default_device()); 988 pdev = pci_dev_get(vga_default_device());
@@ -971,11 +992,11 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
971 ret_val = -EPROTO; 992 ret_val = -EPROTO;
972 goto done; 993 goto done;
973 } 994 }
974 pr_devel("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos, 995 pr_debug("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos,
975 domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); 996 domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
976 997
977 pbus = pci_find_bus(domain, bus); 998 pbus = pci_find_bus(domain, bus);
978 pr_devel("vgaarb: pbus %p\n", pbus); 999 pr_debug("vgaarb: pbus %p\n", pbus);
979 if (pbus == NULL) { 1000 if (pbus == NULL) {
980 pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n", 1001 pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n",
981 domain, bus); 1002 domain, bus);
@@ -983,7 +1004,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
983 goto done; 1004 goto done;
984 } 1005 }
985 pdev = pci_get_slot(pbus, devfn); 1006 pdev = pci_get_slot(pbus, devfn);
986 pr_devel("vgaarb: pdev %p\n", pdev); 1007 pr_debug("vgaarb: pdev %p\n", pdev);
987 if (!pdev) { 1008 if (!pdev) {
988 pr_err("vgaarb: invalid PCI address %x:%x\n", 1009 pr_err("vgaarb: invalid PCI address %x:%x\n",
989 bus, devfn); 1010 bus, devfn);
@@ -993,7 +1014,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
993 } 1014 }
994 1015
995 vgadev = vgadev_find(pdev); 1016 vgadev = vgadev_find(pdev);
996 pr_devel("vgaarb: vgadev %p\n", vgadev); 1017 pr_debug("vgaarb: vgadev %p\n", vgadev);
997 if (vgadev == NULL) { 1018 if (vgadev == NULL) {
998 pr_err("vgaarb: this pci device is not a vga device\n"); 1019 pr_err("vgaarb: this pci device is not a vga device\n");
999 pci_dev_put(pdev); 1020 pci_dev_put(pdev);
@@ -1029,7 +1050,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
1029 } else if (strncmp(curr_pos, "decodes ", 8) == 0) { 1050 } else if (strncmp(curr_pos, "decodes ", 8) == 0) {
1030 curr_pos += 8; 1051 curr_pos += 8;
1031 remaining -= 8; 1052 remaining -= 8;
1032 pr_devel("vgaarb: client 0x%p called 'decodes'\n", priv); 1053 pr_debug("vgaarb: client 0x%p called 'decodes'\n", priv);
1033 1054
1034 if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { 1055 if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
1035 ret_val = -EPROTO; 1056 ret_val = -EPROTO;
@@ -1058,7 +1079,7 @@ static unsigned int vga_arb_fpoll(struct file *file, poll_table * wait)
1058{ 1079{
1059 struct vga_arb_private *priv = file->private_data; 1080 struct vga_arb_private *priv = file->private_data;
1060 1081
1061 pr_devel("%s\n", __func__); 1082 pr_debug("%s\n", __func__);
1062 1083
1063 if (priv == NULL) 1084 if (priv == NULL)
1064 return -ENODEV; 1085 return -ENODEV;
@@ -1071,7 +1092,7 @@ static int vga_arb_open(struct inode *inode, struct file *file)
1071 struct vga_arb_private *priv; 1092 struct vga_arb_private *priv;
1072 unsigned long flags; 1093 unsigned long flags;
1073 1094
1074 pr_devel("%s\n", __func__); 1095 pr_debug("%s\n", __func__);
1075 1096
1076 priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL); 1097 priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL);
1077 if (priv == NULL) 1098 if (priv == NULL)
@@ -1101,7 +1122,7 @@ static int vga_arb_release(struct inode *inode, struct file *file)
1101 unsigned long flags; 1122 unsigned long flags;
1102 int i; 1123 int i;
1103 1124
1104 pr_devel("%s\n", __func__); 1125 pr_debug("%s\n", __func__);
1105 1126
1106 if (priv == NULL) 1127 if (priv == NULL)
1107 return -ENODEV; 1128 return -ENODEV;
@@ -1112,7 +1133,7 @@ static int vga_arb_release(struct inode *inode, struct file *file)
1112 uc = &priv->cards[i]; 1133 uc = &priv->cards[i];
1113 if (uc->pdev == NULL) 1134 if (uc->pdev == NULL)
1114 continue; 1135 continue;
1115 pr_devel("uc->io_cnt == %d, uc->mem_cnt == %d\n", 1136 pr_debug("uc->io_cnt == %d, uc->mem_cnt == %d\n",
1116 uc->io_cnt, uc->mem_cnt); 1137 uc->io_cnt, uc->mem_cnt);
1117 while (uc->io_cnt--) 1138 while (uc->io_cnt--)
1118 vga_put(uc->pdev, VGA_RSRC_LEGACY_IO); 1139 vga_put(uc->pdev, VGA_RSRC_LEGACY_IO);
@@ -1165,7 +1186,7 @@ static int pci_notify(struct notifier_block *nb, unsigned long action,
1165 struct pci_dev *pdev = to_pci_dev(dev); 1186 struct pci_dev *pdev = to_pci_dev(dev);
1166 bool notify = false; 1187 bool notify = false;
1167 1188
1168 pr_devel("%s\n", __func__); 1189 pr_debug("%s\n", __func__);
1169 1190
1170 /* For now we're only intereted in devices added and removed. I didn't 1191 /* For now we're only intereted in devices added and removed. I didn't
1171 * test this thing here, so someone needs to double check for the 1192 * test this thing here, so someone needs to double check for the
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
index 4086c7257f91..f13c843a2964 100644
--- a/drivers/hwmon/adt7411.c
+++ b/drivers/hwmon/adt7411.c
@@ -316,7 +316,6 @@ static int __devinit adt7411_probe(struct i2c_client *client,
316 exit_remove: 316 exit_remove:
317 sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); 317 sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
318 exit_free: 318 exit_free:
319 i2c_set_clientdata(client, NULL);
320 kfree(data); 319 kfree(data);
321 return ret; 320 return ret;
322} 321}
@@ -327,7 +326,6 @@ static int __devexit adt7411_remove(struct i2c_client *client)
327 326
328 hwmon_device_unregister(data->hwmon_dev); 327 hwmon_device_unregister(data->hwmon_dev);
329 sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); 328 sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
330 i2c_set_clientdata(client, NULL);
331 kfree(data); 329 kfree(data);
332 return 0; 330 return 0;
333} 331}
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c
index 0f388adc6187..3b973f30b1f6 100644
--- a/drivers/hwmon/asc7621.c
+++ b/drivers/hwmon/asc7621.c
@@ -1141,7 +1141,6 @@ exit_remove:
1141 &(asc7621_params[i].sda.dev_attr)); 1141 &(asc7621_params[i].sda.dev_attr));
1142 } 1142 }
1143 1143
1144 i2c_set_clientdata(client, NULL);
1145 kfree(data); 1144 kfree(data);
1146 return err; 1145 return err;
1147} 1146}
@@ -1196,7 +1195,6 @@ static int asc7621_remove(struct i2c_client *client)
1196 &(asc7621_params[i].sda.dev_attr)); 1195 &(asc7621_params[i].sda.dev_attr));
1197 } 1196 }
1198 1197
1199 i2c_set_clientdata(client, NULL);
1200 kfree(data); 1198 kfree(data);
1201 return 0; 1199 return 0;
1202} 1200}
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index bad2cf3ef4a4..0f58ecc5334d 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -662,7 +662,6 @@ exit_remove:
662 sysfs_remove_group(&client->dev.kobj, &f75375_group); 662 sysfs_remove_group(&client->dev.kobj, &f75375_group);
663exit_free: 663exit_free:
664 kfree(data); 664 kfree(data);
665 i2c_set_clientdata(client, NULL);
666 return err; 665 return err;
667} 666}
668 667
@@ -672,7 +671,6 @@ static int f75375_remove(struct i2c_client *client)
672 hwmon_device_unregister(data->hwmon_dev); 671 hwmon_device_unregister(data->hwmon_dev);
673 sysfs_remove_group(&client->dev.kobj, &f75375_group); 672 sysfs_remove_group(&client->dev.kobj, &f75375_group);
674 kfree(data); 673 kfree(data);
675 i2c_set_clientdata(client, NULL);
676 return 0; 674 return 0;
677} 675}
678 676
diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c
index 09ea12e0a551..1f63d1a3af5e 100644
--- a/drivers/hwmon/g760a.c
+++ b/drivers/hwmon/g760a.c
@@ -236,7 +236,6 @@ error_hwmon_device_register:
236 sysfs_remove_group(&client->dev.kobj, &g760a_group); 236 sysfs_remove_group(&client->dev.kobj, &g760a_group);
237error_sysfs_create_group: 237error_sysfs_create_group:
238 kfree(data); 238 kfree(data);
239 i2c_set_clientdata(client, NULL);
240 239
241 return err; 240 return err;
242} 241}
@@ -247,7 +246,6 @@ static int g760a_remove(struct i2c_client *client)
247 hwmon_device_unregister(data->hwmon_dev); 246 hwmon_device_unregister(data->hwmon_dev);
248 sysfs_remove_group(&client->dev.kobj, &g760a_group); 247 sysfs_remove_group(&client->dev.kobj, &g760a_group);
249 kfree(data); 248 kfree(data);
250 i2c_set_clientdata(client, NULL);
251 249
252 return 0; 250 return 0;
253} 251}
diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c
index 4d1b76bc8148..29b9030d42c3 100644
--- a/drivers/hwmon/lm73.c
+++ b/drivers/hwmon/lm73.c
@@ -136,7 +136,6 @@ static int lm73_remove(struct i2c_client *client)
136 136
137 hwmon_device_unregister(hwmon_dev); 137 hwmon_device_unregister(hwmon_dev);
138 sysfs_remove_group(&client->dev.kobj, &lm73_group); 138 sysfs_remove_group(&client->dev.kobj, &lm73_group);
139 i2c_set_clientdata(client, NULL);
140 return 0; 139 return 0;
141} 140}
142 141
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 56463428a419..393f354f92a4 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -192,7 +192,6 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
192exit_remove: 192exit_remove:
193 sysfs_remove_group(&client->dev.kobj, &lm75_group); 193 sysfs_remove_group(&client->dev.kobj, &lm75_group);
194exit_free: 194exit_free:
195 i2c_set_clientdata(client, NULL);
196 kfree(data); 195 kfree(data);
197 return status; 196 return status;
198} 197}
@@ -204,7 +203,6 @@ static int lm75_remove(struct i2c_client *client)
204 hwmon_device_unregister(data->hwmon_dev); 203 hwmon_device_unregister(data->hwmon_dev);
205 sysfs_remove_group(&client->dev.kobj, &lm75_group); 204 sysfs_remove_group(&client->dev.kobj, &lm75_group);
206 lm75_write_value(client, LM75_REG_CONF, data->orig_conf); 205 lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
207 i2c_set_clientdata(client, NULL);
208 kfree(data); 206 kfree(data);
209 return 0; 207 return 0;
210} 208}
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
index 8fc8eb8cba47..94741d42112d 100644
--- a/drivers/hwmon/lm95241.c
+++ b/drivers/hwmon/lm95241.c
@@ -399,7 +399,6 @@ static int lm95241_remove(struct i2c_client *client)
399 hwmon_device_unregister(data->hwmon_dev); 399 hwmon_device_unregister(data->hwmon_dev);
400 sysfs_remove_group(&client->dev.kobj, &lm95241_group); 400 sysfs_remove_group(&client->dev.kobj, &lm95241_group);
401 401
402 i2c_set_clientdata(client, NULL);
403 kfree(data); 402 kfree(data);
404 return 0; 403 return 0;
405} 404}
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index 8013895a1faf..93187c3cb5e7 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -224,7 +224,6 @@ fail_remove_sysfs:
224fail_restore_config: 224fail_restore_config:
225 tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig); 225 tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig);
226fail_free: 226fail_free:
227 i2c_set_clientdata(client, NULL);
228 kfree(tmp102); 227 kfree(tmp102);
229 228
230 return status; 229 return status;
@@ -247,7 +246,6 @@ static int __devexit tmp102_remove(struct i2c_client *client)
247 config | TMP102_CONF_SD); 246 config | TMP102_CONF_SD);
248 } 247 }
249 248
250 i2c_set_clientdata(client, NULL);
251 kfree(tmp102); 249 kfree(tmp102);
252 250
253 return 0; 251 return 0;
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index 738c472ece27..6b4165c12092 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -295,7 +295,6 @@ exit_remove:
295 sysfs_remove_group(&client->dev.kobj, &tmp421_group); 295 sysfs_remove_group(&client->dev.kobj, &tmp421_group);
296 296
297exit_free: 297exit_free:
298 i2c_set_clientdata(client, NULL);
299 kfree(data); 298 kfree(data);
300 299
301 return err; 300 return err;
@@ -308,7 +307,6 @@ static int tmp421_remove(struct i2c_client *client)
308 hwmon_device_unregister(data->hwmon_dev); 307 hwmon_device_unregister(data->hwmon_dev);
309 sysfs_remove_group(&client->dev.kobj, &tmp421_group); 308 sysfs_remove_group(&client->dev.kobj, &tmp421_group);
310 309
311 i2c_set_clientdata(client, NULL);
312 kfree(data); 310 kfree(data);
313 311
314 return 0; 312 return 0;
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 32d4adee73db..c84b9b4e6960 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -1197,7 +1197,6 @@ ERROR4:
1197 if (data->lm75[1]) 1197 if (data->lm75[1])
1198 i2c_unregister_device(data->lm75[1]); 1198 i2c_unregister_device(data->lm75[1]);
1199ERROR3: 1199ERROR3:
1200 i2c_set_clientdata(client, NULL);
1201 kfree(data); 1200 kfree(data);
1202ERROR1: 1201ERROR1:
1203 return err; 1202 return err;
@@ -1219,7 +1218,6 @@ w83781d_remove(struct i2c_client *client)
1219 if (data->lm75[1]) 1218 if (data->lm75[1])
1220 i2c_unregister_device(data->lm75[1]); 1219 i2c_unregister_device(data->lm75[1]);
1221 1220
1222 i2c_set_clientdata(client, NULL);
1223 kfree(data); 1221 kfree(data);
1224 1222
1225 return 0; 1223 return 0;
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 87ab0568bb0e..bceafbfa7268 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -475,6 +475,26 @@ config I2C_PASEMI
475 help 475 help
476 Supports the PA Semi PWRficient on-chip SMBus interfaces. 476 Supports the PA Semi PWRficient on-chip SMBus interfaces.
477 477
478config I2C_PCA_PLATFORM
479 tristate "PCA9564/PCA9665 as platform device"
480 select I2C_ALGOPCA
481 default n
482 help
483 This driver supports a memory mapped Philips PCA9564/PCA9665
484 parallel bus to I2C bus controller.
485
486 This driver can also be built as a module. If so, the module
487 will be called i2c-pca-platform.
488
489config I2C_PMCMSP
490 tristate "PMC MSP I2C TWI Controller"
491 depends on PMC_MSP
492 help
493 This driver supports the PMC TWI controller on MSP devices.
494
495 This driver can also be built as module. If so, the module
496 will be called i2c-pmcmsp.
497
478config I2C_PNX 498config I2C_PNX
479 tristate "I2C bus support for Philips PNX targets" 499 tristate "I2C bus support for Philips PNX targets"
480 depends on ARCH_PNX4008 500 depends on ARCH_PNX4008
@@ -711,26 +731,6 @@ config I2C_PCA_ISA
711 delays when I2C/SMBus chip drivers are loaded (e.g. at boot 731 delays when I2C/SMBus chip drivers are loaded (e.g. at boot
712 time). If unsure, say N. 732 time). If unsure, say N.
713 733
714config I2C_PCA_PLATFORM
715 tristate "PCA9564/PCA9665 as platform device"
716 select I2C_ALGOPCA
717 default n
718 help
719 This driver supports a memory mapped Philips PCA9564/PCA9665
720 parallel bus to I2C bus controller.
721
722 This driver can also be built as a module. If so, the module
723 will be called i2c-pca-platform.
724
725config I2C_PMCMSP
726 tristate "PMC MSP I2C TWI Controller"
727 depends on PMC_MSP
728 help
729 This driver supports the PMC TWI controller on MSP devices.
730
731 This driver can also be built as module. If so, the module
732 will be called i2c-pmcmsp.
733
734config I2C_SIBYTE 734config I2C_SIBYTE
735 tristate "SiByte SMBus interface" 735 tristate "SiByte SMBus interface"
736 depends on SIBYTE_SB1xxx_SOC 736 depends on SIBYTE_SB1xxx_SOC
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 097236f631e8..936880bd1dc5 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
27obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o 27obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
28obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o 28obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
29 29
30# Embebbed system I2C/SMBus host controller drivers 30# Embedded system I2C/SMBus host controller drivers
31obj-$(CONFIG_I2C_AT91) += i2c-at91.o 31obj-$(CONFIG_I2C_AT91) += i2c-at91.o
32obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o 32obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
33obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o 33obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
@@ -46,6 +46,8 @@ obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
46obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o 46obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
47obj-$(CONFIG_I2C_OMAP) += i2c-omap.o 47obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
48obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o 48obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
49obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
50obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o
49obj-$(CONFIG_I2C_PNX) += i2c-pnx.o 51obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
50obj-$(CONFIG_I2C_PXA) += i2c-pxa.o 52obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
51obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o 53obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
@@ -68,8 +70,6 @@ obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o
68obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o 70obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o
69obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o 71obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
70obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o 72obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
71obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
72obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o
73obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o 73obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
74obj-$(CONFIG_I2C_STUB) += i2c-stub.o 74obj-$(CONFIG_I2C_STUB) += i2c-stub.o
75obj-$(CONFIG_SCx200_ACB) += scx200_acb.o 75obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e0f833cca3f1..1cca2631e5b3 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -47,7 +47,6 @@ static DEFINE_MUTEX(core_lock);
47static DEFINE_IDR(i2c_adapter_idr); 47static DEFINE_IDR(i2c_adapter_idr);
48 48
49static struct device_type i2c_client_type; 49static struct device_type i2c_client_type;
50static int i2c_check_addr(struct i2c_adapter *adapter, int addr);
51static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); 50static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
52 51
53/* ------------------------------------------------------------------------- */ 52/* ------------------------------------------------------------------------- */
@@ -371,6 +370,59 @@ struct i2c_client *i2c_verify_client(struct device *dev)
371EXPORT_SYMBOL(i2c_verify_client); 370EXPORT_SYMBOL(i2c_verify_client);
372 371
373 372
373/* This is a permissive address validity check, I2C address map constraints
374 * are purposedly not enforced, except for the general call address. */
375static int i2c_check_client_addr_validity(const struct i2c_client *client)
376{
377 if (client->flags & I2C_CLIENT_TEN) {
378 /* 10-bit address, all values are valid */
379 if (client->addr > 0x3ff)
380 return -EINVAL;
381 } else {
382 /* 7-bit address, reject the general call address */
383 if (client->addr == 0x00 || client->addr > 0x7f)
384 return -EINVAL;
385 }
386 return 0;
387}
388
389/* And this is a strict address validity check, used when probing. If a
390 * device uses a reserved address, then it shouldn't be probed. 7-bit
391 * addressing is assumed, 10-bit address devices are rare and should be
392 * explicitly enumerated. */
393static int i2c_check_addr_validity(unsigned short addr)
394{
395 /*
396 * Reserved addresses per I2C specification:
397 * 0x00 General call address / START byte
398 * 0x01 CBUS address
399 * 0x02 Reserved for different bus format
400 * 0x03 Reserved for future purposes
401 * 0x04-0x07 Hs-mode master code
402 * 0x78-0x7b 10-bit slave addressing
403 * 0x7c-0x7f Reserved for future purposes
404 */
405 if (addr < 0x08 || addr > 0x77)
406 return -EINVAL;
407 return 0;
408}
409
410static int __i2c_check_addr_busy(struct device *dev, void *addrp)
411{
412 struct i2c_client *client = i2c_verify_client(dev);
413 int addr = *(int *)addrp;
414
415 if (client && client->addr == addr)
416 return -EBUSY;
417 return 0;
418}
419
420static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
421{
422 return device_for_each_child(&adapter->dev, &addr,
423 __i2c_check_addr_busy);
424}
425
374/** 426/**
375 * i2c_new_device - instantiate an i2c device 427 * i2c_new_device - instantiate an i2c device
376 * @adap: the adapter managing the device 428 * @adap: the adapter managing the device
@@ -410,8 +462,16 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
410 462
411 strlcpy(client->name, info->type, sizeof(client->name)); 463 strlcpy(client->name, info->type, sizeof(client->name));
412 464
465 /* Check for address validity */
466 status = i2c_check_client_addr_validity(client);
467 if (status) {
468 dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",
469 client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);
470 goto out_err_silent;
471 }
472
413 /* Check for address business */ 473 /* Check for address business */
414 status = i2c_check_addr(adap, client->addr); 474 status = i2c_check_addr_busy(adap, client->addr);
415 if (status) 475 if (status)
416 goto out_err; 476 goto out_err;
417 477
@@ -436,6 +496,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
436out_err: 496out_err:
437 dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x " 497 dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
438 "(%d)\n", client->name, client->addr, status); 498 "(%d)\n", client->name, client->addr, status);
499out_err_silent:
439 kfree(client); 500 kfree(client);
440 return NULL; 501 return NULL;
441} 502}
@@ -561,15 +622,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
561 return -EINVAL; 622 return -EINVAL;
562 } 623 }
563 624
564 if (info.addr < 0x03 || info.addr > 0x77) {
565 dev_err(dev, "%s: Invalid I2C address 0x%hx\n", "new_device",
566 info.addr);
567 return -EINVAL;
568 }
569
570 client = i2c_new_device(adap, &info); 625 client = i2c_new_device(adap, &info);
571 if (!client) 626 if (!client)
572 return -EEXIST; 627 return -EINVAL;
573 628
574 /* Keep track of the added device */ 629 /* Keep track of the added device */
575 i2c_lock_adapter(adap); 630 i2c_lock_adapter(adap);
@@ -1024,21 +1079,6 @@ EXPORT_SYMBOL(i2c_del_driver);
1024 1079
1025/* ------------------------------------------------------------------------- */ 1080/* ------------------------------------------------------------------------- */
1026 1081
1027static int __i2c_check_addr(struct device *dev, void *addrp)
1028{
1029 struct i2c_client *client = i2c_verify_client(dev);
1030 int addr = *(int *)addrp;
1031
1032 if (client && client->addr == addr)
1033 return -EBUSY;
1034 return 0;
1035}
1036
1037static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
1038{
1039 return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
1040}
1041
1042/** 1082/**
1043 * i2c_use_client - increments the reference count of the i2c client structure 1083 * i2c_use_client - increments the reference count of the i2c client structure
1044 * @client: the client being referenced 1084 * @client: the client being referenced
@@ -1277,6 +1317,41 @@ EXPORT_SYMBOL(i2c_master_recv);
1277 * ---------------------------------------------------- 1317 * ----------------------------------------------------
1278 */ 1318 */
1279 1319
1320/*
1321 * Legacy default probe function, mostly relevant for SMBus. The default
1322 * probe method is a quick write, but it is known to corrupt the 24RF08
1323 * EEPROMs due to a state machine bug, and could also irreversibly
1324 * write-protect some EEPROMs, so for address ranges 0x30-0x37 and 0x50-0x5f,
1325 * we use a short byte read instead. Also, some bus drivers don't implement
1326 * quick write, so we fallback to a byte read in that case too.
1327 * On x86, there is another special case for FSC hardware monitoring chips,
1328 * which want regular byte reads (address 0x73.) Fortunately, these are the
1329 * only known chips using this I2C address on PC hardware.
1330 * Returns 1 if probe succeeded, 0 if not.
1331 */
1332static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr)
1333{
1334 int err;
1335 union i2c_smbus_data dummy;
1336
1337#ifdef CONFIG_X86
1338 if (addr == 0x73 && (adap->class & I2C_CLASS_HWMON)
1339 && i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE_DATA))
1340 err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
1341 I2C_SMBUS_BYTE_DATA, &dummy);
1342 else
1343#endif
1344 if ((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50
1345 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
1346 err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
1347 I2C_SMBUS_BYTE, &dummy);
1348 else
1349 err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0,
1350 I2C_SMBUS_QUICK, NULL);
1351
1352 return err >= 0;
1353}
1354
1280static int i2c_detect_address(struct i2c_client *temp_client, 1355static int i2c_detect_address(struct i2c_client *temp_client,
1281 struct i2c_driver *driver) 1356 struct i2c_driver *driver)
1282{ 1357{
@@ -1286,34 +1361,20 @@ static int i2c_detect_address(struct i2c_client *temp_client,
1286 int err; 1361 int err;
1287 1362
1288 /* Make sure the address is valid */ 1363 /* Make sure the address is valid */
1289 if (addr < 0x03 || addr > 0x77) { 1364 err = i2c_check_addr_validity(addr);
1365 if (err) {
1290 dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n", 1366 dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
1291 addr); 1367 addr);
1292 return -EINVAL; 1368 return err;
1293 } 1369 }
1294 1370
1295 /* Skip if already in use */ 1371 /* Skip if already in use */
1296 if (i2c_check_addr(adapter, addr)) 1372 if (i2c_check_addr_busy(adapter, addr))
1297 return 0; 1373 return 0;
1298 1374
1299 /* Make sure there is something at this address */ 1375 /* Make sure there is something at this address */
1300 if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) { 1376 if (!i2c_default_probe(adapter, addr))
1301 /* Special probe for FSC hwmon chips */ 1377 return 0;
1302 union i2c_smbus_data dummy;
1303
1304 if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0,
1305 I2C_SMBUS_BYTE_DATA, &dummy) < 0)
1306 return 0;
1307 } else {
1308 if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
1309 I2C_SMBUS_QUICK, NULL) < 0)
1310 return 0;
1311
1312 /* Prevent 24RF08 corruption */
1313 if ((addr & ~0x0f) == 0x50)
1314 i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
1315 I2C_SMBUS_QUICK, NULL);
1316 }
1317 1378
1318 /* Finally call the custom detection function */ 1379 /* Finally call the custom detection function */
1319 memset(&info, 0, sizeof(struct i2c_board_info)); 1380 memset(&info, 0, sizeof(struct i2c_board_info));
@@ -1407,42 +1468,22 @@ i2c_new_probed_device(struct i2c_adapter *adap,
1407 1468
1408 for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { 1469 for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
1409 /* Check address validity */ 1470 /* Check address validity */
1410 if (addr_list[i] < 0x03 || addr_list[i] > 0x77) { 1471 if (i2c_check_addr_validity(addr_list[i]) < 0) {
1411 dev_warn(&adap->dev, "Invalid 7-bit address " 1472 dev_warn(&adap->dev, "Invalid 7-bit address "
1412 "0x%02x\n", addr_list[i]); 1473 "0x%02x\n", addr_list[i]);
1413 continue; 1474 continue;
1414 } 1475 }
1415 1476
1416 /* Check address availability */ 1477 /* Check address availability */
1417 if (i2c_check_addr(adap, addr_list[i])) { 1478 if (i2c_check_addr_busy(adap, addr_list[i])) {
1418 dev_dbg(&adap->dev, "Address 0x%02x already in " 1479 dev_dbg(&adap->dev, "Address 0x%02x already in "
1419 "use, not probing\n", addr_list[i]); 1480 "use, not probing\n", addr_list[i]);
1420 continue; 1481 continue;
1421 } 1482 }
1422 1483
1423 /* Test address responsiveness 1484 /* Test address responsiveness */
1424 The default probe method is a quick write, but it is known 1485 if (i2c_default_probe(adap, addr_list[i]))
1425 to corrupt the 24RF08 EEPROMs due to a state machine bug, 1486 break;
1426 and could also irreversibly write-protect some EEPROMs, so
1427 for address ranges 0x30-0x37 and 0x50-0x5f, we use a byte
1428 read instead. Also, some bus drivers don't implement
1429 quick write, so we fallback to a byte read it that case
1430 too. */
1431 if ((addr_list[i] & ~0x07) == 0x30
1432 || (addr_list[i] & ~0x0f) == 0x50
1433 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
1434 union i2c_smbus_data data;
1435
1436 if (i2c_smbus_xfer(adap, addr_list[i], 0,
1437 I2C_SMBUS_READ, 0,
1438 I2C_SMBUS_BYTE, &data) >= 0)
1439 break;
1440 } else {
1441 if (i2c_smbus_xfer(adap, addr_list[i], 0,
1442 I2C_SMBUS_WRITE, 0,
1443 I2C_SMBUS_QUICK, NULL) >= 0)
1444 break;
1445 }
1446 } 1487 }
1447 1488
1448 if (addr_list[i] == I2C_CLIENT_END) { 1489 if (addr_list[i] == I2C_CLIENT_END) {
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index a24e0bfe9201..f61ccc1e5ea3 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -173,7 +173,6 @@ static int smbalert_remove(struct i2c_client *ara)
173 173
174 cancel_work_sync(&alert->alert); 174 cancel_work_sync(&alert->alert);
175 175
176 i2c_set_clientdata(ara, NULL);
177 kfree(alert); 176 kfree(alert);
178 return 0; 177 return 0;
179} 178}
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 183fa38760d8..ebcf8e470a97 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -1400,8 +1400,11 @@ static struct of_device_id pmac_ide_macio_match[] =
1400 1400
1401static struct macio_driver pmac_ide_macio_driver = 1401static struct macio_driver pmac_ide_macio_driver =
1402{ 1402{
1403 .name = "ide-pmac", 1403 .driver = {
1404 .match_table = pmac_ide_macio_match, 1404 .name = "ide-pmac",
1405 .owner = THIS_MODULE,
1406 .of_match_table = pmac_ide_macio_match,
1407 },
1405 .probe = pmac_ide_macio_attach, 1408 .probe = pmac_ide_macio_attach,
1406 .suspend = pmac_ide_macio_suspend, 1409 .suspend = pmac_ide_macio_suspend,
1407 .resume = pmac_ide_macio_resume, 1410 .resume = pmac_ide_macio_resume,
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c
index edef8527eb34..844954bf417b 100644
--- a/drivers/infiniband/hw/qib/qib_fs.c
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -542,10 +542,8 @@ static int qibfs_fill_super(struct super_block *sb, void *data, int silent)
542 list_for_each_entry_safe(dd, tmp, &qib_dev_list, list) { 542 list_for_each_entry_safe(dd, tmp, &qib_dev_list, list) {
543 spin_unlock_irqrestore(&qib_devs_lock, flags); 543 spin_unlock_irqrestore(&qib_devs_lock, flags);
544 ret = add_cntr_files(sb, dd); 544 ret = add_cntr_files(sb, dd);
545 if (ret) { 545 if (ret)
546 deactivate_super(sb);
547 goto bail; 546 goto bail;
548 }
549 spin_lock_irqsave(&qib_devs_lock, flags); 547 spin_lock_irqsave(&qib_devs_lock, flags);
550 } 548 }
551 549
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c
index 4771ab172b59..744600eff222 100644
--- a/drivers/input/keyboard/adp5588-keys.c
+++ b/drivers/input/keyboard/adp5588-keys.c
@@ -287,7 +287,6 @@ static int __devexit adp5588_remove(struct i2c_client *client)
287 free_irq(client->irq, kpad); 287 free_irq(client->irq, kpad);
288 cancel_delayed_work_sync(&kpad->work); 288 cancel_delayed_work_sync(&kpad->work);
289 input_unregister_device(kpad->input); 289 input_unregister_device(kpad->input);
290 i2c_set_clientdata(client, NULL);
291 kfree(kpad); 290 kfree(kpad);
292 291
293 return 0; 292 return 0;
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index bc696931fed7..40b032f0e32c 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -778,8 +778,6 @@ static int __devexit lm8323_remove(struct i2c_client *client)
778 struct lm8323_chip *lm = i2c_get_clientdata(client); 778 struct lm8323_chip *lm = i2c_get_clientdata(client);
779 int i; 779 int i;
780 780
781 i2c_set_clientdata(client, NULL);
782
783 disable_irq_wake(client->irq); 781 disable_irq_wake(client->irq);
784 free_irq(client->irq, lm); 782 free_irq(client->irq, lm);
785 cancel_work_sync(&lm->work); 783 cancel_work_sync(&lm->work);
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c
index 7fc8185e5c1b..9091ff5ea808 100644
--- a/drivers/input/keyboard/max7359_keypad.c
+++ b/drivers/input/keyboard/max7359_keypad.c
@@ -265,7 +265,6 @@ static int __devexit max7359_remove(struct i2c_client *client)
265 265
266 free_irq(client->irq, keypad); 266 free_irq(client->irq, keypad);
267 input_unregister_device(keypad->input_dev); 267 input_unregister_device(keypad->input_dev);
268 i2c_set_clientdata(client, NULL);
269 kfree(keypad); 268 kfree(keypad);
270 269
271 return 0; 270 return 0;
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c
index 31f30087b591..fac695157e8a 100644
--- a/drivers/input/keyboard/qt2160.c
+++ b/drivers/input/keyboard/qt2160.c
@@ -358,7 +358,6 @@ static int __devexit qt2160_remove(struct i2c_client *client)
358 input_unregister_device(qt2160->input); 358 input_unregister_device(qt2160->input);
359 kfree(qt2160); 359 kfree(qt2160);
360 360
361 i2c_set_clientdata(client, NULL);
362 return 0; 361 return 0;
363} 362}
364 363
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 493c93f25e2a..00137bebcf97 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -316,8 +316,6 @@ static int __devexit tca6416_keypad_remove(struct i2c_client *client)
316 input_unregister_device(chip->input); 316 input_unregister_device(chip->input);
317 kfree(chip); 317 kfree(chip);
318 318
319 i2c_set_clientdata(client, NULL);
320
321 return 0; 319 return 0;
322} 320}
323 321
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
index e9adbe49f6a4..2bef8fa56c94 100644
--- a/drivers/input/misc/ad714x-i2c.c
+++ b/drivers/input/misc/ad714x-i2c.c
@@ -97,7 +97,6 @@ static int __devexit ad714x_i2c_remove(struct i2c_client *client)
97 struct ad714x_chip *chip = i2c_get_clientdata(client); 97 struct ad714x_chip *chip = i2c_get_clientdata(client);
98 98
99 ad714x_remove(chip); 99 ad714x_remove(chip);
100 i2c_set_clientdata(client, NULL);
101 100
102 return 0; 101 return 0;
103} 102}
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c
index 5c3ac4e0b055..0ac47d2898ec 100644
--- a/drivers/input/misc/pcf8574_keypad.c
+++ b/drivers/input/misc/pcf8574_keypad.c
@@ -168,8 +168,6 @@ static int __devexit pcf8574_kp_remove(struct i2c_client *client)
168 input_unregister_device(lp->idev); 168 input_unregister_device(lp->idev);
169 kfree(lp); 169 kfree(lp);
170 170
171 i2c_set_clientdata(client, NULL);
172
173 return 0; 171 return 0;
174} 172}
175 173
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c
index 8291e7399ffa..0ae62f0bcb32 100644
--- a/drivers/input/mouse/synaptics_i2c.c
+++ b/drivers/input/mouse/synaptics_i2c.c
@@ -613,7 +613,6 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client)
613 free_irq(client->irq, touch); 613 free_irq(client->irq, touch);
614 614
615 input_unregister_device(touch->input); 615 input_unregister_device(touch->input);
616 i2c_set_clientdata(client, NULL);
617 kfree(touch); 616 kfree(touch);
618 617
619 return 0; 618 return 0;
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index f34f1dbeb577..3bfe8fafc6ad 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -21,7 +21,8 @@ if SERIO
21config SERIO_I8042 21config SERIO_I8042
22 tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 22 tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
23 default y 23 default y
24 depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K && !BLACKFIN 24 depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \
25 (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN
25 help 26 help
26 i8042 is the chip over which the standard AT keyboard and PS/2 27 i8042 is the chip over which the standard AT keyboard and PS/2
27 mouse are connected to the computer. If you use these devices, 28 mouse are connected to the computer. If you use these devices,
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 2dc0c07c0469..42ba3691d908 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -508,7 +508,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
508 } 508 }
509 509
510 input_dev->name = wacom_wac->name; 510 input_dev->name = wacom_wac->name;
511 input_dev->name = wacom_wac->name;
512 input_dev->dev.parent = &intf->dev; 511 input_dev->dev.parent = &intf->dev;
513 input_dev->open = wacom_open; 512 input_dev->open = wacom_open;
514 input_dev->close = wacom_close; 513 input_dev->close = wacom_close;
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 847fd0135bcf..d564af58175c 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -300,7 +300,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
300 case 0x823: /* Intuos3 Grip Pen */ 300 case 0x823: /* Intuos3 Grip Pen */
301 case 0x813: /* Intuos3 Classic Pen */ 301 case 0x813: /* Intuos3 Classic Pen */
302 case 0x885: /* Intuos3 Marker Pen */ 302 case 0x885: /* Intuos3 Marker Pen */
303 case 0x802: /* Intuos4 Grip Pen Eraser */ 303 case 0x802: /* Intuos4 General Pen */
304 case 0x804: /* Intuos4 Marker Pen */ 304 case 0x804: /* Intuos4 Marker Pen */
305 case 0x40802: /* Intuos4 Classic Pen */ 305 case 0x40802: /* Intuos4 Classic Pen */
306 case 0x022: 306 case 0x022:
@@ -335,7 +335,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
335 case 0x81b: /* Intuos3 Classic Pen Eraser */ 335 case 0x81b: /* Intuos3 Classic Pen Eraser */
336 case 0x91b: /* Intuos3 Airbrush Eraser */ 336 case 0x91b: /* Intuos3 Airbrush Eraser */
337 case 0x80c: /* Intuos4 Marker Pen Eraser */ 337 case 0x80c: /* Intuos4 Marker Pen Eraser */
338 case 0x80a: /* Intuos4 Grip Pen Eraser */ 338 case 0x80a: /* Intuos4 General Pen Eraser */
339 case 0x4080a: /* Intuos4 Classic Pen Eraser */ 339 case 0x4080a: /* Intuos4 Classic Pen Eraser */
340 case 0x90a: /* Intuos4 Airbrush Eraser */ 340 case 0x90a: /* Intuos4 Airbrush Eraser */
341 wacom->tool[idx] = BTN_TOOL_RUBBER; 341 wacom->tool[idx] = BTN_TOOL_RUBBER;
@@ -356,6 +356,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
356 return 1; 356 return 1;
357 } 357 }
358 358
359 /* older I4 styli don't work with new Cintiqs */
360 if (!((wacom->id[idx] >> 20) & 0x01) &&
361 (features->type == WACOM_21UX2))
362 return 1;
363
359 /* Exit report */ 364 /* Exit report */
360 if ((data[1] & 0xfe) == 0x80) { 365 if ((data[1] & 0xfe) == 0x80) {
361 /* 366 /*
@@ -474,21 +479,43 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
474 input_report_abs(input, ABS_MISC, 0); 479 input_report_abs(input, ABS_MISC, 0);
475 } 480 }
476 } else { 481 } else {
477 input_report_key(input, BTN_0, (data[5] & 0x01)); 482 if (features->type == WACOM_21UX2) {
478 input_report_key(input, BTN_1, (data[5] & 0x02)); 483 input_report_key(input, BTN_0, (data[5] & 0x01));
479 input_report_key(input, BTN_2, (data[5] & 0x04)); 484 input_report_key(input, BTN_1, (data[6] & 0x01));
480 input_report_key(input, BTN_3, (data[5] & 0x08)); 485 input_report_key(input, BTN_2, (data[6] & 0x02));
481 input_report_key(input, BTN_4, (data[6] & 0x01)); 486 input_report_key(input, BTN_3, (data[6] & 0x04));
482 input_report_key(input, BTN_5, (data[6] & 0x02)); 487 input_report_key(input, BTN_4, (data[6] & 0x08));
483 input_report_key(input, BTN_6, (data[6] & 0x04)); 488 input_report_key(input, BTN_5, (data[6] & 0x10));
484 input_report_key(input, BTN_7, (data[6] & 0x08)); 489 input_report_key(input, BTN_6, (data[6] & 0x20));
485 input_report_key(input, BTN_8, (data[5] & 0x10)); 490 input_report_key(input, BTN_7, (data[6] & 0x40));
486 input_report_key(input, BTN_9, (data[6] & 0x10)); 491 input_report_key(input, BTN_8, (data[6] & 0x80));
492 input_report_key(input, BTN_9, (data[7] & 0x01));
493 input_report_key(input, BTN_A, (data[8] & 0x01));
494 input_report_key(input, BTN_B, (data[8] & 0x02));
495 input_report_key(input, BTN_C, (data[8] & 0x04));
496 input_report_key(input, BTN_X, (data[8] & 0x08));
497 input_report_key(input, BTN_Y, (data[8] & 0x10));
498 input_report_key(input, BTN_Z, (data[8] & 0x20));
499 input_report_key(input, BTN_BASE, (data[8] & 0x40));
500 input_report_key(input, BTN_BASE2, (data[8] & 0x80));
501 } else {
502 input_report_key(input, BTN_0, (data[5] & 0x01));
503 input_report_key(input, BTN_1, (data[5] & 0x02));
504 input_report_key(input, BTN_2, (data[5] & 0x04));
505 input_report_key(input, BTN_3, (data[5] & 0x08));
506 input_report_key(input, BTN_4, (data[6] & 0x01));
507 input_report_key(input, BTN_5, (data[6] & 0x02));
508 input_report_key(input, BTN_6, (data[6] & 0x04));
509 input_report_key(input, BTN_7, (data[6] & 0x08));
510 input_report_key(input, BTN_8, (data[5] & 0x10));
511 input_report_key(input, BTN_9, (data[6] & 0x10));
512 }
487 input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); 513 input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
488 input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); 514 input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
489 515
490 if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | 516 if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) |
491 data[2] | (data[3] & 0x1f) | data[4]) { 517 data[2] | (data[3] & 0x1f) | data[4] | data[8] |
518 (data[7] & 0x01)) {
492 input_report_key(input, wacom->tool[1], 1); 519 input_report_key(input, wacom->tool[1], 1);
493 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); 520 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
494 } else { 521 } else {
@@ -640,7 +667,7 @@ static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx)
640 if (!idx) 667 if (!idx)
641 input_report_key(input, BTN_TOUCH, 1); 668 input_report_key(input, BTN_TOUCH, 1);
642 input_event(input, EV_MSC, MSC_SERIAL, finger); 669 input_event(input, EV_MSC, MSC_SERIAL, finger);
643 input_sync(wacom->input); 670 input_sync(input);
644 671
645 wacom->last_finger = finger; 672 wacom->last_finger = finger;
646} 673}
@@ -826,6 +853,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
826 case INTUOS4L: 853 case INTUOS4L:
827 case CINTIQ: 854 case CINTIQ:
828 case WACOM_BEE: 855 case WACOM_BEE:
856 case WACOM_21UX2:
829 sync = wacom_intuos_irq(wacom_wac); 857 sync = wacom_intuos_irq(wacom_wac);
830 break; 858 break;
831 859
@@ -921,6 +949,17 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
921 __set_bit(BTN_STYLUS2, input_dev->keybit); 949 __set_bit(BTN_STYLUS2, input_dev->keybit);
922 break; 950 break;
923 951
952 case WACOM_21UX2:
953 __set_bit(BTN_A, input_dev->keybit);
954 __set_bit(BTN_B, input_dev->keybit);
955 __set_bit(BTN_C, input_dev->keybit);
956 __set_bit(BTN_X, input_dev->keybit);
957 __set_bit(BTN_Y, input_dev->keybit);
958 __set_bit(BTN_Z, input_dev->keybit);
959 __set_bit(BTN_BASE, input_dev->keybit);
960 __set_bit(BTN_BASE2, input_dev->keybit);
961 /* fall through */
962
924 case WACOM_BEE: 963 case WACOM_BEE:
925 __set_bit(BTN_8, input_dev->keybit); 964 __set_bit(BTN_8, input_dev->keybit);
926 __set_bit(BTN_9, input_dev->keybit); 965 __set_bit(BTN_9, input_dev->keybit);
@@ -1105,6 +1144,8 @@ static const struct wacom_features wacom_features_0xBA =
1105 { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; 1144 { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L };
1106static const struct wacom_features wacom_features_0xBB = 1145static const struct wacom_features wacom_features_0xBB =
1107 { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; 1146 { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L };
1147static const struct wacom_features wacom_features_0xBC =
1148 { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, 63, INTUOS4 };
1108static const struct wacom_features wacom_features_0x3F = 1149static const struct wacom_features wacom_features_0x3F =
1109 { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; 1150 { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ };
1110static const struct wacom_features wacom_features_0xC5 = 1151static const struct wacom_features wacom_features_0xC5 =
@@ -1113,6 +1154,8 @@ static const struct wacom_features wacom_features_0xC6 =
1113 { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; 1154 { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE };
1114static const struct wacom_features wacom_features_0xC7 = 1155static const struct wacom_features wacom_features_0xC7 =
1115 { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; 1156 { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL };
1157static const struct wacom_features wacom_features_0xCC =
1158 { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, 63, WACOM_21UX2 };
1116static const struct wacom_features wacom_features_0x90 = 1159static const struct wacom_features wacom_features_0x90 =
1117 { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; 1160 { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC };
1118static const struct wacom_features wacom_features_0x93 = 1161static const struct wacom_features wacom_features_0x93 =
@@ -1185,10 +1228,12 @@ const struct usb_device_id wacom_ids[] = {
1185 { USB_DEVICE_WACOM(0xB9) }, 1228 { USB_DEVICE_WACOM(0xB9) },
1186 { USB_DEVICE_WACOM(0xBA) }, 1229 { USB_DEVICE_WACOM(0xBA) },
1187 { USB_DEVICE_WACOM(0xBB) }, 1230 { USB_DEVICE_WACOM(0xBB) },
1231 { USB_DEVICE_WACOM(0xBC) },
1188 { USB_DEVICE_WACOM(0x3F) }, 1232 { USB_DEVICE_WACOM(0x3F) },
1189 { USB_DEVICE_WACOM(0xC5) }, 1233 { USB_DEVICE_WACOM(0xC5) },
1190 { USB_DEVICE_WACOM(0xC6) }, 1234 { USB_DEVICE_WACOM(0xC6) },
1191 { USB_DEVICE_WACOM(0xC7) }, 1235 { USB_DEVICE_WACOM(0xC7) },
1236 { USB_DEVICE_WACOM(0xCC) },
1192 { USB_DEVICE_WACOM(0x90) }, 1237 { USB_DEVICE_WACOM(0x90) },
1193 { USB_DEVICE_WACOM(0x93) }, 1238 { USB_DEVICE_WACOM(0x93) },
1194 { USB_DEVICE_WACOM(0x9A) }, 1239 { USB_DEVICE_WACOM(0x9A) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 063f1af3204f..854b92092dfc 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -50,6 +50,7 @@ enum {
50 INTUOS4S, 50 INTUOS4S,
51 INTUOS4, 51 INTUOS4,
52 INTUOS4L, 52 INTUOS4L,
53 WACOM_21UX2,
53 CINTIQ, 54 CINTIQ,
54 WACOM_BEE, 55 WACOM_BEE,
55 WACOM_MO, 56 WACOM_MO,
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6703c6b9800a..3b9d5e2105d7 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -156,7 +156,7 @@ config TOUCHSCREEN_FUJITSU
156config TOUCHSCREEN_S3C2410 156config TOUCHSCREEN_S3C2410
157 tristate "Samsung S3C2410/generic touchscreen input driver" 157 tristate "Samsung S3C2410/generic touchscreen input driver"
158 depends on ARCH_S3C2410 || SAMSUNG_DEV_TS 158 depends on ARCH_S3C2410 || SAMSUNG_DEV_TS
159 select S3C24XX_ADC 159 select S3C_ADC
160 help 160 help
161 Say Y here if you have the s3c2410 touchscreen. 161 Say Y here if you have the s3c2410 touchscreen.
162 162
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index 794d070c6900..4b32fb4704cd 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -812,10 +812,8 @@ static int __devinit ad7879_probe(struct i2c_client *client,
812 ts->bus = client; 812 ts->bus = client;
813 813
814 error = ad7879_construct(client, ts); 814 error = ad7879_construct(client, ts);
815 if (error) { 815 if (error)
816 i2c_set_clientdata(client, NULL);
817 kfree(ts); 816 kfree(ts);
818 }
819 817
820 return error; 818 return error;
821} 819}
@@ -825,7 +823,6 @@ static int __devexit ad7879_remove(struct i2c_client *client)
825 struct ad7879 *ts = dev_get_drvdata(&client->dev); 823 struct ad7879 *ts = dev_get_drvdata(&client->dev);
826 824
827 ad7879_destroy(client, ts); 825 ad7879_destroy(client, ts);
828 i2c_set_clientdata(client, NULL);
829 kfree(ts); 826 kfree(ts);
830 827
831 return 0; 828 return 0;
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 634f6f6b9b13..a9fdf55c0238 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -1164,7 +1164,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1164 ts->reg = regulator_get(&spi->dev, "vcc"); 1164 ts->reg = regulator_get(&spi->dev, "vcc");
1165 if (IS_ERR(ts->reg)) { 1165 if (IS_ERR(ts->reg)) {
1166 err = PTR_ERR(ts->reg); 1166 err = PTR_ERR(ts->reg);
1167 dev_err(&spi->dev, "unable to get regulator: %ld\n", err); 1167 dev_err(&spi->dev, "unable to get regulator: %d\n", err);
1168 goto err_free_gpio; 1168 goto err_free_gpio;
1169 } 1169 }
1170 1170
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 75f8b73010fa..7a3a916f84a8 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -238,7 +238,6 @@ err2:
238 input = NULL; /* so we dont try to free it below */ 238 input = NULL; /* so we dont try to free it below */
239err1: 239err1:
240 input_free_device(input); 240 input_free_device(input);
241 i2c_set_clientdata(client, NULL);
242 kfree(priv); 241 kfree(priv);
243err0: 242err0:
244 return err; 243 return err;
@@ -256,7 +255,6 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
256 enable_irq(priv->irq); 255 enable_irq(priv->irq);
257 256
258 input_unregister_device(priv->input); 257 input_unregister_device(priv->input);
259 i2c_set_clientdata(client, NULL);
260 kfree(priv); 258 kfree(priv);
261 259
262 return 0; 260 return 0;
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c
index ce8ab0269f6f..1fb0c2f06a44 100644
--- a/drivers/input/touchscreen/mcs5000_ts.c
+++ b/drivers/input/touchscreen/mcs5000_ts.c
@@ -256,7 +256,6 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client)
256 free_irq(client->irq, data); 256 free_irq(client->irq, data);
257 input_unregister_device(data->input_dev); 257 input_unregister_device(data->input_dev);
258 kfree(data); 258 kfree(data);
259 i2c_set_clientdata(client, NULL);
260 259
261 return 0; 260 return 0;
262} 261}
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
index ac5d0f9b0cb1..6085d12fd561 100644
--- a/drivers/input/touchscreen/s3c2410_ts.c
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -173,7 +173,7 @@ static irqreturn_t stylus_irq(int irq, void *dev_id)
173 if (down) 173 if (down)
174 s3c_adc_start(ts.client, 0, 1 << ts.shift); 174 s3c_adc_start(ts.client, 0, 1 << ts.shift);
175 else 175 else
176 dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count); 176 dev_dbg(ts.dev, "%s: count=%d\n", __func__, ts.count);
177 177
178 if (ts.features & FEAT_PEN_IRQ) { 178 if (ts.features & FEAT_PEN_IRQ) {
179 /* Clear pen down/up interrupt */ 179 /* Clear pen down/up interrupt */
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c
index 5de80a1a730b..5b70a1419b4d 100644
--- a/drivers/input/touchscreen/tps6507x-ts.c
+++ b/drivers/input/touchscreen/tps6507x-ts.c
@@ -221,7 +221,7 @@ done:
221 221
222 if (poll) { 222 if (poll) {
223 schd = queue_delayed_work(tsc->wq, &tsc->work, 223 schd = queue_delayed_work(tsc->wq, &tsc->work,
224 tsc->poll_period * HZ / 1000); 224 msecs_to_jiffies(tsc->poll_period));
225 if (schd) 225 if (schd)
226 tsc->polling = 1; 226 tsc->polling = 1;
227 else { 227 else {
@@ -326,7 +326,7 @@ static int tps6507x_ts_probe(struct platform_device *pdev)
326 goto err2; 326 goto err2;
327 327
328 schd = queue_delayed_work(tsc->wq, &tsc->work, 328 schd = queue_delayed_work(tsc->wq, &tsc->work,
329 tsc->poll_period * HZ / 1000); 329 msecs_to_jiffies(tsc->poll_period));
330 330
331 if (schd) 331 if (schd)
332 tsc->polling = 1; 332 tsc->polling = 1;
@@ -339,10 +339,8 @@ static int tps6507x_ts_probe(struct platform_device *pdev)
339 return 0; 339 return 0;
340 340
341err2: 341err2:
342 cancel_delayed_work(&tsc->work); 342 cancel_delayed_work_sync(&tsc->work);
343 flush_workqueue(tsc->wq);
344 destroy_workqueue(tsc->wq); 343 destroy_workqueue(tsc->wq);
345 tsc->wq = 0;
346 input_free_device(input_dev); 344 input_free_device(input_dev);
347err1: 345err1:
348 kfree(tsc); 346 kfree(tsc);
@@ -360,10 +358,8 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev)
360 if (!tsc) 358 if (!tsc)
361 return 0; 359 return 0;
362 360
363 cancel_delayed_work(&tsc->work); 361 cancel_delayed_work_sync(&tsc->work);
364 flush_workqueue(tsc->wq);
365 destroy_workqueue(tsc->wq); 362 destroy_workqueue(tsc->wq);
366 tsc->wq = 0;
367 363
368 input_free_device(input_dev); 364 input_free_device(input_dev);
369 365
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 769b479fcaa6..be23780e8a3e 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -347,8 +347,6 @@ static int __devexit tsc2007_remove(struct i2c_client *client)
347 struct tsc2007 *ts = i2c_get_clientdata(client); 347 struct tsc2007 *ts = i2c_get_clientdata(client);
348 struct tsc2007_platform_data *pdata = client->dev.platform_data; 348 struct tsc2007_platform_data *pdata = client->dev.platform_data;
349 349
350 i2c_set_clientdata(client, NULL);
351
352 tsc2007_free_irq(ts); 350 tsc2007_free_irq(ts);
353 351
354 if (pdata->exit_platform_hw) 352 if (pdata->exit_platform_hw)
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index bde3c88b8b27..b054494df846 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -1020,12 +1020,12 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
1020 if (cmd == AVMB1_ADDCARD) { 1020 if (cmd == AVMB1_ADDCARD) {
1021 if ((retval = copy_from_user(&cdef, data, 1021 if ((retval = copy_from_user(&cdef, data,
1022 sizeof(avmb1_carddef)))) 1022 sizeof(avmb1_carddef))))
1023 return retval; 1023 return -EFAULT;
1024 cdef.cardtype = AVM_CARDTYPE_B1; 1024 cdef.cardtype = AVM_CARDTYPE_B1;
1025 } else { 1025 } else {
1026 if ((retval = copy_from_user(&cdef, data, 1026 if ((retval = copy_from_user(&cdef, data,
1027 sizeof(avmb1_extcarddef)))) 1027 sizeof(avmb1_extcarddef))))
1028 return retval; 1028 return -EFAULT;
1029 } 1029 }
1030 cparams.port = cdef.port; 1030 cparams.port = cdef.port;
1031 cparams.irq = cdef.irq; 1031 cparams.irq = cdef.irq;
@@ -1218,7 +1218,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1218 kcapi_carddef cdef; 1218 kcapi_carddef cdef;
1219 1219
1220 if ((retval = copy_from_user(&cdef, data, sizeof(cdef)))) 1220 if ((retval = copy_from_user(&cdef, data, sizeof(cdef))))
1221 return retval; 1221 return -EFAULT;
1222 1222
1223 cparams.port = cdef.port; 1223 cparams.port = cdef.port;
1224 cparams.irq = cdef.irq; 1224 cparams.irq = cdef.irq;
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index b3b7e2879bac..8700474747e8 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -97,8 +97,10 @@ static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val)
97 hw->name, __func__, reg, val); 97 hw->name, __func__, reg, val);
98 98
99 spin_lock(&hw->ctrl_lock); 99 spin_lock(&hw->ctrl_lock);
100 if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) 100 if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) {
101 spin_unlock(&hw->ctrl_lock);
101 return 1; 102 return 1;
103 }
102 buf = &hw->ctrl_buff[hw->ctrl_in_idx]; 104 buf = &hw->ctrl_buff[hw->ctrl_in_idx];
103 buf->hfcs_reg = reg; 105 buf->hfcs_reg = reg;
104 buf->reg_val = val; 106 buf->reg_val = val;
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
index 0a3553df065f..54ae71a907f9 100644
--- a/drivers/isdn/hardware/mISDN/netjet.c
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -320,12 +320,12 @@ inittiger(struct tiger_hw *card)
320 return -ENOMEM; 320 return -ENOMEM;
321 } 321 }
322 for (i = 0; i < 2; i++) { 322 for (i = 0; i < 2; i++) {
323 card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_KERNEL); 323 card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_ATOMIC);
324 if (!card->bc[i].hsbuf) { 324 if (!card->bc[i].hsbuf) {
325 pr_info("%s: no B%d send buffer\n", card->name, i + 1); 325 pr_info("%s: no B%d send buffer\n", card->name, i + 1);
326 return -ENOMEM; 326 return -ENOMEM;
327 } 327 }
328 card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_KERNEL); 328 card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_ATOMIC);
329 if (!card->bc[i].hrbuf) { 329 if (!card->bc[i].hrbuf) {
330 pr_info("%s: no B%d recv buffer\n", card->name, i + 1); 330 pr_info("%s: no B%d recv buffer\n", card->name, i + 1);
331 return -ENOMEM; 331 return -ENOMEM;
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 286b501a3573..5dcdf9d69b3a 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -742,7 +742,6 @@ failed_unregister_dev_file:
742 for (i--; i >= 0; i--) 742 for (i--; i >= 0; i--)
743 device_remove_file(&led->client->dev, bd2802_attributes[i]); 743 device_remove_file(&led->client->dev, bd2802_attributes[i]);
744failed_free: 744failed_free:
745 i2c_set_clientdata(client, NULL);
746 kfree(led); 745 kfree(led);
747 746
748 return ret; 747 return ret;
@@ -759,7 +758,6 @@ static int __exit bd2802_remove(struct i2c_client *client)
759 bd2802_disable_adv_conf(led); 758 bd2802_disable_adv_conf(led);
760 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) 759 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++)
761 device_remove_file(&led->client->dev, bd2802_attributes[i]); 760 device_remove_file(&led->client->dev, bd2802_attributes[i]);
762 i2c_set_clientdata(client, NULL);
763 kfree(led); 761 kfree(led);
764 762
765 return 0; 763 return 0;
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c
index 932a58da76c4..9010c054615e 100644
--- a/drivers/leds/leds-lp3944.c
+++ b/drivers/leds/leds-lp3944.c
@@ -432,7 +432,6 @@ static int __devexit lp3944_remove(struct i2c_client *client)
432 } 432 }
433 433
434 kfree(data); 434 kfree(data);
435 i2c_set_clientdata(client, NULL);
436 435
437 return 0; 436 return 0;
438} 437}
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 6682175fa9f7..43d08756d823 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -320,10 +320,8 @@ static int pca9532_probe(struct i2c_client *client,
320 mutex_init(&data->update_lock); 320 mutex_init(&data->update_lock);
321 321
322 err = pca9532_configure(client, data, pca9532_pdata); 322 err = pca9532_configure(client, data, pca9532_pdata);
323 if (err) { 323 if (err)
324 kfree(data); 324 kfree(data);
325 i2c_set_clientdata(client, NULL);
326 }
327 325
328 return err; 326 return err;
329} 327}
@@ -351,7 +349,6 @@ static int pca9532_remove(struct i2c_client *client)
351 } 349 }
352 350
353 kfree(data); 351 kfree(data);
354 i2c_set_clientdata(client, NULL);
355 return 0; 352 return 0;
356} 353}
357 354
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index 8ff50f234190..66aa3e8e786f 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -342,7 +342,6 @@ exit:
342 } 342 }
343 343
344 kfree(pca955x); 344 kfree(pca955x);
345 i2c_set_clientdata(client, NULL);
346 345
347 return err; 346 return err;
348} 347}
@@ -358,7 +357,6 @@ static int __devexit pca955x_remove(struct i2c_client *client)
358 } 357 }
359 358
360 kfree(pca955x); 359 kfree(pca955x);
361 i2c_set_clientdata(client, NULL);
362 360
363 return 0; 361 return 0;
364} 362}
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 97147804a49c..b6e7ddc09d76 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -492,8 +492,8 @@ static void macio_pci_add_devices(struct macio_chip *chip)
492 } 492 }
493 493
494 /* Add media bay devices if any */ 494 /* Add media bay devices if any */
495 pnode = mbdev->ofdev.dev.of_node; 495 if (mbdev) {
496 if (mbdev) 496 pnode = mbdev->ofdev.dev.of_node;
497 for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { 497 for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {
498 if (macio_skip_device(np)) 498 if (macio_skip_device(np))
499 continue; 499 continue;
@@ -502,10 +502,11 @@ static void macio_pci_add_devices(struct macio_chip *chip)
502 mbdev, root_res) == NULL) 502 mbdev, root_res) == NULL)
503 of_node_put(np); 503 of_node_put(np);
504 } 504 }
505 }
505 506
506 /* Add serial ports if any */ 507 /* Add serial ports if any */
507 pnode = sdev->ofdev.dev.of_node;
508 if (sdev) { 508 if (sdev) {
509 pnode = sdev->ofdev.dev.of_node;
509 for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { 510 for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {
510 if (macio_skip_device(np)) 511 if (macio_skip_device(np))
511 continue; 512 continue;
@@ -525,7 +526,6 @@ static void macio_pci_add_devices(struct macio_chip *chip)
525int macio_register_driver(struct macio_driver *drv) 526int macio_register_driver(struct macio_driver *drv)
526{ 527{
527 /* initialize common driver fields */ 528 /* initialize common driver fields */
528 drv->driver.name = drv->name;
529 drv->driver.bus = &macio_bus_type; 529 drv->driver.bus = &macio_bus_type;
530 530
531 /* register with core */ 531 /* register with core */
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 288acce76b74..2fd435bc542e 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -728,8 +728,10 @@ static struct of_device_id media_bay_match[] =
728 728
729static struct macio_driver media_bay_driver = 729static struct macio_driver media_bay_driver =
730{ 730{
731 .name = "media-bay", 731 .driver = {
732 .match_table = media_bay_match, 732 .name = "media-bay",
733 .of_match_table = media_bay_match,
734 },
733 .probe = media_bay_attach, 735 .probe = media_bay_attach,
734 .suspend = media_bay_suspend, 736 .suspend = media_bay_suspend,
735 .resume = media_bay_resume 737 .resume = media_bay_resume
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c
index 12946c5f583f..53cce3a5da23 100644
--- a/drivers/macintosh/rack-meter.c
+++ b/drivers/macintosh/rack-meter.c
@@ -584,9 +584,11 @@ static struct of_device_id rackmeter_match[] = {
584}; 584};
585 585
586static struct macio_driver rackmeter_driver = { 586static struct macio_driver rackmeter_driver = {
587 .name = "rackmeter", 587 .driver = {
588 .owner = THIS_MODULE, 588 .name = "rackmeter",
589 .match_table = rackmeter_match, 589 .owner = THIS_MODULE,
590 .of_match_table = rackmeter_match,
591 },
590 .probe = rackmeter_probe, 592 .probe = rackmeter_probe,
591 .remove = __devexit_p(rackmeter_remove), 593 .remove = __devexit_p(rackmeter_remove),
592 .shutdown = rackmeter_shutdown, 594 .shutdown = rackmeter_shutdown,
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 16d82f17ae82..c42eeb43042d 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -182,7 +182,6 @@ remove_thermostat(struct i2c_client *client)
182 182
183 thermostat = NULL; 183 thermostat = NULL;
184 184
185 i2c_set_clientdata(client, NULL);
186 kfree(th); 185 kfree(th);
187 186
188 return 0; 187 return 0;
@@ -400,7 +399,6 @@ static int probe_thermostat(struct i2c_client *client,
400 rc = read_reg(th, CONFIG_REG); 399 rc = read_reg(th, CONFIG_REG);
401 if (rc < 0) { 400 if (rc < 0) {
402 dev_err(&client->dev, "Thermostat failed to read config!\n"); 401 dev_err(&client->dev, "Thermostat failed to read config!\n");
403 i2c_set_clientdata(client, NULL);
404 kfree(th); 402 kfree(th);
405 return -ENODEV; 403 return -ENODEV;
406 } 404 }
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index d8257d35afde..647c6add2193 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -107,10 +107,8 @@ static int wf_lm75_probe(struct i2c_client *client,
107 i2c_set_clientdata(client, lm); 107 i2c_set_clientdata(client, lm);
108 108
109 rc = wf_register_sensor(&lm->sens); 109 rc = wf_register_sensor(&lm->sens);
110 if (rc) { 110 if (rc)
111 i2c_set_clientdata(client, NULL);
112 kfree(lm); 111 kfree(lm);
113 }
114 112
115 return rc; 113 return rc;
116} 114}
@@ -216,7 +214,6 @@ static int wf_lm75_remove(struct i2c_client *client)
216 /* release sensor */ 214 /* release sensor */
217 wf_unregister_sensor(&lm->sens); 215 wf_unregister_sensor(&lm->sens);
218 216
219 i2c_set_clientdata(client, NULL);
220 return 0; 217 return 0;
221} 218}
222 219
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index b486eb929fde..8204113268f4 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -81,7 +81,6 @@ static int wf_max6690_probe(struct i2c_client *client,
81 81
82 rc = wf_register_sensor(&max->sens); 82 rc = wf_register_sensor(&max->sens);
83 if (rc) { 83 if (rc) {
84 i2c_set_clientdata(client, NULL);
85 kfree(max); 84 kfree(max);
86 } 85 }
87 86
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index e20330a28959..65a8ff3e1f8e 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -376,7 +376,6 @@ static int wf_sat_remove(struct i2c_client *client)
376 /* XXX TODO */ 376 /* XXX TODO */
377 377
378 sat->i2c = NULL; 378 sat->i2c = NULL;
379 i2c_set_clientdata(client, NULL);
380 return 0; 379 return 0;
381} 380}
382 381
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
index 195c6cf359f6..d22a8ec523fc 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/IR/Kconfig
@@ -13,6 +13,7 @@ source "drivers/media/IR/keymaps/Kconfig"
13config IR_NEC_DECODER 13config IR_NEC_DECODER
14 tristate "Enable IR raw decoder for the NEC protocol" 14 tristate "Enable IR raw decoder for the NEC protocol"
15 depends on IR_CORE 15 depends on IR_CORE
16 select BITREVERSE
16 default y 17 default y
17 18
18 ---help--- 19 ---help---
@@ -22,6 +23,7 @@ config IR_NEC_DECODER
22config IR_RC5_DECODER 23config IR_RC5_DECODER
23 tristate "Enable IR raw decoder for the RC-5 protocol" 24 tristate "Enable IR raw decoder for the RC-5 protocol"
24 depends on IR_CORE 25 depends on IR_CORE
26 select BITREVERSE
25 default y 27 default y
26 28
27 ---help--- 29 ---help---
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
index 5e2045670004..4bbd45f4284c 100644
--- a/drivers/media/IR/imon.c
+++ b/drivers/media/IR/imon.c
@@ -94,6 +94,7 @@ struct imon_context {
94 94
95 bool display_supported; /* not all controllers do */ 95 bool display_supported; /* not all controllers do */
96 bool display_isopen; /* display port has been opened */ 96 bool display_isopen; /* display port has been opened */
97 bool rf_device; /* true if iMON 2.4G LT/DT RF device */
97 bool rf_isassociating; /* RF remote associating */ 98 bool rf_isassociating; /* RF remote associating */
98 bool dev_present_intf0; /* USB device presence, interface 0 */ 99 bool dev_present_intf0; /* USB device presence, interface 0 */
99 bool dev_present_intf1; /* USB device presence, interface 1 */ 100 bool dev_present_intf1; /* USB device presence, interface 1 */
@@ -385,7 +386,7 @@ static int display_open(struct inode *inode, struct file *file)
385 err("%s: display port is already open", __func__); 386 err("%s: display port is already open", __func__);
386 retval = -EBUSY; 387 retval = -EBUSY;
387 } else { 388 } else {
388 ictx->display_isopen = 1; 389 ictx->display_isopen = true;
389 file->private_data = ictx; 390 file->private_data = ictx;
390 dev_dbg(ictx->dev, "display port opened\n"); 391 dev_dbg(ictx->dev, "display port opened\n");
391 } 392 }
@@ -422,7 +423,7 @@ static int display_close(struct inode *inode, struct file *file)
422 err("%s: display is not open", __func__); 423 err("%s: display is not open", __func__);
423 retval = -EIO; 424 retval = -EIO;
424 } else { 425 } else {
425 ictx->display_isopen = 0; 426 ictx->display_isopen = false;
426 dev_dbg(ictx->dev, "display port closed\n"); 427 dev_dbg(ictx->dev, "display port closed\n");
427 if (!ictx->dev_present_intf0) { 428 if (!ictx->dev_present_intf0) {
428 /* 429 /*
@@ -491,12 +492,12 @@ static int send_packet(struct imon_context *ictx)
491 } 492 }
492 493
493 init_completion(&ictx->tx.finished); 494 init_completion(&ictx->tx.finished);
494 ictx->tx.busy = 1; 495 ictx->tx.busy = true;
495 smp_rmb(); /* ensure later readers know we're busy */ 496 smp_rmb(); /* ensure later readers know we're busy */
496 497
497 retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL); 498 retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL);
498 if (retval) { 499 if (retval) {
499 ictx->tx.busy = 0; 500 ictx->tx.busy = false;
500 smp_rmb(); /* ensure later readers know we're not busy */ 501 smp_rmb(); /* ensure later readers know we're not busy */
501 err("%s: error submitting urb(%d)", __func__, retval); 502 err("%s: error submitting urb(%d)", __func__, retval);
502 } else { 503 } else {
@@ -682,7 +683,7 @@ static ssize_t store_associate_remote(struct device *d,
682 return -ENODEV; 683 return -ENODEV;
683 684
684 mutex_lock(&ictx->lock); 685 mutex_lock(&ictx->lock);
685 ictx->rf_isassociating = 1; 686 ictx->rf_isassociating = true;
686 send_associate_24g(ictx); 687 send_associate_24g(ictx);
687 mutex_unlock(&ictx->lock); 688 mutex_unlock(&ictx->lock);
688 689
@@ -950,7 +951,7 @@ static void usb_tx_callback(struct urb *urb)
950 ictx->tx.status = urb->status; 951 ictx->tx.status = urb->status;
951 952
952 /* notify waiters that write has finished */ 953 /* notify waiters that write has finished */
953 ictx->tx.busy = 0; 954 ictx->tx.busy = false;
954 smp_rmb(); /* ensure later readers know we're not busy */ 955 smp_rmb(); /* ensure later readers know we're not busy */
955 complete(&ictx->tx.finished); 956 complete(&ictx->tx.finished);
956} 957}
@@ -1215,7 +1216,7 @@ static bool imon_mouse_event(struct imon_context *ictx,
1215{ 1216{
1216 char rel_x = 0x00, rel_y = 0x00; 1217 char rel_x = 0x00, rel_y = 0x00;
1217 u8 right_shift = 1; 1218 u8 right_shift = 1;
1218 bool mouse_input = 1; 1219 bool mouse_input = true;
1219 int dir = 0; 1220 int dir = 0;
1220 1221
1221 /* newer iMON device PAD or mouse button */ 1222 /* newer iMON device PAD or mouse button */
@@ -1246,7 +1247,7 @@ static bool imon_mouse_event(struct imon_context *ictx,
1246 } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) { 1247 } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) {
1247 dir = -1; 1248 dir = -1;
1248 } else 1249 } else
1249 mouse_input = 0; 1250 mouse_input = false;
1250 1251
1251 if (mouse_input) { 1252 if (mouse_input) {
1252 dev_dbg(ictx->dev, "sending mouse data via input subsystem\n"); 1253 dev_dbg(ictx->dev, "sending mouse data via input subsystem\n");
@@ -1450,7 +1451,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
1450 unsigned char *buf = urb->transfer_buffer; 1451 unsigned char *buf = urb->transfer_buffer;
1451 struct device *dev = ictx->dev; 1452 struct device *dev = ictx->dev;
1452 u32 kc; 1453 u32 kc;
1453 bool norelease = 0; 1454 bool norelease = false;
1454 int i; 1455 int i;
1455 u64 temp_key; 1456 u64 temp_key;
1456 u64 panel_key = 0; 1457 u64 panel_key = 0;
@@ -1465,7 +1466,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
1465 idev = ictx->idev; 1466 idev = ictx->idev;
1466 1467
1467 /* filter out junk data on the older 0xffdc imon devices */ 1468 /* filter out junk data on the older 0xffdc imon devices */
1468 if ((buf[0] == 0xff) && (buf[7] == 0xff)) 1469 if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff))
1469 return; 1470 return;
1470 1471
1471 /* Figure out what key was pressed */ 1472 /* Figure out what key was pressed */
@@ -1517,7 +1518,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
1517 !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) { 1518 !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
1518 len = 8; 1519 len = 8;
1519 imon_pad_to_keys(ictx, buf); 1520 imon_pad_to_keys(ictx, buf);
1520 norelease = 1; 1521 norelease = true;
1521 } 1522 }
1522 1523
1523 if (debug) { 1524 if (debug) {
@@ -1580,7 +1581,7 @@ not_input_data:
1580 (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */ 1581 (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */
1581 dev_warn(dev, "%s: remote associated refid=%02X\n", 1582 dev_warn(dev, "%s: remote associated refid=%02X\n",
1582 __func__, buf[1]); 1583 __func__, buf[1]);
1583 ictx->rf_isassociating = 0; 1584 ictx->rf_isassociating = false;
1584 } 1585 }
1585} 1586}
1586 1587
@@ -1790,9 +1791,9 @@ static bool imon_find_endpoints(struct imon_context *ictx,
1790 int ifnum = iface_desc->desc.bInterfaceNumber; 1791 int ifnum = iface_desc->desc.bInterfaceNumber;
1791 int num_endpts = iface_desc->desc.bNumEndpoints; 1792 int num_endpts = iface_desc->desc.bNumEndpoints;
1792 int i, ep_dir, ep_type; 1793 int i, ep_dir, ep_type;
1793 bool ir_ep_found = 0; 1794 bool ir_ep_found = false;
1794 bool display_ep_found = 0; 1795 bool display_ep_found = false;
1795 bool tx_control = 0; 1796 bool tx_control = false;
1796 1797
1797 /* 1798 /*
1798 * Scan the endpoint list and set: 1799 * Scan the endpoint list and set:
@@ -1808,13 +1809,13 @@ static bool imon_find_endpoints(struct imon_context *ictx,
1808 ep_type == USB_ENDPOINT_XFER_INT) { 1809 ep_type == USB_ENDPOINT_XFER_INT) {
1809 1810
1810 rx_endpoint = ep; 1811 rx_endpoint = ep;
1811 ir_ep_found = 1; 1812 ir_ep_found = true;
1812 dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__); 1813 dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__);
1813 1814
1814 } else if (!display_ep_found && ep_dir == USB_DIR_OUT && 1815 } else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
1815 ep_type == USB_ENDPOINT_XFER_INT) { 1816 ep_type == USB_ENDPOINT_XFER_INT) {
1816 tx_endpoint = ep; 1817 tx_endpoint = ep;
1817 display_ep_found = 1; 1818 display_ep_found = true;
1818 dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__); 1819 dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__);
1819 } 1820 }
1820 } 1821 }
@@ -1835,8 +1836,8 @@ static bool imon_find_endpoints(struct imon_context *ictx,
1835 * newer iMON devices that use control urb instead of interrupt 1836 * newer iMON devices that use control urb instead of interrupt
1836 */ 1837 */
1837 if (!display_ep_found) { 1838 if (!display_ep_found) {
1838 tx_control = 1; 1839 tx_control = true;
1839 display_ep_found = 1; 1840 display_ep_found = true;
1840 dev_dbg(ictx->dev, "%s: device uses control endpoint, not " 1841 dev_dbg(ictx->dev, "%s: device uses control endpoint, not "
1841 "interface OUT endpoint\n", __func__); 1842 "interface OUT endpoint\n", __func__);
1842 } 1843 }
@@ -1847,7 +1848,7 @@ static bool imon_find_endpoints(struct imon_context *ictx,
1847 * and without... :\ 1848 * and without... :\
1848 */ 1849 */
1849 if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) { 1850 if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) {
1850 display_ep_found = 0; 1851 display_ep_found = false;
1851 dev_dbg(ictx->dev, "%s: device has no display\n", __func__); 1852 dev_dbg(ictx->dev, "%s: device has no display\n", __func__);
1852 } 1853 }
1853 1854
@@ -1856,7 +1857,7 @@ static bool imon_find_endpoints(struct imon_context *ictx,
1856 * that refers to e.g. /dev/lcd0 (a character device LCD or VFD). 1857 * that refers to e.g. /dev/lcd0 (a character device LCD or VFD).
1857 */ 1858 */
1858 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { 1859 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
1859 display_ep_found = 0; 1860 display_ep_found = false;
1860 dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__); 1861 dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__);
1861 } 1862 }
1862 1863
@@ -1905,9 +1906,10 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
1905 1906
1906 ictx->dev = dev; 1907 ictx->dev = dev;
1907 ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf)); 1908 ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf));
1908 ictx->dev_present_intf0 = 1; 1909 ictx->dev_present_intf0 = true;
1909 ictx->rx_urb_intf0 = rx_urb; 1910 ictx->rx_urb_intf0 = rx_urb;
1910 ictx->tx_urb = tx_urb; 1911 ictx->tx_urb = tx_urb;
1912 ictx->rf_device = false;
1911 1913
1912 ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor); 1914 ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor);
1913 ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct); 1915 ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct);
@@ -1979,7 +1981,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf,
1979 } 1981 }
1980 1982
1981 ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); 1983 ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf));
1982 ictx->dev_present_intf1 = 1; 1984 ictx->dev_present_intf1 = true;
1983 ictx->rx_urb_intf1 = rx_urb; 1985 ictx->rx_urb_intf1 = rx_urb;
1984 1986
1985 ret = -ENODEV; 1987 ret = -ENODEV;
@@ -2047,6 +2049,12 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
2047 dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR"); 2049 dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR");
2048 ictx->display_supported = false; 2050 ictx->display_supported = false;
2049 break; 2051 break;
2052 /* iMON 2.4G LT (usb stick), no display, iMON RF */
2053 case 0x4e:
2054 dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF");
2055 ictx->display_supported = false;
2056 ictx->rf_device = true;
2057 break;
2050 /* iMON VFD, no IR (does have vol knob tho) */ 2058 /* iMON VFD, no IR (does have vol knob tho) */
2051 case 0x35: 2059 case 0x35:
2052 dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR"); 2060 dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR");
@@ -2197,15 +2205,6 @@ static int __devinit imon_probe(struct usb_interface *interface,
2197 goto fail; 2205 goto fail;
2198 } 2206 }
2199 2207
2200 if (product == 0xffdc) {
2201 /* RF products *also* use 0xffdc... sigh... */
2202 sysfs_err = sysfs_create_group(&interface->dev.kobj,
2203 &imon_rf_attribute_group);
2204 if (sysfs_err)
2205 err("%s: Could not create RF sysfs entries(%d)",
2206 __func__, sysfs_err);
2207 }
2208
2209 } else { 2208 } else {
2210 /* this is the secondary interface on the device */ 2209 /* this is the secondary interface on the device */
2211 ictx = imon_init_intf1(interface, first_if_ctx); 2210 ictx = imon_init_intf1(interface, first_if_ctx);
@@ -2233,6 +2232,14 @@ static int __devinit imon_probe(struct usb_interface *interface,
2233 2232
2234 imon_set_display_type(ictx, interface); 2233 imon_set_display_type(ictx, interface);
2235 2234
2235 if (product == 0xffdc && ictx->rf_device) {
2236 sysfs_err = sysfs_create_group(&interface->dev.kobj,
2237 &imon_rf_attribute_group);
2238 if (sysfs_err)
2239 err("%s: Could not create RF sysfs entries(%d)",
2240 __func__, sysfs_err);
2241 }
2242
2236 if (ictx->display_supported) 2243 if (ictx->display_supported)
2237 imon_init_display(ictx, interface); 2244 imon_init_display(ictx, interface);
2238 } 2245 }
@@ -2297,7 +2304,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
2297 } 2304 }
2298 2305
2299 if (ifnum == 0) { 2306 if (ifnum == 0) {
2300 ictx->dev_present_intf0 = 0; 2307 ictx->dev_present_intf0 = false;
2301 usb_kill_urb(ictx->rx_urb_intf0); 2308 usb_kill_urb(ictx->rx_urb_intf0);
2302 input_unregister_device(ictx->idev); 2309 input_unregister_device(ictx->idev);
2303 if (ictx->display_supported) { 2310 if (ictx->display_supported) {
@@ -2307,7 +2314,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
2307 usb_deregister_dev(interface, &imon_vfd_class); 2314 usb_deregister_dev(interface, &imon_vfd_class);
2308 } 2315 }
2309 } else { 2316 } else {
2310 ictx->dev_present_intf1 = 0; 2317 ictx->dev_present_intf1 = false;
2311 usb_kill_urb(ictx->rx_urb_intf1); 2318 usb_kill_urb(ictx->rx_urb_intf1);
2312 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) 2319 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
2313 input_unregister_device(ictx->touch); 2320 input_unregister_device(ictx->touch);
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index 9374a006f43d..94a8577e72eb 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -490,11 +490,12 @@ int __ir_input_register(struct input_dev *input_dev,
490 if (rc < 0) 490 if (rc < 0)
491 goto out_table; 491 goto out_table;
492 492
493 if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { 493 if (ir_dev->props)
494 rc = ir_raw_event_register(input_dev); 494 if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) {
495 if (rc < 0) 495 rc = ir_raw_event_register(input_dev);
496 goto out_event; 496 if (rc < 0)
497 } 497 goto out_event;
498 }
498 499
499 IR_dprintk(1, "Registered input device on %s for %s remote.\n", 500 IR_dprintk(1, "Registered input device on %s for %s remote.\n",
500 driver_name, rc_tab->name); 501 driver_name, rc_tab->name);
@@ -530,8 +531,10 @@ void ir_input_unregister(struct input_dev *input_dev)
530 IR_dprintk(1, "Freed keycode table\n"); 531 IR_dprintk(1, "Freed keycode table\n");
531 532
532 del_timer_sync(&ir_dev->timer_keyup); 533 del_timer_sync(&ir_dev->timer_keyup);
533 if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) 534 if (ir_dev->props)
534 ir_raw_event_unregister(input_dev); 535 if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
536 ir_raw_event_unregister(input_dev);
537
535 rc_tab = &ir_dev->rc_tab; 538 rc_tab = &ir_dev->rc_tab;
536 rc_tab->size = 0; 539 rc_tab->size = 0;
537 kfree(rc_tab->scan); 540 kfree(rc_tab->scan);
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index d7da63e16c92..2098dd1488e0 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -221,9 +221,10 @@ int ir_register_class(struct input_dev *input_dev)
221 if (unlikely(devno < 0)) 221 if (unlikely(devno < 0))
222 return devno; 222 return devno;
223 223
224 if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) 224 if (ir_dev->props) {
225 ir_dev->dev.type = &rc_dev_type; 225 if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
226 else 226 ir_dev->dev.type = &rc_dev_type;
227 } else
227 ir_dev->dev.type = &ir_raw_dev_type; 228 ir_dev->dev.type = &ir_raw_dev_type;
228 229
229 ir_dev->dev.class = &ir_input_class; 230 ir_dev->dev.class = &ir_input_class;
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile
index ec25258a955f..aea649fbcf5a 100644
--- a/drivers/media/IR/keymaps/Makefile
+++ b/drivers/media/IR/keymaps/Makefile
@@ -6,7 +6,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
6 rc-avermedia.o \ 6 rc-avermedia.o \
7 rc-avermedia-cardbus.o \ 7 rc-avermedia-cardbus.o \
8 rc-avermedia-dvbt.o \ 8 rc-avermedia-dvbt.o \
9 rc-avermedia-m135a-rm-jx.o \ 9 rc-avermedia-m135a.o \
10 rc-avermedia-m733a-rm-k6.o \
10 rc-avertv-303.o \ 11 rc-avertv-303.o \
11 rc-behold.o \ 12 rc-behold.o \
12 rc-behold-columbus.o \ 13 rc-behold-columbus.o \
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c b/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c
deleted file mode 100644
index 101e7ea85941..000000000000
--- a/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c
+++ /dev/null
@@ -1,90 +0,0 @@
1/* avermedia-m135a-rm-jx.h - Keytable for avermedia_m135a_rm_jx Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.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
13#include <media/rc-map.h>
14
15/*
16 * Avermedia M135A with IR model RM-JX
17 * The same codes exist on both Positivo (BR) and original IR
18 * Mauro Carvalho Chehab <mchehab@infradead.org>
19 */
20
21static struct ir_scancode avermedia_m135a_rm_jx[] = {
22 { 0x0200, KEY_POWER2 },
23 { 0x022e, KEY_DOT }, /* '.' */
24 { 0x0201, KEY_MODE }, /* TV/FM or SOURCE */
25
26 { 0x0205, KEY_1 },
27 { 0x0206, KEY_2 },
28 { 0x0207, KEY_3 },
29 { 0x0209, KEY_4 },
30 { 0x020a, KEY_5 },
31 { 0x020b, KEY_6 },
32 { 0x020d, KEY_7 },
33 { 0x020e, KEY_8 },
34 { 0x020f, KEY_9 },
35 { 0x0211, KEY_0 },
36
37 { 0x0213, KEY_RIGHT }, /* -> or L */
38 { 0x0212, KEY_LEFT }, /* <- or R */
39
40 { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */
41 { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */
42
43 { 0x0303, KEY_CHANNELUP },
44 { 0x0302, KEY_CHANNELDOWN },
45 { 0x021f, KEY_VOLUMEUP },
46 { 0x021e, KEY_VOLUMEDOWN },
47 { 0x020c, KEY_ENTER }, /* Full Screen */
48
49 { 0x0214, KEY_MUTE },
50 { 0x0208, KEY_AUDIO },
51
52 { 0x0203, KEY_TEXT }, /* Teletext */
53 { 0x0204, KEY_EPG },
54 { 0x022b, KEY_TV2 }, /* TV2 or PIP */
55
56 { 0x021d, KEY_RED },
57 { 0x021c, KEY_YELLOW },
58 { 0x0301, KEY_GREEN },
59 { 0x0300, KEY_BLUE },
60
61 { 0x021a, KEY_PLAYPAUSE },
62 { 0x0219, KEY_RECORD },
63 { 0x0218, KEY_PLAY },
64 { 0x021b, KEY_STOP },
65};
66
67static struct rc_keymap avermedia_m135a_rm_jx_map = {
68 .map = {
69 .scan = avermedia_m135a_rm_jx,
70 .size = ARRAY_SIZE(avermedia_m135a_rm_jx),
71 .ir_type = IR_TYPE_NEC,
72 .name = RC_MAP_AVERMEDIA_M135A_RM_JX,
73 }
74};
75
76static int __init init_rc_map_avermedia_m135a_rm_jx(void)
77{
78 return ir_register_map(&avermedia_m135a_rm_jx_map);
79}
80
81static void __exit exit_rc_map_avermedia_m135a_rm_jx(void)
82{
83 ir_unregister_map(&avermedia_m135a_rm_jx_map);
84}
85
86module_init(init_rc_map_avermedia_m135a_rm_jx)
87module_exit(exit_rc_map_avermedia_m135a_rm_jx)
88
89MODULE_LICENSE("GPL");
90MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m135a.c b/drivers/media/IR/keymaps/rc-avermedia-m135a.c
new file mode 100644
index 000000000000..e4471fb2ad1e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-m135a.c
@@ -0,0 +1,147 @@
1/* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers
2 *
3 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 * Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
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
12#include <media/rc-map.h>
13
14/*
15 * Avermedia M135A with RM-JX and RM-K6 remote controls
16 *
17 * On Avermedia M135A with IR model RM-JX, the same codes exist on both
18 * Positivo (BR) and original IR, initial version and remote control codes
19 * added by Mauro Carvalho Chehab <mchehab@infradead.org>
20 *
21 * Positivo also ships Avermedia M135A with model RM-K6, extra control
22 * codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
23 */
24
25static struct ir_scancode avermedia_m135a[] = {
26 /* RM-JX */
27 { 0x0200, KEY_POWER2 },
28 { 0x022e, KEY_DOT }, /* '.' */
29 { 0x0201, KEY_MODE }, /* TV/FM or SOURCE */
30
31 { 0x0205, KEY_1 },
32 { 0x0206, KEY_2 },
33 { 0x0207, KEY_3 },
34 { 0x0209, KEY_4 },
35 { 0x020a, KEY_5 },
36 { 0x020b, KEY_6 },
37 { 0x020d, KEY_7 },
38 { 0x020e, KEY_8 },
39 { 0x020f, KEY_9 },
40 { 0x0211, KEY_0 },
41
42 { 0x0213, KEY_RIGHT }, /* -> or L */
43 { 0x0212, KEY_LEFT }, /* <- or R */
44
45 { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */
46 { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */
47
48 { 0x0303, KEY_CHANNELUP },
49 { 0x0302, KEY_CHANNELDOWN },
50 { 0x021f, KEY_VOLUMEUP },
51 { 0x021e, KEY_VOLUMEDOWN },
52 { 0x020c, KEY_ENTER }, /* Full Screen */
53
54 { 0x0214, KEY_MUTE },
55 { 0x0208, KEY_AUDIO },
56
57 { 0x0203, KEY_TEXT }, /* Teletext */
58 { 0x0204, KEY_EPG },
59 { 0x022b, KEY_TV2 }, /* TV2 or PIP */
60
61 { 0x021d, KEY_RED },
62 { 0x021c, KEY_YELLOW },
63 { 0x0301, KEY_GREEN },
64 { 0x0300, KEY_BLUE },
65
66 { 0x021a, KEY_PLAYPAUSE },
67 { 0x0219, KEY_RECORD },
68 { 0x0218, KEY_PLAY },
69 { 0x021b, KEY_STOP },
70
71 /* RM-K6 */
72 { 0x0401, KEY_POWER2 },
73 { 0x0406, KEY_MUTE },
74 { 0x0408, KEY_MODE }, /* TV/FM */
75
76 { 0x0409, KEY_1 },
77 { 0x040a, KEY_2 },
78 { 0x040b, KEY_3 },
79 { 0x040c, KEY_4 },
80 { 0x040d, KEY_5 },
81 { 0x040e, KEY_6 },
82 { 0x040f, KEY_7 },
83 { 0x0410, KEY_8 },
84 { 0x0411, KEY_9 },
85 { 0x044c, KEY_DOT }, /* '.' */
86 { 0x0412, KEY_0 },
87 { 0x0407, KEY_REFRESH }, /* Refresh/Reload */
88
89 { 0x0413, KEY_AUDIO },
90 { 0x0440, KEY_SCREEN }, /* Full Screen toggle */
91 { 0x0441, KEY_HOME },
92 { 0x0442, KEY_BACK },
93 { 0x0447, KEY_UP },
94 { 0x0448, KEY_DOWN },
95 { 0x0449, KEY_LEFT },
96 { 0x044a, KEY_RIGHT },
97 { 0x044b, KEY_OK },
98 { 0x0404, KEY_VOLUMEUP },
99 { 0x0405, KEY_VOLUMEDOWN },
100 { 0x0402, KEY_CHANNELUP },
101 { 0x0403, KEY_CHANNELDOWN },
102
103 { 0x0443, KEY_RED },
104 { 0x0444, KEY_GREEN },
105 { 0x0445, KEY_YELLOW },
106 { 0x0446, KEY_BLUE },
107
108 { 0x0414, KEY_TEXT },
109 { 0x0415, KEY_EPG },
110 { 0x041a, KEY_TV2 }, /* PIP */
111 { 0x041b, KEY_MHP }, /* Snapshot */
112
113 { 0x0417, KEY_RECORD },
114 { 0x0416, KEY_PLAYPAUSE },
115 { 0x0418, KEY_STOP },
116 { 0x0419, KEY_PAUSE },
117
118 { 0x041f, KEY_PREVIOUS },
119 { 0x041c, KEY_REWIND },
120 { 0x041d, KEY_FORWARD },
121 { 0x041e, KEY_NEXT },
122};
123
124static struct rc_keymap avermedia_m135a_map = {
125 .map = {
126 .scan = avermedia_m135a,
127 .size = ARRAY_SIZE(avermedia_m135a),
128 .ir_type = IR_TYPE_NEC,
129 .name = RC_MAP_AVERMEDIA_M135A,
130 }
131};
132
133static int __init init_rc_map_avermedia_m135a(void)
134{
135 return ir_register_map(&avermedia_m135a_map);
136}
137
138static void __exit exit_rc_map_avermedia_m135a(void)
139{
140 ir_unregister_map(&avermedia_m135a_map);
141}
142
143module_init(init_rc_map_avermedia_m135a)
144module_exit(exit_rc_map_avermedia_m135a)
145
146MODULE_LICENSE("GPL");
147MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c
new file mode 100644
index 000000000000..cf8d45717cb3
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c
@@ -0,0 +1,95 @@
1/* avermedia-m733a-rm-k6.h - Keytable for avermedia_m733a_rm_k6 Remote Controller
2 *
3 * Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
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 * (at your option) any later version.
9 */
10
11#include <media/rc-map.h>
12
13/*
14 * Avermedia M733A with IR model RM-K6
15 * This is the stock remote controller used with Positivo machines with M733A
16 * Herton Ronaldo Krzesinski <herton@mandriva.com.br>
17 */
18
19static struct ir_scancode avermedia_m733a_rm_k6[] = {
20 { 0x0401, KEY_POWER2 },
21 { 0x0406, KEY_MUTE },
22 { 0x0408, KEY_MODE }, /* TV/FM */
23
24 { 0x0409, KEY_1 },
25 { 0x040a, KEY_2 },
26 { 0x040b, KEY_3 },
27 { 0x040c, KEY_4 },
28 { 0x040d, KEY_5 },
29 { 0x040e, KEY_6 },
30 { 0x040f, KEY_7 },
31 { 0x0410, KEY_8 },
32 { 0x0411, KEY_9 },
33 { 0x044c, KEY_DOT }, /* '.' */
34 { 0x0412, KEY_0 },
35 { 0x0407, KEY_REFRESH }, /* Refresh/Reload */
36
37 { 0x0413, KEY_AUDIO },
38 { 0x0440, KEY_SCREEN }, /* Full Screen toggle */
39 { 0x0441, KEY_HOME },
40 { 0x0442, KEY_BACK },
41 { 0x0447, KEY_UP },
42 { 0x0448, KEY_DOWN },
43 { 0x0449, KEY_LEFT },
44 { 0x044a, KEY_RIGHT },
45 { 0x044b, KEY_OK },
46 { 0x0404, KEY_VOLUMEUP },
47 { 0x0405, KEY_VOLUMEDOWN },
48 { 0x0402, KEY_CHANNELUP },
49 { 0x0403, KEY_CHANNELDOWN },
50
51 { 0x0443, KEY_RED },
52 { 0x0444, KEY_GREEN },
53 { 0x0445, KEY_YELLOW },
54 { 0x0446, KEY_BLUE },
55
56 { 0x0414, KEY_TEXT },
57 { 0x0415, KEY_EPG },
58 { 0x041a, KEY_TV2 }, /* PIP */
59 { 0x041b, KEY_MHP }, /* Snapshot */
60
61 { 0x0417, KEY_RECORD },
62 { 0x0416, KEY_PLAYPAUSE },
63 { 0x0418, KEY_STOP },
64 { 0x0419, KEY_PAUSE },
65
66 { 0x041f, KEY_PREVIOUS },
67 { 0x041c, KEY_REWIND },
68 { 0x041d, KEY_FORWARD },
69 { 0x041e, KEY_NEXT },
70};
71
72static struct rc_keymap avermedia_m733a_rm_k6_map = {
73 .map = {
74 .scan = avermedia_m733a_rm_k6,
75 .size = ARRAY_SIZE(avermedia_m733a_rm_k6),
76 .ir_type = IR_TYPE_NEC,
77 .name = RC_MAP_AVERMEDIA_M733A_RM_K6,
78 }
79};
80
81static int __init init_rc_map_avermedia_m733a_rm_k6(void)
82{
83 return ir_register_map(&avermedia_m733a_rm_k6_map);
84}
85
86static void __exit exit_rc_map_avermedia_m733a_rm_k6(void)
87{
88 ir_unregister_map(&avermedia_m733a_rm_k6_map);
89}
90
91module_init(init_rc_map_avermedia_m733a_rm_k6)
92module_exit(exit_rc_map_avermedia_m733a_rm_k6)
93
94MODULE_LICENSE("GPL");
95MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index b762e561a6d5..bca07c0bcd01 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -594,7 +594,7 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id)
594int __devinit dm1105_ir_init(struct dm1105_dev *dm1105) 594int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
595{ 595{
596 struct input_dev *input_dev; 596 struct input_dev *input_dev;
597 char *ir_codes = NULL; 597 char *ir_codes = RC_MAP_DM1105_NEC;
598 int err = -ENOMEM; 598 int err = -ENOMEM;
599 599
600 input_dev = input_allocate_device(); 600 input_dev = input_allocate_device();
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index f6dac2bb0ac6..6c3a8a06ccab 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -351,6 +351,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
351 const u8 *ts, *ts_end, *from_where = NULL; 351 const u8 *ts, *ts_end, *from_where = NULL;
352 u8 ts_remain = 0, how_much = 0, new_ts = 1; 352 u8 ts_remain = 0, how_much = 0, new_ts = 1;
353 struct ethhdr *ethh = NULL; 353 struct ethhdr *ethh = NULL;
354 bool error = false;
354 355
355#ifdef ULE_DEBUG 356#ifdef ULE_DEBUG
356 /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */ 357 /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
@@ -460,10 +461,16 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
460 461
461 /* Drop partly decoded SNDU, reset state, resync on PUSI. */ 462 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
462 if (priv->ule_skb) { 463 if (priv->ule_skb) {
463 dev_kfree_skb( priv->ule_skb ); 464 error = true;
465 dev_kfree_skb(priv->ule_skb);
466 }
467
468 if (error || priv->ule_sndu_remain) {
464 dev->stats.rx_errors++; 469 dev->stats.rx_errors++;
465 dev->stats.rx_frame_errors++; 470 dev->stats.rx_frame_errors++;
471 error = false;
466 } 472 }
473
467 reset_ule(priv); 474 reset_ule(priv);
468 priv->need_pusi = 1; 475 priv->need_pusi = 1;
469 continue; 476 continue;
@@ -535,6 +542,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
535 from_where += 2; 542 from_where += 2;
536 } 543 }
537 544
545 priv->ule_sndu_remain = priv->ule_sndu_len + 2;
538 /* 546 /*
539 * State of current TS: 547 * State of current TS:
540 * ts_remain (remaining bytes in the current TS cell) 548 * ts_remain (remaining bytes in the current TS cell)
@@ -544,6 +552,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
544 */ 552 */
545 switch (ts_remain) { 553 switch (ts_remain) {
546 case 1: 554 case 1:
555 priv->ule_sndu_remain--;
547 priv->ule_sndu_type = from_where[0] << 8; 556 priv->ule_sndu_type = from_where[0] << 8;
548 priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ 557 priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */
549 ts_remain -= 1; from_where += 1; 558 ts_remain -= 1; from_where += 1;
@@ -557,6 +566,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
557 default: /* complete ULE header is present in current TS. */ 566 default: /* complete ULE header is present in current TS. */
558 /* Extract ULE type field. */ 567 /* Extract ULE type field. */
559 if (priv->ule_sndu_type_1) { 568 if (priv->ule_sndu_type_1) {
569 priv->ule_sndu_type_1 = 0;
560 priv->ule_sndu_type |= from_where[0]; 570 priv->ule_sndu_type |= from_where[0];
561 from_where += 1; /* points to payload start. */ 571 from_where += 1; /* points to payload start. */
562 ts_remain -= 1; 572 ts_remain -= 1;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index e5f91f16ffa4..553b48ac1919 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -76,6 +76,7 @@ config DVB_USB_DIB0700
76 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 76 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
77 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE 77 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
78 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE 78 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
79 select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE
79 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE 80 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
80 select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE 81 select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
81 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE 82 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
@@ -134,6 +135,7 @@ config DVB_USB_M920X
134 select DVB_TDA1004X if !DVB_FE_CUSTOMISE 135 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
135 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE 136 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
136 select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE 137 select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
138 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
137 help 139 help
138 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. 140 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
139 Currently, only devices with a product id of 141 Currently, only devices with a product id of
@@ -264,7 +266,7 @@ config DVB_USB_DW2102
264 select DVB_STB6000 if !DVB_FE_CUSTOMISE 266 select DVB_STB6000 if !DVB_FE_CUSTOMISE
265 select DVB_CX24116 if !DVB_FE_CUSTOMISE 267 select DVB_CX24116 if !DVB_FE_CUSTOMISE
266 select DVB_SI21XX if !DVB_FE_CUSTOMISE 268 select DVB_SI21XX if !DVB_FE_CUSTOMISE
267 select DVB_TDA10021 if !DVB_FE_CUSTOMISE 269 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
268 select DVB_MT312 if !DVB_FE_CUSTOMISE 270 select DVB_MT312 if !DVB_FE_CUSTOMISE
269 select DVB_ZL10039 if !DVB_FE_CUSTOMISE 271 select DVB_ZL10039 if !DVB_FE_CUSTOMISE
270 select DVB_DS3000 if !DVB_FE_CUSTOMISE 272 select DVB_DS3000 if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 0eb490889162..11e9e85dac86 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -1026,8 +1026,10 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1026 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); 1026 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1027 1027
1028 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 1028 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1029 &cxusb_dualdig4_rev2_config) < 0) 1029 &cxusb_dualdig4_rev2_config) < 0) {
1030 printk(KERN_WARNING "Unable to enumerate dib7000p\n");
1030 return -ENODEV; 1031 return -ENODEV;
1032 }
1031 1033
1032 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, 1034 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1033 &cxusb_dualdig4_rev2_config); 1035 &cxusb_dualdig4_rev2_config);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 085c4e457e0e..b4afe6f8ed19 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -198,6 +198,7 @@
198#define USB_PID_AVERMEDIA_A850 0x850a 198#define USB_PID_AVERMEDIA_A850 0x850a
199#define USB_PID_AVERMEDIA_A805 0xa805 199#define USB_PID_AVERMEDIA_A805 0xa805
200#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 200#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
201#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
201#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 202#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
202#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 203#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
203#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 204#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c
index 20ca9d9ee99b..a6de489a6a39 100644
--- a/drivers/media/dvb/dvb-usb/ttusb2.c
+++ b/drivers/media/dvb/dvb-usb/ttusb2.c
@@ -29,6 +29,8 @@
29 29
30#include "tda826x.h" 30#include "tda826x.h"
31#include "tda10086.h" 31#include "tda10086.h"
32#include "tda1002x.h"
33#include "tda827x.h"
32#include "lnbp21.h" 34#include "lnbp21.h"
33 35
34/* debug */ 36/* debug */
@@ -150,7 +152,17 @@ static struct tda10086_config tda10086_config = {
150 .xtal_freq = TDA10086_XTAL_16M, 152 .xtal_freq = TDA10086_XTAL_16M,
151}; 153};
152 154
153static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) 155static struct tda10023_config tda10023_config = {
156 .demod_address = 0x0c,
157 .invert = 0,
158 .xtal = 16000000,
159 .pll_m = 11,
160 .pll_p = 3,
161 .pll_n = 1,
162 .deltaf = 0xa511,
163};
164
165static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
154{ 166{
155 if (usb_set_interface(adap->dev->udev,0,3) < 0) 167 if (usb_set_interface(adap->dev->udev,0,3) < 0)
156 err("set interface to alts=3 failed"); 168 err("set interface to alts=3 failed");
@@ -163,7 +175,27 @@ static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
163 return 0; 175 return 0;
164} 176}
165 177
166static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap) 178static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
179{
180 if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
181 err("set interface to alts=3 failed");
182 if ((adap->fe = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) {
183 deb_info("TDA10023 attach failed\n");
184 return -ENODEV;
185 }
186 return 0;
187}
188
189static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
190{
191 if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) {
192 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
193 return -ENODEV;
194 }
195 return 0;
196}
197
198static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
167{ 199{
168 if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) { 200 if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
169 deb_info("TDA8263 attach failed\n"); 201 deb_info("TDA8263 attach failed\n");
@@ -180,6 +212,7 @@ static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap)
180/* DVB USB Driver stuff */ 212/* DVB USB Driver stuff */
181static struct dvb_usb_device_properties ttusb2_properties; 213static struct dvb_usb_device_properties ttusb2_properties;
182static struct dvb_usb_device_properties ttusb2_properties_s2400; 214static struct dvb_usb_device_properties ttusb2_properties_s2400;
215static struct dvb_usb_device_properties ttusb2_properties_ct3650;
183 216
184static int ttusb2_probe(struct usb_interface *intf, 217static int ttusb2_probe(struct usb_interface *intf,
185 const struct usb_device_id *id) 218 const struct usb_device_id *id)
@@ -187,6 +220,8 @@ static int ttusb2_probe(struct usb_interface *intf,
187 if (0 == dvb_usb_device_init(intf, &ttusb2_properties, 220 if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
188 THIS_MODULE, NULL, adapter_nr) || 221 THIS_MODULE, NULL, adapter_nr) ||
189 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400, 222 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
223 THIS_MODULE, NULL, adapter_nr) ||
224 0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
190 THIS_MODULE, NULL, adapter_nr)) 225 THIS_MODULE, NULL, adapter_nr))
191 return 0; 226 return 0;
192 return -ENODEV; 227 return -ENODEV;
@@ -197,6 +232,8 @@ static struct usb_device_id ttusb2_table [] = {
197 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) }, 232 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
198 { USB_DEVICE(USB_VID_TECHNOTREND, 233 { USB_DEVICE(USB_VID_TECHNOTREND,
199 USB_PID_TECHNOTREND_CONNECT_S2400) }, 234 USB_PID_TECHNOTREND_CONNECT_S2400) },
235 { USB_DEVICE(USB_VID_TECHNOTREND,
236 USB_PID_TECHNOTREND_CONNECT_CT3650) },
200 {} /* Terminating entry */ 237 {} /* Terminating entry */
201}; 238};
202MODULE_DEVICE_TABLE (usb, ttusb2_table); 239MODULE_DEVICE_TABLE (usb, ttusb2_table);
@@ -214,8 +251,8 @@ static struct dvb_usb_device_properties ttusb2_properties = {
214 { 251 {
215 .streaming_ctrl = NULL, // ttusb2_streaming_ctrl, 252 .streaming_ctrl = NULL, // ttusb2_streaming_ctrl,
216 253
217 .frontend_attach = ttusb2_frontend_attach, 254 .frontend_attach = ttusb2_frontend_tda10086_attach,
218 .tuner_attach = ttusb2_tuner_attach, 255 .tuner_attach = ttusb2_tuner_tda826x_attach,
219 256
220 /* parameter for the MPEG2-data transfer */ 257 /* parameter for the MPEG2-data transfer */
221 .stream = { 258 .stream = {
@@ -266,8 +303,8 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
266 { 303 {
267 .streaming_ctrl = NULL, 304 .streaming_ctrl = NULL,
268 305
269 .frontend_attach = ttusb2_frontend_attach, 306 .frontend_attach = ttusb2_frontend_tda10086_attach,
270 .tuner_attach = ttusb2_tuner_attach, 307 .tuner_attach = ttusb2_tuner_tda826x_attach,
271 308
272 /* parameter for the MPEG2-data transfer */ 309 /* parameter for the MPEG2-data transfer */
273 .stream = { 310 .stream = {
@@ -301,6 +338,52 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
301 } 338 }
302}; 339};
303 340
341static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
342 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
343
344 .usb_ctrl = CYPRESS_FX2,
345
346 .size_of_priv = sizeof(struct ttusb2_state),
347
348 .num_adapters = 1,
349 .adapter = {
350 {
351 .streaming_ctrl = NULL,
352
353 .frontend_attach = ttusb2_frontend_tda10023_attach,
354 .tuner_attach = ttusb2_tuner_tda827x_attach,
355
356 /* parameter for the MPEG2-data transfer */
357 .stream = {
358 .type = USB_ISOC,
359 .count = 5,
360 .endpoint = 0x02,
361 .u = {
362 .isoc = {
363 .framesperurb = 4,
364 .framesize = 940,
365 .interval = 1,
366 }
367 }
368 }
369 },
370 },
371
372 .power_ctrl = ttusb2_power_ctrl,
373 .identify_state = ttusb2_identify_state,
374
375 .i2c_algo = &ttusb2_i2c_algo,
376
377 .generic_bulk_ctrl_endpoint = 0x01,
378
379 .num_device_descs = 1,
380 .devices = {
381 { "Technotrend TT-connect CT-3650",
382 .warm_ids = { &ttusb2_table[3], NULL },
383 },
384 }
385};
386
304static struct usb_driver ttusb2_driver = { 387static struct usb_driver ttusb2_driver = {
305 .name = "dvb_usb_ttusb2", 388 .name = "dvb_usb_ttusb2",
306 .probe = ttusb2_probe, 389 .probe = ttusb2_probe,
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
index 26333b4f4d3e..b34ca7afb0e6 100644
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -58,7 +58,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
58 num = hpsb_iso_n_ready(iso); 58 num = hpsb_iso_n_ready(iso);
59 59
60 if (!fdtv) { 60 if (!fdtv) {
61 dev_err(fdtv->device, "received at unknown iso channel\n"); 61 pr_err("received at unknown iso channel\n");
62 goto out; 62 goto out;
63 } 63 }
64 64
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 68dba3a4b4da..29cdbfe36852 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -567,30 +567,6 @@ static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
567 567
568/* ----------------------------------------------------------------------- */ 568/* ----------------------------------------------------------------------- */
569 569
570static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
571{
572 switch (fmt->type) {
573 default:
574 return -EINVAL;
575 }
576 return 0;
577}
578
579static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
580{
581 switch (fmt->type) {
582 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
583 /* Not yet implemented */
584 break;
585 default:
586 return -EINVAL;
587 }
588
589 return 0;
590}
591
592/* ----------------------------------------------------------------------- */
593
594#ifdef CONFIG_VIDEO_ADV_DEBUG 570#ifdef CONFIG_VIDEO_ADV_DEBUG
595static int au8522_g_register(struct v4l2_subdev *sd, 571static int au8522_g_register(struct v4l2_subdev *sd,
596 struct v4l2_dbg_register *reg) 572 struct v4l2_dbg_register *reg)
@@ -772,8 +748,6 @@ static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
772 748
773static const struct v4l2_subdev_video_ops au8522_video_ops = { 749static const struct v4l2_subdev_video_ops au8522_video_ops = {
774 .s_routing = au8522_s_video_routing, 750 .s_routing = au8522_s_video_routing,
775 .g_fmt = au8522_g_fmt,
776 .s_fmt = au8522_s_fmt,
777 .s_stream = au8522_s_stream, 751 .s_stream = au8522_s_stream,
778}; 752};
779 753
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
index 78001e8bcdb7..fc61d9230db8 100644
--- a/drivers/media/dvb/frontends/ds3000.c
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -969,15 +969,12 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
969 dprintk("%s\n", __func__); 969 dprintk("%s\n", __func__);
970 970
971 /* allocate memory for the internal state */ 971 /* allocate memory for the internal state */
972 state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL); 972 state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
973 if (state == NULL) { 973 if (state == NULL) {
974 printk(KERN_ERR "Unable to kmalloc\n"); 974 printk(KERN_ERR "Unable to kmalloc\n");
975 goto error2; 975 goto error2;
976 } 976 }
977 977
978 /* setup the state */
979 memset(state, 0, sizeof(struct ds3000_state));
980
981 state->config = config; 978 state->config = config;
982 state->i2c = i2c; 979 state->i2c = i2c;
983 state->prevUCBS2 = 0; 980 state->prevUCBS2 = 0;
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
index 42591ce1aaad..f36cab12bdc7 100644
--- a/drivers/media/dvb/frontends/stv6110x.c
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -303,7 +303,10 @@ static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
303 303
304static int stv6110x_sleep(struct dvb_frontend *fe) 304static int stv6110x_sleep(struct dvb_frontend *fe)
305{ 305{
306 return stv6110x_set_mode(fe, TUNER_SLEEP); 306 if (fe->tuner_priv)
307 return stv6110x_set_mode(fe, TUNER_SLEEP);
308
309 return 0;
307} 310}
308 311
309static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) 312static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
index 692c3e226e83..4692a41ad95b 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -217,6 +217,19 @@ static struct ngene_info ngene_info_cineS2v5 = {
217 .fw_version = 15, 217 .fw_version = 15,
218}; 218};
219 219
220static struct ngene_info ngene_info_duoFlexS2 = {
221 .type = NGENE_SIDEWINDER,
222 .name = "Digital Devices DuoFlex S2 miniPCIe",
223 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
224 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
225 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
226 .fe_config = {&fe_cineS2, &fe_cineS2},
227 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
228 .lnb = {0x0a, 0x08},
229 .tsf = {3, 3},
230 .fw_version = 15,
231};
232
220static struct ngene_info ngene_info_m780 = { 233static struct ngene_info ngene_info_m780 = {
221 .type = NGENE_APP, 234 .type = NGENE_APP,
222 .name = "Aver M780 ATSC/QAM-B", 235 .name = "Aver M780 ATSC/QAM-B",
@@ -256,6 +269,8 @@ static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
256 NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), 269 NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2),
257 NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2), 270 NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2),
258 NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5), 271 NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5),
272 NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlexS2),
273 NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlexS2),
259 NGENE_ID(0x1461, 0x062e, ngene_info_m780), 274 NGENE_ID(0x1461, 0x062e, ngene_info_m780),
260 {0} 275 {0}
261}; 276};
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index c8b4dfa0ab5f..4caeb163a666 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -53,8 +53,6 @@ MODULE_PARM_DESC(debug, "Print debugging information.");
53 53
54DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 54DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
55 55
56#define COMMAND_TIMEOUT_WORKAROUND
57
58#define dprintk if (debug) printk 56#define dprintk if (debug) printk
59 57
60#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) 58#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
@@ -147,24 +145,24 @@ static void demux_tasklet(unsigned long data)
147 } else { 145 } else {
148 if (chan->HWState == HWSTATE_RUN) { 146 if (chan->HWState == HWSTATE_RUN) {
149 u32 Flags = 0; 147 u32 Flags = 0;
148 IBufferExchange *exch1 = chan->pBufferExchange;
149 IBufferExchange *exch2 = chan->pBufferExchange2;
150 if (Cur->ngeneBuffer.SR.Flags & 0x01) 150 if (Cur->ngeneBuffer.SR.Flags & 0x01)
151 Flags |= BEF_EVEN_FIELD; 151 Flags |= BEF_EVEN_FIELD;
152 if (Cur->ngeneBuffer.SR.Flags & 0x20) 152 if (Cur->ngeneBuffer.SR.Flags & 0x20)
153 Flags |= BEF_OVERFLOW; 153 Flags |= BEF_OVERFLOW;
154 if (chan->pBufferExchange) 154 spin_unlock_irq(&chan->state_lock);
155 chan->pBufferExchange(chan, 155 if (exch1)
156 Cur->Buffer1, 156 exch1(chan, Cur->Buffer1,
157 chan-> 157 chan->Capture1Length,
158 Capture1Length, 158 Cur->ngeneBuffer.SR.Clock,
159 Cur->ngeneBuffer. 159 Flags);
160 SR.Clock, Flags); 160 if (exch2)
161 if (chan->pBufferExchange2) 161 exch2(chan, Cur->Buffer2,
162 chan->pBufferExchange2(chan, 162 chan->Capture2Length,
163 Cur->Buffer2, 163 Cur->ngeneBuffer.SR.Clock,
164 chan-> 164 Flags);
165 Capture2Length, 165 spin_lock_irq(&chan->state_lock);
166 Cur->ngeneBuffer.
167 SR.Clock, Flags);
168 } else if (chan->HWState != HWSTATE_STOP) 166 } else if (chan->HWState != HWSTATE_STOP)
169 chan->HWState = HWSTATE_RUN; 167 chan->HWState = HWSTATE_RUN;
170 } 168 }
@@ -572,11 +570,7 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream,
572 u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700); 570 u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700);
573 u16 BsSDO = 0x9B00; 571 u16 BsSDO = 0x9B00;
574 572
575 /* down(&dev->stream_mutex); */ 573 down(&dev->stream_mutex);
576 while (down_trylock(&dev->stream_mutex)) {
577 printk(KERN_INFO DEVICE_NAME ": SC locked\n");
578 msleep(1);
579 }
580 memset(&com, 0, sizeof(com)); 574 memset(&com, 0, sizeof(com));
581 com.cmd.hdr.Opcode = CMD_CONTROL; 575 com.cmd.hdr.Opcode = CMD_CONTROL;
582 com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2; 576 com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2;
@@ -1252,14 +1246,17 @@ static int ngene_load_firm(struct ngene *dev)
1252 version = 15; 1246 version = 15;
1253 size = 23466; 1247 size = 23466;
1254 fw_name = "ngene_15.fw"; 1248 fw_name = "ngene_15.fw";
1249 dev->cmd_timeout_workaround = true;
1255 break; 1250 break;
1256 case 16: 1251 case 16:
1257 size = 23498; 1252 size = 23498;
1258 fw_name = "ngene_16.fw"; 1253 fw_name = "ngene_16.fw";
1254 dev->cmd_timeout_workaround = true;
1259 break; 1255 break;
1260 case 17: 1256 case 17:
1261 size = 24446; 1257 size = 24446;
1262 fw_name = "ngene_17.fw"; 1258 fw_name = "ngene_17.fw";
1259 dev->cmd_timeout_workaround = true;
1263 break; 1260 break;
1264 } 1261 }
1265 1262
@@ -1299,11 +1296,16 @@ static void ngene_stop(struct ngene *dev)
1299 ngwritel(0, NGENE_EVENT); 1296 ngwritel(0, NGENE_EVENT);
1300 ngwritel(0, NGENE_EVENT_HI); 1297 ngwritel(0, NGENE_EVENT_HI);
1301 free_irq(dev->pci_dev->irq, dev); 1298 free_irq(dev->pci_dev->irq, dev);
1299#ifdef CONFIG_PCI_MSI
1300 if (dev->msi_enabled)
1301 pci_disable_msi(dev->pci_dev);
1302#endif
1302} 1303}
1303 1304
1304static int ngene_start(struct ngene *dev) 1305static int ngene_start(struct ngene *dev)
1305{ 1306{
1306 int stat; 1307 int stat;
1308 unsigned long flags;
1307 int i; 1309 int i;
1308 1310
1309 pci_set_master(dev->pci_dev); 1311 pci_set_master(dev->pci_dev);
@@ -1333,6 +1335,28 @@ static int ngene_start(struct ngene *dev)
1333 if (stat < 0) 1335 if (stat < 0)
1334 goto fail; 1336 goto fail;
1335 1337
1338#ifdef CONFIG_PCI_MSI
1339 /* enable MSI if kernel and card support it */
1340 if (pci_msi_enabled() && dev->card_info->msi_supported) {
1341 ngwritel(0, NGENE_INT_ENABLE);
1342 free_irq(dev->pci_dev->irq, dev);
1343 stat = pci_enable_msi(dev->pci_dev);
1344 if (stat) {
1345 printk(KERN_INFO DEVICE_NAME
1346 ": MSI not available\n");
1347 flags = IRQF_SHARED;
1348 } else {
1349 flags = 0;
1350 dev->msi_enabled = true;
1351 }
1352 stat = request_irq(dev->pci_dev->irq, irq_handler,
1353 flags, "nGene", dev);
1354 if (stat < 0)
1355 goto fail2;
1356 ngwritel(1, NGENE_INT_ENABLE);
1357 }
1358#endif
1359
1336 stat = ngene_i2c_init(dev, 0); 1360 stat = ngene_i2c_init(dev, 0);
1337 if (stat < 0) 1361 if (stat < 0)
1338 goto fail; 1362 goto fail;
@@ -1358,10 +1382,18 @@ static int ngene_start(struct ngene *dev)
1358 bconf = BUFFER_CONFIG_3333; 1382 bconf = BUFFER_CONFIG_3333;
1359 stat = ngene_command_config_buf(dev, bconf); 1383 stat = ngene_command_config_buf(dev, bconf);
1360 } 1384 }
1361 return stat; 1385 if (!stat)
1386 return stat;
1387
1388 /* otherwise error: fall through */
1362fail: 1389fail:
1363 ngwritel(0, NGENE_INT_ENABLE); 1390 ngwritel(0, NGENE_INT_ENABLE);
1364 free_irq(dev->pci_dev->irq, dev); 1391 free_irq(dev->pci_dev->irq, dev);
1392#ifdef CONFIG_PCI_MSI
1393fail2:
1394 if (dev->msi_enabled)
1395 pci_disable_msi(dev->pci_dev);
1396#endif
1365 return stat; 1397 return stat;
1366} 1398}
1367 1399
@@ -1379,10 +1411,8 @@ static void release_channel(struct ngene_channel *chan)
1379 struct ngene_info *ni = dev->card_info; 1411 struct ngene_info *ni = dev->card_info;
1380 int io = ni->io_type[chan->number]; 1412 int io = ni->io_type[chan->number];
1381 1413
1382#ifdef COMMAND_TIMEOUT_WORKAROUND 1414 if (chan->dev->cmd_timeout_workaround && chan->running)
1383 if (chan->running)
1384 set_transfer(chan, 0); 1415 set_transfer(chan, 0);
1385#endif
1386 1416
1387 tasklet_kill(&chan->demux_tasklet); 1417 tasklet_kill(&chan->demux_tasklet);
1388 1418
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c
index 96013eb353cd..48f980b21d66 100644
--- a/drivers/media/dvb/ngene/ngene-dvb.c
+++ b/drivers/media/dvb/ngene/ngene-dvb.c
@@ -37,15 +37,12 @@
37#include <linux/pci.h> 37#include <linux/pci.h>
38#include <linux/smp_lock.h> 38#include <linux/smp_lock.h>
39#include <linux/timer.h> 39#include <linux/timer.h>
40#include <linux/version.h>
41#include <linux/byteorder/generic.h> 40#include <linux/byteorder/generic.h>
42#include <linux/firmware.h> 41#include <linux/firmware.h>
43#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
44 43
45#include "ngene.h" 44#include "ngene.h"
46 45
47#define COMMAND_TIMEOUT_WORKAROUND
48
49 46
50/****************************************************************************/ 47/****************************************************************************/
51/* COMMAND API interface ****************************************************/ 48/* COMMAND API interface ****************************************************/
@@ -69,9 +66,7 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
69 struct ngene_channel *chan = priv; 66 struct ngene_channel *chan = priv;
70 67
71 68
72#ifdef COMMAND_TIMEOUT_WORKAROUND
73 if (chan->users > 0) 69 if (chan->users > 0)
74#endif
75 dvb_dmx_swfilter(&chan->demux, buf, len); 70 dvb_dmx_swfilter(&chan->demux, buf, len);
76 return NULL; 71 return NULL;
77} 72}
@@ -106,11 +101,8 @@ int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
106 struct ngene_channel *chan = dvbdmx->priv; 101 struct ngene_channel *chan = dvbdmx->priv;
107 102
108 if (chan->users == 0) { 103 if (chan->users == 0) {
109#ifdef COMMAND_TIMEOUT_WORKAROUND 104 if (!chan->dev->cmd_timeout_workaround || !chan->running)
110 if (!chan->running)
111#endif
112 set_transfer(chan, 1); 105 set_transfer(chan, 1);
113 /* msleep(10); */
114 } 106 }
115 107
116 return ++chan->users; 108 return ++chan->users;
@@ -124,9 +116,8 @@ int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
124 if (--chan->users) 116 if (--chan->users)
125 return chan->users; 117 return chan->users;
126 118
127#ifndef COMMAND_TIMEOUT_WORKAROUND 119 if (!chan->dev->cmd_timeout_workaround)
128 set_transfer(chan, 0); 120 set_transfer(chan, 0);
129#endif
130 121
131 return 0; 122 return 0;
132} 123}
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c
index 2ef54ca6badd..477fe0aade86 100644
--- a/drivers/media/dvb/ngene/ngene-i2c.c
+++ b/drivers/media/dvb/ngene/ngene-i2c.c
@@ -39,7 +39,6 @@
39#include <linux/pci_ids.h> 39#include <linux/pci_ids.h>
40#include <linux/smp_lock.h> 40#include <linux/smp_lock.h>
41#include <linux/timer.h> 41#include <linux/timer.h>
42#include <linux/version.h>
43#include <linux/byteorder/generic.h> 42#include <linux/byteorder/generic.h>
44#include <linux/firmware.h> 43#include <linux/firmware.h>
45#include <linux/vmalloc.h> 44#include <linux/vmalloc.h>
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h
index 676fcbb79026..8fb4200f83f8 100644
--- a/drivers/media/dvb/ngene/ngene.h
+++ b/drivers/media/dvb/ngene/ngene.h
@@ -725,6 +725,8 @@ struct ngene {
725 u32 device_version; 725 u32 device_version;
726 u32 fw_interface_version; 726 u32 fw_interface_version;
727 u32 icounts; 727 u32 icounts;
728 bool msi_enabled;
729 bool cmd_timeout_workaround;
728 730
729 u8 *CmdDoneByte; 731 u8 *CmdDoneByte;
730 int BootFirmware; 732 int BootFirmware;
@@ -797,6 +799,7 @@ struct ngene_info {
797#define NGENE_VBOX_V2 7 799#define NGENE_VBOX_V2 7
798 800
799 int fw_version; 801 int fw_version;
802 bool msi_supported;
800 char *name; 803 char *name;
801 804
802 int io_type[MAX_STREAM]; 805 int io_type[MAX_STREAM];
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index d8d4214fd65f..32a7ec65ec42 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -68,13 +68,14 @@ config DVB_BUDGET
68 select DVB_VES1820 if !DVB_FE_CUSTOMISE 68 select DVB_VES1820 if !DVB_FE_CUSTOMISE
69 select DVB_L64781 if !DVB_FE_CUSTOMISE 69 select DVB_L64781 if !DVB_FE_CUSTOMISE
70 select DVB_TDA8083 if !DVB_FE_CUSTOMISE 70 select DVB_TDA8083 if !DVB_FE_CUSTOMISE
71 select DVB_TDA10021 if !DVB_FE_CUSTOMISE
72 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
73 select DVB_S5H1420 if !DVB_FE_CUSTOMISE 71 select DVB_S5H1420 if !DVB_FE_CUSTOMISE
74 select DVB_TDA10086 if !DVB_FE_CUSTOMISE 72 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
75 select DVB_TDA826X if !DVB_FE_CUSTOMISE 73 select DVB_TDA826X if !DVB_FE_CUSTOMISE
76 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 74 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
77 select DVB_TDA1004X if !DVB_FE_CUSTOMISE 75 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
76 select DVB_ISL6423 if !DVB_FE_CUSTOMISE
77 select DVB_STV090x if !DVB_FE_CUSTOMISE
78 select DVB_STV6110x if !DVB_FE_CUSTOMISE
78 help 79 help
79 Support for simple SAA7146 based DVB cards (so called Budget- 80 Support for simple SAA7146 based DVB cards (so called Budget-
80 or Nova-PCI cards) without onboard MPEG2 decoder, and without 81 or Nova-PCI cards) without onboard MPEG2 decoder, and without
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 461714396331..13ac9e3ab121 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -215,6 +215,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
215 break; 215 break;
216 case 0x1010: 216 case 0x1010:
217 case 0x1017: 217 case 0x1017:
218 case 0x1019:
218 case 0x101a: 219 case 0x101a:
219 /* for the Technotrend 1500 bundled remote */ 220 /* for the Technotrend 1500 bundled remote */
220 ir_codes = RC_MAP_TT_1500; 221 ir_codes = RC_MAP_TT_1500;
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index a5844d08d8b7..67a4ec8768a6 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -482,7 +482,6 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
482 cancel_work_sync(&radio->radio_work); 482 cancel_work_sync(&radio->radio_work);
483 video_unregister_device(radio->videodev); 483 video_unregister_device(radio->videodev);
484 kfree(radio); 484 kfree(radio);
485 i2c_set_clientdata(client, NULL);
486 485
487 return 0; 486 return 0;
488} 487}
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index ad9e6f9c22e9..bdbc9d305419 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -646,7 +646,7 @@ config VIDEO_PMS
646 646
647config VIDEO_BWQCAM 647config VIDEO_BWQCAM
648 tristate "Quickcam BW Video For Linux" 648 tristate "Quickcam BW Video For Linux"
649 depends on PARPORT && VIDEO_V4L1 649 depends on PARPORT && VIDEO_V4L2
650 help 650 help
651 Say Y have if you the black and white version of the QuickCam 651 Say Y have if you the black and white version of the QuickCam
652 camera. See the next option for the color version. 652 camera. See the next option for the color version.
@@ -656,7 +656,7 @@ config VIDEO_BWQCAM
656 656
657config VIDEO_CQCAM 657config VIDEO_CQCAM
658 tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" 658 tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)"
659 depends on EXPERIMENTAL && PARPORT && VIDEO_V4L1 659 depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2
660 help 660 help
661 This is the video4linux driver for the colour version of the 661 This is the video4linux driver for the colour version of the
662 Connectix QuickCam. If you have one of these cameras, say Y here, 662 Connectix QuickCam. If you have one of these cameras, say Y here,
diff --git a/drivers/media/video/ak881x.c b/drivers/media/video/ak881x.c
index 35390d4717b9..1573392f74bd 100644
--- a/drivers/media/video/ak881x.c
+++ b/drivers/media/video/ak881x.c
@@ -11,6 +11,7 @@
11#include <linux/i2c.h> 11#include <linux/i2c.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/slab.h>
14#include <linux/videodev2.h> 15#include <linux/videodev2.h>
15 16
16#include <media/ak881x.h> 17#include <media/ak881x.h>
@@ -141,7 +142,7 @@ static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd,
141 return ak881x_try_g_mbus_fmt(sd, mf); 142 return ak881x_try_g_mbus_fmt(sd, mf);
142} 143}
143 144
144static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, int index, 145static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
145 enum v4l2_mbus_pixelcode *code) 146 enum v4l2_mbus_pixelcode *code)
146{ 147{
147 if (index) 148 if (index)
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 3c9e754d73a0..935e0c9a9674 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -66,19 +66,58 @@ OTHER DEALINGS IN THE SOFTWARE.
66#include <linux/delay.h> 66#include <linux/delay.h>
67#include <linux/errno.h> 67#include <linux/errno.h>
68#include <linux/fs.h> 68#include <linux/fs.h>
69#include <linux/init.h>
70#include <linux/kernel.h> 69#include <linux/kernel.h>
71#include <linux/slab.h> 70#include <linux/slab.h>
72#include <linux/mm.h> 71#include <linux/mm.h>
73#include <linux/parport.h> 72#include <linux/parport.h>
74#include <linux/sched.h> 73#include <linux/sched.h>
75#include <linux/videodev.h> 74#include <linux/version.h>
76#include <media/v4l2-common.h> 75#include <linux/videodev2.h>
77#include <media/v4l2-ioctl.h>
78#include <linux/mutex.h> 76#include <linux/mutex.h>
79#include <asm/uaccess.h> 77#include <asm/uaccess.h>
80 78#include <media/v4l2-common.h>
81#include "bw-qcam.h" 79#include <media/v4l2-ioctl.h>
80#include <media/v4l2-device.h>
81
82/* One from column A... */
83#define QC_NOTSET 0
84#define QC_UNIDIR 1
85#define QC_BIDIR 2
86#define QC_SERIAL 3
87
88/* ... and one from column B */
89#define QC_ANY 0x00
90#define QC_FORCE_UNIDIR 0x10
91#define QC_FORCE_BIDIR 0x20
92#define QC_FORCE_SERIAL 0x30
93/* in the port_mode member */
94
95#define QC_MODE_MASK 0x07
96#define QC_FORCE_MASK 0x70
97
98#define MAX_HEIGHT 243
99#define MAX_WIDTH 336
100
101/* Bit fields for status flags */
102#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
103
104struct qcam {
105 struct v4l2_device v4l2_dev;
106 struct video_device vdev;
107 struct pardevice *pdev;
108 struct parport *pport;
109 struct mutex lock;
110 int width, height;
111 int bpp;
112 int mode;
113 int contrast, brightness, whitebal;
114 int port_mode;
115 int transfer_scale;
116 int top, left;
117 int status;
118 unsigned int saved_bits;
119 unsigned long in_use;
120};
82 121
83static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */ 122static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
84static unsigned int yieldlines = 4; /* Yield after this many during capture */ 123static unsigned int yieldlines = 4; /* Yield after this many during capture */
@@ -93,22 +132,26 @@ module_param(video_nr, int, 0);
93 * immediately attempt to initialize qcam */ 132 * immediately attempt to initialize qcam */
94module_param(force_init, int, 0); 133module_param(force_init, int, 0);
95 134
96static inline int read_lpstatus(struct qcam_device *q) 135#define MAX_CAMS 4
136static struct qcam *qcams[MAX_CAMS];
137static unsigned int num_cams;
138
139static inline int read_lpstatus(struct qcam *q)
97{ 140{
98 return parport_read_status(q->pport); 141 return parport_read_status(q->pport);
99} 142}
100 143
101static inline int read_lpdata(struct qcam_device *q) 144static inline int read_lpdata(struct qcam *q)
102{ 145{
103 return parport_read_data(q->pport); 146 return parport_read_data(q->pport);
104} 147}
105 148
106static inline void write_lpdata(struct qcam_device *q, int d) 149static inline void write_lpdata(struct qcam *q, int d)
107{ 150{
108 parport_write_data(q->pport, d); 151 parport_write_data(q->pport, d);
109} 152}
110 153
111static inline void write_lpcontrol(struct qcam_device *q, int d) 154static void write_lpcontrol(struct qcam *q, int d)
112{ 155{
113 if (d & 0x20) { 156 if (d & 0x20) {
114 /* Set bidirectional mode to reverse (data in) */ 157 /* Set bidirectional mode to reverse (data in) */
@@ -124,126 +167,11 @@ static inline void write_lpcontrol(struct qcam_device *q, int d)
124 parport_write_control(q->pport, d); 167 parport_write_control(q->pport, d);
125} 168}
126 169
127static int qc_waithand(struct qcam_device *q, int val);
128static int qc_command(struct qcam_device *q, int command);
129static int qc_readparam(struct qcam_device *q);
130static int qc_setscanmode(struct qcam_device *q);
131static int qc_readbytes(struct qcam_device *q, char buffer[]);
132
133static struct video_device qcam_template;
134
135static int qc_calibrate(struct qcam_device *q)
136{
137 /*
138 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
139 * The white balance is an individiual value for each
140 * quickcam.
141 */
142
143 int value;
144 int count = 0;
145
146 qc_command(q, 27); /* AutoAdjustOffset */
147 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
148
149 /* GetOffset (33) will read 255 until autocalibration */
150 /* is finished. After that, a value of 1-254 will be */
151 /* returned. */
152
153 do {
154 qc_command(q, 33);
155 value = qc_readparam(q);
156 mdelay(1);
157 schedule();
158 count++;
159 } while (value == 0xff && count < 2048);
160
161 q->whitebal = value;
162 return value;
163}
164
165/* Initialize the QuickCam driver control structure. This is where
166 * defaults are set for people who don't have a config file.*/
167
168static struct qcam_device *qcam_init(struct parport *port)
169{
170 struct qcam_device *q;
171
172 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
173 if (q == NULL)
174 return NULL;
175
176 q->pport = port;
177 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
178 NULL, 0, NULL);
179 if (q->pdev == NULL) {
180 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
181 port->name);
182 kfree(q);
183 return NULL;
184 }
185
186 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
187
188 mutex_init(&q->lock);
189
190 q->port_mode = (QC_ANY | QC_NOTSET);
191 q->width = 320;
192 q->height = 240;
193 q->bpp = 4;
194 q->transfer_scale = 2;
195 q->contrast = 192;
196 q->brightness = 180;
197 q->whitebal = 105;
198 q->top = 1;
199 q->left = 14;
200 q->mode = -1;
201 q->status = QC_PARAM_CHANGE;
202 return q;
203}
204
205
206/* qc_command is probably a bit of a misnomer -- it's used to send
207 * bytes *to* the camera. Generally, these bytes are either commands
208 * or arguments to commands, so the name fits, but it still bugs me a
209 * bit. See the documentation for a list of commands. */
210
211static int qc_command(struct qcam_device *q, int command)
212{
213 int n1, n2;
214 int cmd;
215
216 write_lpdata(q, command);
217 write_lpcontrol(q, 6);
218
219 n1 = qc_waithand(q, 1);
220
221 write_lpcontrol(q, 0xe);
222 n2 = qc_waithand(q, 0);
223
224 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
225 return cmd;
226}
227
228static int qc_readparam(struct qcam_device *q)
229{
230 int n1, n2;
231 int cmd;
232
233 write_lpcontrol(q, 6);
234 n1 = qc_waithand(q, 1);
235
236 write_lpcontrol(q, 0xe);
237 n2 = qc_waithand(q, 0);
238
239 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
240 return cmd;
241}
242 170
243/* qc_waithand busy-waits for a handshake signal from the QuickCam. 171/* qc_waithand busy-waits for a handshake signal from the QuickCam.
244 * Almost all communication with the camera requires handshaking. */ 172 * Almost all communication with the camera requires handshaking. */
245 173
246static int qc_waithand(struct qcam_device *q, int val) 174static int qc_waithand(struct qcam *q, int val)
247{ 175{
248 int status; 176 int status;
249 int runs = 0; 177 int runs = 0;
@@ -286,7 +214,7 @@ static int qc_waithand(struct qcam_device *q, int val)
286 * (bit 3 of status register). It also returns the last value read, 214 * (bit 3 of status register). It also returns the last value read,
287 * since this data is useful. */ 215 * since this data is useful. */
288 216
289static unsigned int qc_waithand2(struct qcam_device *q, int val) 217static unsigned int qc_waithand2(struct qcam *q, int val)
290{ 218{
291 unsigned int status; 219 unsigned int status;
292 int runs = 0; 220 int runs = 0;
@@ -309,6 +237,43 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
309 return status; 237 return status;
310} 238}
311 239
240/* qc_command is probably a bit of a misnomer -- it's used to send
241 * bytes *to* the camera. Generally, these bytes are either commands
242 * or arguments to commands, so the name fits, but it still bugs me a
243 * bit. See the documentation for a list of commands. */
244
245static int qc_command(struct qcam *q, int command)
246{
247 int n1, n2;
248 int cmd;
249
250 write_lpdata(q, command);
251 write_lpcontrol(q, 6);
252
253 n1 = qc_waithand(q, 1);
254
255 write_lpcontrol(q, 0xe);
256 n2 = qc_waithand(q, 0);
257
258 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
259 return cmd;
260}
261
262static int qc_readparam(struct qcam *q)
263{
264 int n1, n2;
265 int cmd;
266
267 write_lpcontrol(q, 6);
268 n1 = qc_waithand(q, 1);
269
270 write_lpcontrol(q, 0xe);
271 n2 = qc_waithand(q, 0);
272
273 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
274 return cmd;
275}
276
312 277
313/* Try to detect a QuickCam. It appears to flash the upper 4 bits of 278/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
314 the status register at 5-10 Hz. This is only used in the autoprobe 279 the status register at 5-10 Hz. This is only used in the autoprobe
@@ -317,7 +282,7 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
317 almost completely safe, while their method screws up my printer if 282 almost completely safe, while their method screws up my printer if
318 I plug it in before the camera. */ 283 I plug it in before the camera. */
319 284
320static int qc_detect(struct qcam_device *q) 285static int qc_detect(struct qcam *q)
321{ 286{
322 int reg, lastreg; 287 int reg, lastreg;
323 int count = 0; 288 int count = 0;
@@ -358,41 +323,6 @@ static int qc_detect(struct qcam_device *q)
358 } 323 }
359} 324}
360 325
361
362/* Reset the QuickCam. This uses the same sequence the Windows
363 * QuickPic program uses. Someone with a bi-directional port should
364 * check that bi-directional mode is detected right, and then
365 * implement bi-directional mode in qc_readbyte(). */
366
367static void qc_reset(struct qcam_device *q)
368{
369 switch (q->port_mode & QC_FORCE_MASK) {
370 case QC_FORCE_UNIDIR:
371 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
372 break;
373
374 case QC_FORCE_BIDIR:
375 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
376 break;
377
378 case QC_ANY:
379 write_lpcontrol(q, 0x20);
380 write_lpdata(q, 0x75);
381
382 if (read_lpdata(q) != 0x75)
383 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
384 else
385 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
386 break;
387 }
388
389 write_lpcontrol(q, 0xb);
390 udelay(250);
391 write_lpcontrol(q, 0xe);
392 qc_setscanmode(q); /* in case port_mode changed */
393}
394
395
396/* Decide which scan mode to use. There's no real requirement that 326/* Decide which scan mode to use. There's no real requirement that
397 * the scanmode match the resolution in q->height and q-> width -- the 327 * the scanmode match the resolution in q->height and q-> width -- the
398 * camera takes the picture at the resolution specified in the 328 * camera takes the picture at the resolution specified in the
@@ -402,7 +332,7 @@ static void qc_reset(struct qcam_device *q)
402 * returned. If the scan is smaller, then the rest of the image 332 * returned. If the scan is smaller, then the rest of the image
403 * returned contains garbage. */ 333 * returned contains garbage. */
404 334
405static int qc_setscanmode(struct qcam_device *q) 335static int qc_setscanmode(struct qcam *q)
406{ 336{
407 int old_mode = q->mode; 337 int old_mode = q->mode;
408 338
@@ -442,10 +372,45 @@ static int qc_setscanmode(struct qcam_device *q)
442} 372}
443 373
444 374
375/* Reset the QuickCam. This uses the same sequence the Windows
376 * QuickPic program uses. Someone with a bi-directional port should
377 * check that bi-directional mode is detected right, and then
378 * implement bi-directional mode in qc_readbyte(). */
379
380static void qc_reset(struct qcam *q)
381{
382 switch (q->port_mode & QC_FORCE_MASK) {
383 case QC_FORCE_UNIDIR:
384 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
385 break;
386
387 case QC_FORCE_BIDIR:
388 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
389 break;
390
391 case QC_ANY:
392 write_lpcontrol(q, 0x20);
393 write_lpdata(q, 0x75);
394
395 if (read_lpdata(q) != 0x75)
396 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
397 else
398 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
399 break;
400 }
401
402 write_lpcontrol(q, 0xb);
403 udelay(250);
404 write_lpcontrol(q, 0xe);
405 qc_setscanmode(q); /* in case port_mode changed */
406}
407
408
409
445/* Reset the QuickCam and program for brightness, contrast, 410/* Reset the QuickCam and program for brightness, contrast,
446 * white-balance, and resolution. */ 411 * white-balance, and resolution. */
447 412
448static void qc_set(struct qcam_device *q) 413static void qc_set(struct qcam *q)
449{ 414{
450 int val; 415 int val;
451 int val2; 416 int val2;
@@ -499,7 +464,7 @@ static void qc_set(struct qcam_device *q)
499 the supplied buffer. It returns the number of bytes read, 464 the supplied buffer. It returns the number of bytes read,
500 or -1 on error. */ 465 or -1 on error. */
501 466
502static inline int qc_readbytes(struct qcam_device *q, char buffer[]) 467static inline int qc_readbytes(struct qcam *q, char buffer[])
503{ 468{
504 int ret = 1; 469 int ret = 1;
505 unsigned int hi, lo; 470 unsigned int hi, lo;
@@ -590,7 +555,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
590 * n=2^(bit depth)-1. Ask me for more details if you don't understand 555 * n=2^(bit depth)-1. Ask me for more details if you don't understand
591 * this. */ 556 * this. */
592 557
593static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len) 558static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
594{ 559{
595 int i, j, k, yield; 560 int i, j, k, yield;
596 int bytes; 561 int bytes;
@@ -674,171 +639,206 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
674 * Video4linux interfacing 639 * Video4linux interfacing
675 */ 640 */
676 641
677static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) 642static int qcam_querycap(struct file *file, void *priv,
643 struct v4l2_capability *vcap)
678{ 644{
679 struct video_device *dev = video_devdata(file); 645 struct qcam *qcam = video_drvdata(file);
680 struct qcam_device *qcam = (struct qcam_device *)dev;
681
682 switch (cmd) {
683 case VIDIOCGCAP:
684 {
685 struct video_capability *b = arg;
686 strcpy(b->name, "Quickcam");
687 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
688 b->channels = 1;
689 b->audios = 0;
690 b->maxwidth = 320;
691 b->maxheight = 240;
692 b->minwidth = 80;
693 b->minheight = 60;
694 return 0;
695 }
696 case VIDIOCGCHAN:
697 {
698 struct video_channel *v = arg;
699 if (v->channel != 0)
700 return -EINVAL;
701 v->flags = 0;
702 v->tuners = 0;
703 /* Good question.. its composite or SVHS so.. */
704 v->type = VIDEO_TYPE_CAMERA;
705 strcpy(v->name, "Camera");
706 return 0;
707 }
708 case VIDIOCSCHAN:
709 {
710 struct video_channel *v = arg;
711 if (v->channel != 0)
712 return -EINVAL;
713 return 0;
714 }
715 case VIDIOCGTUNER:
716 {
717 struct video_tuner *v = arg;
718 if (v->tuner)
719 return -EINVAL;
720 strcpy(v->name, "Format");
721 v->rangelow = 0;
722 v->rangehigh = 0;
723 v->flags = 0;
724 v->mode = VIDEO_MODE_AUTO;
725 return 0;
726 }
727 case VIDIOCSTUNER:
728 {
729 struct video_tuner *v = arg;
730 if (v->tuner)
731 return -EINVAL;
732 if (v->mode != VIDEO_MODE_AUTO)
733 return -EINVAL;
734 return 0;
735 }
736 case VIDIOCGPICT:
737 {
738 struct video_picture *p = arg;
739 p->colour = 0x8000;
740 p->hue = 0x8000;
741 p->brightness = qcam->brightness << 8;
742 p->contrast = qcam->contrast << 8;
743 p->whiteness = qcam->whitebal << 8;
744 p->depth = qcam->bpp;
745 p->palette = VIDEO_PALETTE_GREY;
746 return 0;
747 }
748 case VIDIOCSPICT:
749 {
750 struct video_picture *p = arg;
751 if (p->palette != VIDEO_PALETTE_GREY)
752 return -EINVAL;
753 if (p->depth != 4 && p->depth != 6)
754 return -EINVAL;
755
756 /*
757 * Now load the camera.
758 */
759
760 qcam->brightness = p->brightness >> 8;
761 qcam->contrast = p->contrast >> 8;
762 qcam->whitebal = p->whiteness >> 8;
763 qcam->bpp = p->depth;
764
765 mutex_lock(&qcam->lock);
766 qc_setscanmode(qcam);
767 mutex_unlock(&qcam->lock);
768 qcam->status |= QC_PARAM_CHANGE;
769 646
770 return 0; 647 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
771 } 648 strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card));
772 case VIDIOCSWIN: 649 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
773 { 650 vcap->version = KERNEL_VERSION(0, 0, 2);
774 struct video_window *vw = arg; 651 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
775 if (vw->flags) 652 return 0;
776 return -EINVAL; 653}
777 if (vw->clipcount)
778 return -EINVAL;
779 if (vw->height < 60 || vw->height > 240)
780 return -EINVAL;
781 if (vw->width < 80 || vw->width > 320)
782 return -EINVAL;
783
784 qcam->width = 320;
785 qcam->height = 240;
786 qcam->transfer_scale = 4;
787
788 if (vw->width >= 160 && vw->height >= 120)
789 qcam->transfer_scale = 2;
790 if (vw->width >= 320 && vw->height >= 240) {
791 qcam->width = 320;
792 qcam->height = 240;
793 qcam->transfer_scale = 1;
794 }
795 mutex_lock(&qcam->lock);
796 qc_setscanmode(qcam);
797 mutex_unlock(&qcam->lock);
798 654
799 /* We must update the camera before we grab. We could 655static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
800 just have changed the grab size */ 656{
801 qcam->status |= QC_PARAM_CHANGE; 657 if (vin->index > 0)
658 return -EINVAL;
659 strlcpy(vin->name, "Camera", sizeof(vin->name));
660 vin->type = V4L2_INPUT_TYPE_CAMERA;
661 vin->audioset = 0;
662 vin->tuner = 0;
663 vin->std = 0;
664 vin->status = 0;
665 return 0;
666}
802 667
803 /* Ok we figured out what to use from our wide choice */ 668static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
804 return 0; 669{
805 } 670 *inp = 0;
806 case VIDIOCGWIN: 671 return 0;
807 { 672}
808 struct video_window *vw = arg;
809 673
810 memset(vw, 0, sizeof(*vw)); 674static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
811 vw->width = qcam->width / qcam->transfer_scale; 675{
812 vw->height = qcam->height / qcam->transfer_scale; 676 return (inp > 0) ? -EINVAL : 0;
813 return 0; 677}
814 } 678
815 case VIDIOCKEY: 679static int qcam_queryctrl(struct file *file, void *priv,
816 return 0; 680 struct v4l2_queryctrl *qc)
817 case VIDIOCCAPTURE: 681{
818 case VIDIOCGFBUF: 682 switch (qc->id) {
819 case VIDIOCSFBUF: 683 case V4L2_CID_BRIGHTNESS:
820 case VIDIOCGFREQ: 684 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180);
821 case VIDIOCSFREQ: 685 case V4L2_CID_CONTRAST:
822 case VIDIOCGAUDIO: 686 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
823 case VIDIOCSAUDIO: 687 case V4L2_CID_GAMMA:
824 return -EINVAL; 688 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105);
689 }
690 return -EINVAL;
691}
692
693static int qcam_g_ctrl(struct file *file, void *priv,
694 struct v4l2_control *ctrl)
695{
696 struct qcam *qcam = video_drvdata(file);
697 int ret = 0;
698
699 switch (ctrl->id) {
700 case V4L2_CID_BRIGHTNESS:
701 ctrl->value = qcam->brightness;
702 break;
703 case V4L2_CID_CONTRAST:
704 ctrl->value = qcam->contrast;
705 break;
706 case V4L2_CID_GAMMA:
707 ctrl->value = qcam->whitebal;
708 break;
825 default: 709 default:
826 return -ENOIOCTLCMD; 710 ret = -EINVAL;
711 break;
827 } 712 }
713 return ret;
714}
715
716static int qcam_s_ctrl(struct file *file, void *priv,
717 struct v4l2_control *ctrl)
718{
719 struct qcam *qcam = video_drvdata(file);
720 int ret = 0;
721
722 mutex_lock(&qcam->lock);
723 switch (ctrl->id) {
724 case V4L2_CID_BRIGHTNESS:
725 qcam->brightness = ctrl->value;
726 break;
727 case V4L2_CID_CONTRAST:
728 qcam->contrast = ctrl->value;
729 break;
730 case V4L2_CID_GAMMA:
731 qcam->whitebal = ctrl->value;
732 break;
733 default:
734 ret = -EINVAL;
735 break;
736 }
737 if (ret == 0) {
738 qc_setscanmode(qcam);
739 qcam->status |= QC_PARAM_CHANGE;
740 }
741 mutex_unlock(&qcam->lock);
742 return ret;
743}
744
745static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
746{
747 struct qcam *qcam = video_drvdata(file);
748 struct v4l2_pix_format *pix = &fmt->fmt.pix;
749
750 pix->width = qcam->width / qcam->transfer_scale;
751 pix->height = qcam->height / qcam->transfer_scale;
752 pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6;
753 pix->field = V4L2_FIELD_NONE;
754 pix->bytesperline = qcam->width;
755 pix->sizeimage = qcam->width * qcam->height;
756 /* Just a guess */
757 pix->colorspace = V4L2_COLORSPACE_SRGB;
758 return 0;
759}
760
761static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
762{
763 struct v4l2_pix_format *pix = &fmt->fmt.pix;
764
765 if (pix->height <= 60 || pix->width <= 80) {
766 pix->height = 60;
767 pix->width = 80;
768 } else if (pix->height <= 120 || pix->width <= 160) {
769 pix->height = 120;
770 pix->width = 160;
771 } else {
772 pix->height = 240;
773 pix->width = 320;
774 }
775 if (pix->pixelformat != V4L2_PIX_FMT_Y4 &&
776 pix->pixelformat != V4L2_PIX_FMT_Y6)
777 pix->pixelformat = V4L2_PIX_FMT_Y4;
778 pix->field = V4L2_FIELD_NONE;
779 pix->bytesperline = pix->width;
780 pix->sizeimage = pix->width * pix->height;
781 /* Just a guess */
782 pix->colorspace = V4L2_COLORSPACE_SRGB;
783 return 0;
784}
785
786static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
787{
788 struct qcam *qcam = video_drvdata(file);
789 struct v4l2_pix_format *pix = &fmt->fmt.pix;
790 int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
791
792 if (ret)
793 return ret;
794 qcam->width = 320;
795 qcam->height = 240;
796 if (pix->height == 60)
797 qcam->transfer_scale = 4;
798 else if (pix->height == 120)
799 qcam->transfer_scale = 2;
800 else
801 qcam->transfer_scale = 1;
802 if (pix->pixelformat == V4L2_PIX_FMT_Y6)
803 qcam->bpp = 6;
804 else
805 qcam->bpp = 4;
806
807 mutex_lock(&qcam->lock);
808 qc_setscanmode(qcam);
809 /* We must update the camera before we grab. We could
810 just have changed the grab size */
811 qcam->status |= QC_PARAM_CHANGE;
812 mutex_unlock(&qcam->lock);
828 return 0; 813 return 0;
829} 814}
830 815
831static long qcam_ioctl(struct file *file, 816static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
832 unsigned int cmd, unsigned long arg)
833{ 817{
834 return video_usercopy(file, cmd, arg, qcam_do_ioctl); 818 static struct v4l2_fmtdesc formats[] = {
819 { 0, 0, 0,
820 "4-Bit Monochrome", V4L2_PIX_FMT_Y4,
821 { 0, 0, 0, 0 }
822 },
823 { 0, 0, 0,
824 "6-Bit Monochrome", V4L2_PIX_FMT_Y6,
825 { 0, 0, 0, 0 }
826 },
827 };
828 enum v4l2_buf_type type = fmt->type;
829
830 if (fmt->index > 1)
831 return -EINVAL;
832
833 *fmt = formats[fmt->index];
834 fmt->type = type;
835 return 0;
835} 836}
836 837
837static ssize_t qcam_read(struct file *file, char __user *buf, 838static ssize_t qcam_read(struct file *file, char __user *buf,
838 size_t count, loff_t *ppos) 839 size_t count, loff_t *ppos)
839{ 840{
840 struct video_device *v = video_devdata(file); 841 struct qcam *qcam = video_drvdata(file);
841 struct qcam_device *qcam = (struct qcam_device *)v;
842 int len; 842 int len;
843 parport_claim_or_block(qcam->pdev); 843 parport_claim_or_block(qcam->pdev);
844 844
@@ -858,43 +858,112 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
858 return len; 858 return len;
859} 859}
860 860
861static int qcam_exclusive_open(struct file *file) 861static const struct v4l2_file_operations qcam_fops = {
862 .owner = THIS_MODULE,
863 .ioctl = video_ioctl2,
864 .read = qcam_read,
865};
866
867static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
868 .vidioc_querycap = qcam_querycap,
869 .vidioc_g_input = qcam_g_input,
870 .vidioc_s_input = qcam_s_input,
871 .vidioc_enum_input = qcam_enum_input,
872 .vidioc_queryctrl = qcam_queryctrl,
873 .vidioc_g_ctrl = qcam_g_ctrl,
874 .vidioc_s_ctrl = qcam_s_ctrl,
875 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
876 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
877 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
878 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
879};
880
881/* Initialize the QuickCam driver control structure. This is where
882 * defaults are set for people who don't have a config file.*/
883
884static struct qcam *qcam_init(struct parport *port)
862{ 885{
863 struct video_device *dev = video_devdata(file); 886 struct qcam *qcam;
864 struct qcam_device *qcam = (struct qcam_device *)dev; 887 struct v4l2_device *v4l2_dev;
888
889 qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
890 if (qcam == NULL)
891 return NULL;
892
893 v4l2_dev = &qcam->v4l2_dev;
894 strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name));
865 895
866 return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; 896 if (v4l2_device_register(NULL, v4l2_dev) < 0) {
897 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
898 return NULL;
899 }
900
901 qcam->pport = port;
902 qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
903 NULL, 0, NULL);
904 if (qcam->pdev == NULL) {
905 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
906 kfree(qcam);
907 return NULL;
908 }
909
910 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
911 qcam->vdev.v4l2_dev = v4l2_dev;
912 qcam->vdev.fops = &qcam_fops;
913 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
914 qcam->vdev.release = video_device_release_empty;
915 video_set_drvdata(&qcam->vdev, qcam);
916
917 mutex_init(&qcam->lock);
918
919 qcam->port_mode = (QC_ANY | QC_NOTSET);
920 qcam->width = 320;
921 qcam->height = 240;
922 qcam->bpp = 4;
923 qcam->transfer_scale = 2;
924 qcam->contrast = 192;
925 qcam->brightness = 180;
926 qcam->whitebal = 105;
927 qcam->top = 1;
928 qcam->left = 14;
929 qcam->mode = -1;
930 qcam->status = QC_PARAM_CHANGE;
931 return qcam;
867} 932}
868 933
869static int qcam_exclusive_release(struct file *file) 934static int qc_calibrate(struct qcam *q)
870{ 935{
871 struct video_device *dev = video_devdata(file); 936 /*
872 struct qcam_device *qcam = (struct qcam_device *)dev; 937 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
938 * The white balance is an individual value for each
939 * quickcam.
940 */
873 941
874 clear_bit(0, &qcam->in_use); 942 int value;
875 return 0; 943 int count = 0;
876}
877 944
878static const struct v4l2_file_operations qcam_fops = { 945 qc_command(q, 27); /* AutoAdjustOffset */
879 .owner = THIS_MODULE, 946 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
880 .open = qcam_exclusive_open,
881 .release = qcam_exclusive_release,
882 .ioctl = qcam_ioctl,
883 .read = qcam_read,
884};
885static struct video_device qcam_template = {
886 .name = "Connectix Quickcam",
887 .fops = &qcam_fops,
888 .release = video_device_release_empty,
889};
890 947
891#define MAX_CAMS 4 948 /* GetOffset (33) will read 255 until autocalibration */
892static struct qcam_device *qcams[MAX_CAMS]; 949 /* is finished. After that, a value of 1-254 will be */
893static unsigned int num_cams; 950 /* returned. */
951
952 do {
953 qc_command(q, 33);
954 value = qc_readparam(q);
955 mdelay(1);
956 schedule();
957 count++;
958 } while (value == 0xff && count < 2048);
959
960 q->whitebal = value;
961 return value;
962}
894 963
895static int init_bwqcam(struct parport *port) 964static int init_bwqcam(struct parport *port)
896{ 965{
897 struct qcam_device *qcam; 966 struct qcam *qcam;
898 967
899 if (num_cams == MAX_CAMS) { 968 if (num_cams == MAX_CAMS) {
900 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS); 969 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
@@ -919,7 +988,7 @@ static int init_bwqcam(struct parport *port)
919 988
920 parport_release(qcam->pdev); 989 parport_release(qcam->pdev);
921 990
922 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name); 991 v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name);
923 992
924 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { 993 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
925 parport_unregister_device(qcam->pdev); 994 parport_unregister_device(qcam->pdev);
@@ -932,7 +1001,7 @@ static int init_bwqcam(struct parport *port)
932 return 0; 1001 return 0;
933} 1002}
934 1003
935static void close_bwqcam(struct qcam_device *qcam) 1004static void close_bwqcam(struct qcam *qcam)
936{ 1005{
937 video_unregister_device(&qcam->vdev); 1006 video_unregister_device(&qcam->vdev);
938 parport_unregister_device(qcam->pdev); 1007 parport_unregister_device(qcam->pdev);
@@ -983,7 +1052,7 @@ static void bwqcam_detach(struct parport *port)
983{ 1052{
984 int i; 1053 int i;
985 for (i = 0; i < num_cams; i++) { 1054 for (i = 0; i < num_cams; i++) {
986 struct qcam_device *qcam = qcams[i]; 1055 struct qcam *qcam = qcams[i];
987 if (qcam && qcam->pdev->port == port) { 1056 if (qcam && qcam->pdev->port == port) {
988 qcams[i] = NULL; 1057 qcams[i] = NULL;
989 close_bwqcam(qcam); 1058 close_bwqcam(qcam);
diff --git a/drivers/media/video/bw-qcam.h b/drivers/media/video/bw-qcam.h
deleted file mode 100644
index 8a60c5de0935..000000000000
--- a/drivers/media/video/bw-qcam.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Video4Linux bw-qcam driver
3 *
4 * Derived from code..
5 */
6
7/******************************************************************
8
9Copyright (C) 1996 by Scott Laird
10
11Permission is hereby granted, free of charge, to any person obtaining
12a copy of this software and associated documentation files (the
13"Software"), to deal in the Software without restriction, including
14without limitation the rights to use, copy, modify, merge, publish,
15distribute, sublicense, and/or sell copies of the Software, and to
16permit persons to whom the Software is furnished to do so, subject to
17the following conditions:
18
19The above copyright notice and this permission notice shall be
20included in all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
26OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28OTHER DEALINGS IN THE SOFTWARE.
29
30******************************************************************/
31
32/* One from column A... */
33#define QC_NOTSET 0
34#define QC_UNIDIR 1
35#define QC_BIDIR 2
36#define QC_SERIAL 3
37
38/* ... and one from column B */
39#define QC_ANY 0x00
40#define QC_FORCE_UNIDIR 0x10
41#define QC_FORCE_BIDIR 0x20
42#define QC_FORCE_SERIAL 0x30
43/* in the port_mode member */
44
45#define QC_MODE_MASK 0x07
46#define QC_FORCE_MASK 0x70
47
48#define MAX_HEIGHT 243
49#define MAX_WIDTH 336
50
51/* Bit fields for status flags */
52#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
53
54struct qcam_device {
55 struct video_device vdev;
56 struct pardevice *pdev;
57 struct parport *pport;
58 struct mutex lock;
59 int width, height;
60 int bpp;
61 int mode;
62 int contrast, brightness, whitebal;
63 int port_mode;
64 int transfer_scale;
65 int top, left;
66 int status;
67 unsigned int saved_bits;
68 unsigned long in_use;
69};
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 8f1dd88b32a6..6e4b19698c13 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -33,15 +33,17 @@
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/parport.h> 34#include <linux/parport.h>
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/videodev.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-ioctl.h>
39#include <linux/mutex.h> 36#include <linux/mutex.h>
40#include <linux/jiffies.h> 37#include <linux/jiffies.h>
41 38#include <linux/version.h>
39#include <linux/videodev2.h>
42#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include <media/v4l2-device.h>
42#include <media/v4l2-common.h>
43#include <media/v4l2-ioctl.h>
43 44
44struct qcam_device { 45struct qcam {
46 struct v4l2_device v4l2_dev;
45 struct video_device vdev; 47 struct video_device vdev;
46 struct pardevice *pdev; 48 struct pardevice *pdev;
47 struct parport *pport; 49 struct parport *pport;
@@ -51,7 +53,6 @@ struct qcam_device {
51 int contrast, brightness, whitebal; 53 int contrast, brightness, whitebal;
52 int top, left; 54 int top, left;
53 unsigned int bidirectional; 55 unsigned int bidirectional;
54 unsigned long in_use;
55 struct mutex lock; 56 struct mutex lock;
56}; 57};
57 58
@@ -68,33 +69,45 @@ struct qcam_device {
68#define QC_DECIMATION_2 2 69#define QC_DECIMATION_2 2
69#define QC_DECIMATION_4 4 70#define QC_DECIMATION_4 4
70 71
71#define BANNER "Colour QuickCam for Video4Linux v0.05" 72#define BANNER "Colour QuickCam for Video4Linux v0.06"
72 73
73static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; 74static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
74static int probe = 2; 75static int probe = 2;
75static int force_rgb; 76static int force_rgb;
76static int video_nr = -1; 77static int video_nr = -1;
77 78
78static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) 79/* FIXME: parport=auto would never have worked, surely? --RR */
80MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n"
81 "probe=<0|1|2> for camera detection method\n"
82 "force_rgb=<0|1> for RGB data format (default BGR)");
83module_param_array(parport, int, NULL, 0);
84module_param(probe, int, 0);
85module_param(force_rgb, bool, 0);
86module_param(video_nr, int, 0);
87
88static struct qcam *qcams[MAX_CAMS];
89static unsigned int num_cams;
90
91static inline void qcam_set_ack(struct qcam *qcam, unsigned int i)
79{ 92{
80 /* note: the QC specs refer to the PCAck pin by voltage, not 93 /* note: the QC specs refer to the PCAck pin by voltage, not
81 software level. PC ports have builtin inverters. */ 94 software level. PC ports have builtin inverters. */
82 parport_frob_control(qcam->pport, 8, i ? 8 : 0); 95 parport_frob_control(qcam->pport, 8, i ? 8 : 0);
83} 96}
84 97
85static inline unsigned int qcam_ready1(struct qcam_device *qcam) 98static inline unsigned int qcam_ready1(struct qcam *qcam)
86{ 99{
87 return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0; 100 return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0;
88} 101}
89 102
90static inline unsigned int qcam_ready2(struct qcam_device *qcam) 103static inline unsigned int qcam_ready2(struct qcam *qcam)
91{ 104{
92 return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0; 105 return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0;
93} 106}
94 107
95static unsigned int qcam_await_ready1(struct qcam_device *qcam, 108static unsigned int qcam_await_ready1(struct qcam *qcam, int value)
96 int value)
97{ 109{
110 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
98 unsigned long oldjiffies = jiffies; 111 unsigned long oldjiffies = jiffies;
99 unsigned int i; 112 unsigned int i;
100 113
@@ -112,14 +125,15 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam,
112 } 125 }
113 126
114 /* Probably somebody pulled the plug out. Not much we can do. */ 127 /* Probably somebody pulled the plug out. Not much we can do. */
115 printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value, 128 v4l2_err(v4l2_dev, "ready1 timeout (%d) %x %x\n", value,
116 parport_read_status(qcam->pport), 129 parport_read_status(qcam->pport),
117 parport_read_control(qcam->pport)); 130 parport_read_control(qcam->pport));
118 return 1; 131 return 1;
119} 132}
120 133
121static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) 134static unsigned int qcam_await_ready2(struct qcam *qcam, int value)
122{ 135{
136 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
123 unsigned long oldjiffies = jiffies; 137 unsigned long oldjiffies = jiffies;
124 unsigned int i; 138 unsigned int i;
125 139
@@ -137,14 +151,14 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
137 } 151 }
138 152
139 /* Probably somebody pulled the plug out. Not much we can do. */ 153 /* Probably somebody pulled the plug out. Not much we can do. */
140 printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value, 154 v4l2_err(v4l2_dev, "ready2 timeout (%d) %x %x %x\n", value,
141 parport_read_status(qcam->pport), 155 parport_read_status(qcam->pport),
142 parport_read_control(qcam->pport), 156 parport_read_control(qcam->pport),
143 parport_read_data(qcam->pport)); 157 parport_read_data(qcam->pport));
144 return 1; 158 return 1;
145} 159}
146 160
147static int qcam_read_data(struct qcam_device *qcam) 161static int qcam_read_data(struct qcam *qcam)
148{ 162{
149 unsigned int idata; 163 unsigned int idata;
150 164
@@ -159,21 +173,22 @@ static int qcam_read_data(struct qcam_device *qcam)
159 return idata; 173 return idata;
160} 174}
161 175
162static int qcam_write_data(struct qcam_device *qcam, unsigned int data) 176static int qcam_write_data(struct qcam *qcam, unsigned int data)
163{ 177{
178 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
164 unsigned int idata; 179 unsigned int idata;
165 180
166 parport_write_data(qcam->pport, data); 181 parport_write_data(qcam->pport, data);
167 idata = qcam_read_data(qcam); 182 idata = qcam_read_data(qcam);
168 if (data != idata) { 183 if (data != idata) {
169 printk(KERN_WARNING "cqcam: sent %x but received %x\n", data, 184 v4l2_warn(v4l2_dev, "sent %x but received %x\n", data,
170 idata); 185 idata);
171 return 1; 186 return 1;
172 } 187 }
173 return 0; 188 return 0;
174} 189}
175 190
176static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data) 191static inline int qcam_set(struct qcam *qcam, unsigned int cmd, unsigned int data)
177{ 192{
178 if (qcam_write_data(qcam, cmd)) 193 if (qcam_write_data(qcam, cmd))
179 return -1; 194 return -1;
@@ -182,14 +197,14 @@ static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned
182 return 0; 197 return 0;
183} 198}
184 199
185static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd) 200static inline int qcam_get(struct qcam *qcam, unsigned int cmd)
186{ 201{
187 if (qcam_write_data(qcam, cmd)) 202 if (qcam_write_data(qcam, cmd))
188 return -1; 203 return -1;
189 return qcam_read_data(qcam); 204 return qcam_read_data(qcam);
190} 205}
191 206
192static int qc_detect(struct qcam_device *qcam) 207static int qc_detect(struct qcam *qcam)
193{ 208{
194 unsigned int stat, ostat, i, count = 0; 209 unsigned int stat, ostat, i, count = 0;
195 210
@@ -246,7 +261,7 @@ static int qc_detect(struct qcam_device *qcam)
246 return 0; 261 return 0;
247} 262}
248 263
249static void qc_reset(struct qcam_device *qcam) 264static void qc_reset(struct qcam *qcam)
250{ 265{
251 parport_write_control(qcam->pport, 0xc); 266 parport_write_control(qcam->pport, 0xc);
252 parport_write_control(qcam->pport, 0x8); 267 parport_write_control(qcam->pport, 0x8);
@@ -258,55 +273,55 @@ static void qc_reset(struct qcam_device *qcam)
258/* Reset the QuickCam and program for brightness, contrast, 273/* Reset the QuickCam and program for brightness, contrast,
259 * white-balance, and resolution. */ 274 * white-balance, and resolution. */
260 275
261static void qc_setup(struct qcam_device *q) 276static void qc_setup(struct qcam *qcam)
262{ 277{
263 qc_reset(q); 278 qc_reset(qcam);
264 279
265 /* Set the brightness. */ 280 /* Set the brightness. */
266 qcam_set(q, 11, q->brightness); 281 qcam_set(qcam, 11, qcam->brightness);
267 282
268 /* Set the height and width. These refer to the actual 283 /* Set the height and width. These refer to the actual
269 CCD area *before* applying the selected decimation. */ 284 CCD area *before* applying the selected decimation. */
270 qcam_set(q, 17, q->ccd_height); 285 qcam_set(qcam, 17, qcam->ccd_height);
271 qcam_set(q, 19, q->ccd_width / 2); 286 qcam_set(qcam, 19, qcam->ccd_width / 2);
272 287
273 /* Set top and left. */ 288 /* Set top and left. */
274 qcam_set(q, 0xd, q->top); 289 qcam_set(qcam, 0xd, qcam->top);
275 qcam_set(q, 0xf, q->left); 290 qcam_set(qcam, 0xf, qcam->left);
276 291
277 /* Set contrast and white balance. */ 292 /* Set contrast and white balance. */
278 qcam_set(q, 0x19, q->contrast); 293 qcam_set(qcam, 0x19, qcam->contrast);
279 qcam_set(q, 0x1f, q->whitebal); 294 qcam_set(qcam, 0x1f, qcam->whitebal);
280 295
281 /* Set the speed. */ 296 /* Set the speed. */
282 qcam_set(q, 45, 2); 297 qcam_set(qcam, 45, 2);
283} 298}
284 299
285/* Read some bytes from the camera and put them in the buffer. 300/* Read some bytes from the camera and put them in the buffer.
286 nbytes should be a multiple of 3, because bidirectional mode gives 301 nbytes should be a multiple of 3, because bidirectional mode gives
287 us three bytes at a time. */ 302 us three bytes at a time. */
288 303
289static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes) 304static unsigned int qcam_read_bytes(struct qcam *qcam, unsigned char *buf, unsigned int nbytes)
290{ 305{
291 unsigned int bytes = 0; 306 unsigned int bytes = 0;
292 307
293 qcam_set_ack(q, 0); 308 qcam_set_ack(qcam, 0);
294 if (q->bidirectional) { 309 if (qcam->bidirectional) {
295 /* It's a bidirectional port */ 310 /* It's a bidirectional port */
296 while (bytes < nbytes) { 311 while (bytes < nbytes) {
297 unsigned int lo1, hi1, lo2, hi2; 312 unsigned int lo1, hi1, lo2, hi2;
298 unsigned char r, g, b; 313 unsigned char r, g, b;
299 314
300 if (qcam_await_ready2(q, 1)) 315 if (qcam_await_ready2(qcam, 1))
301 return bytes; 316 return bytes;
302 lo1 = parport_read_data(q->pport) >> 1; 317 lo1 = parport_read_data(qcam->pport) >> 1;
303 hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; 318 hi1 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
304 qcam_set_ack(q, 1); 319 qcam_set_ack(qcam, 1);
305 if (qcam_await_ready2(q, 0)) 320 if (qcam_await_ready2(qcam, 0))
306 return bytes; 321 return bytes;
307 lo2 = parport_read_data(q->pport) >> 1; 322 lo2 = parport_read_data(qcam->pport) >> 1;
308 hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; 323 hi2 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
309 qcam_set_ack(q, 0); 324 qcam_set_ack(qcam, 0);
310 r = lo1 | ((hi1 & 1) << 7); 325 r = lo1 | ((hi1 & 1) << 7);
311 g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1); 326 g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1);
312 b = lo2 | ((hi2 & 1) << 7); 327 b = lo2 | ((hi2 & 1) << 7);
@@ -328,14 +343,14 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u
328 while (bytes < nbytes) { 343 while (bytes < nbytes) {
329 unsigned int hi, lo; 344 unsigned int hi, lo;
330 345
331 if (qcam_await_ready1(q, 1)) 346 if (qcam_await_ready1(qcam, 1))
332 return bytes; 347 return bytes;
333 hi = (parport_read_status(q->pport) & 0xf0); 348 hi = (parport_read_status(qcam->pport) & 0xf0);
334 qcam_set_ack(q, 1); 349 qcam_set_ack(qcam, 1);
335 if (qcam_await_ready1(q, 0)) 350 if (qcam_await_ready1(qcam, 0))
336 return bytes; 351 return bytes;
337 lo = (parport_read_status(q->pport) & 0xf0); 352 lo = (parport_read_status(qcam->pport) & 0xf0);
338 qcam_set_ack(q, 0); 353 qcam_set_ack(qcam, 0);
339 /* flip some bits */ 354 /* flip some bits */
340 rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88; 355 rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
341 if (i >= 2) { 356 if (i >= 2) {
@@ -361,10 +376,11 @@ get_fragment:
361 376
362#define BUFSZ 150 377#define BUFSZ 150
363 378
364static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len) 379static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len)
365{ 380{
381 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
366 unsigned lines, pixelsperline, bitsperxfer; 382 unsigned lines, pixelsperline, bitsperxfer;
367 unsigned int is_bi_dir = q->bidirectional; 383 unsigned int is_bi_dir = qcam->bidirectional;
368 size_t wantlen, outptr = 0; 384 size_t wantlen, outptr = 0;
369 char tmpbuf[BUFSZ]; 385 char tmpbuf[BUFSZ];
370 386
@@ -373,10 +389,10 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
373 389
374 /* Wait for camera to become ready */ 390 /* Wait for camera to become ready */
375 for (;;) { 391 for (;;) {
376 int i = qcam_get(q, 41); 392 int i = qcam_get(qcam, 41);
377 393
378 if (i == -1) { 394 if (i == -1) {
379 qc_setup(q); 395 qc_setup(qcam);
380 return -EIO; 396 return -EIO;
381 } 397 }
382 if ((i & 0x80) == 0) 398 if ((i & 0x80) == 0)
@@ -384,25 +400,25 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
384 schedule(); 400 schedule();
385 } 401 }
386 402
387 if (qcam_set(q, 7, (q->mode | (is_bi_dir ? 1 : 0)) + 1)) 403 if (qcam_set(qcam, 7, (qcam->mode | (is_bi_dir ? 1 : 0)) + 1))
388 return -EIO; 404 return -EIO;
389 405
390 lines = q->height; 406 lines = qcam->height;
391 pixelsperline = q->width; 407 pixelsperline = qcam->width;
392 bitsperxfer = (is_bi_dir) ? 24 : 8; 408 bitsperxfer = (is_bi_dir) ? 24 : 8;
393 409
394 if (is_bi_dir) { 410 if (is_bi_dir) {
395 /* Turn the port around */ 411 /* Turn the port around */
396 parport_data_reverse(q->pport); 412 parport_data_reverse(qcam->pport);
397 mdelay(3); 413 mdelay(3);
398 qcam_set_ack(q, 0); 414 qcam_set_ack(qcam, 0);
399 if (qcam_await_ready1(q, 1)) { 415 if (qcam_await_ready1(qcam, 1)) {
400 qc_setup(q); 416 qc_setup(qcam);
401 return -EIO; 417 return -EIO;
402 } 418 }
403 qcam_set_ack(q, 1); 419 qcam_set_ack(qcam, 1);
404 if (qcam_await_ready1(q, 0)) { 420 if (qcam_await_ready1(qcam, 0)) {
405 qc_setup(q); 421 qc_setup(qcam);
406 return -EIO; 422 return -EIO;
407 } 423 }
408 } 424 }
@@ -413,7 +429,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
413 size_t t, s; 429 size_t t, s;
414 430
415 s = (wantlen > BUFSZ) ? BUFSZ : wantlen; 431 s = (wantlen > BUFSZ) ? BUFSZ : wantlen;
416 t = qcam_read_bytes(q, tmpbuf, s); 432 t = qcam_read_bytes(qcam, tmpbuf, s);
417 if (outptr < len) { 433 if (outptr < len) {
418 size_t sz = len - outptr; 434 size_t sz = len - outptr;
419 435
@@ -432,10 +448,10 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
432 len = outptr; 448 len = outptr;
433 449
434 if (wantlen) { 450 if (wantlen) {
435 printk(KERN_ERR "qcam: short read.\n"); 451 v4l2_err(v4l2_dev, "short read.\n");
436 if (is_bi_dir) 452 if (is_bi_dir)
437 parport_data_forward(q->pport); 453 parport_data_forward(qcam->pport);
438 qc_setup(q); 454 qc_setup(qcam);
439 return len; 455 return len;
440 } 456 }
441 457
@@ -443,49 +459,49 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
443 int l; 459 int l;
444 460
445 do { 461 do {
446 l = qcam_read_bytes(q, tmpbuf, 3); 462 l = qcam_read_bytes(qcam, tmpbuf, 3);
447 cond_resched(); 463 cond_resched();
448 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e)); 464 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
449 if (force_rgb) { 465 if (force_rgb) {
450 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) 466 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
451 printk(KERN_ERR "qcam: bad EOF\n"); 467 v4l2_err(v4l2_dev, "bad EOF\n");
452 } else { 468 } else {
453 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) 469 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
454 printk(KERN_ERR "qcam: bad EOF\n"); 470 v4l2_err(v4l2_dev, "bad EOF\n");
455 } 471 }
456 qcam_set_ack(q, 0); 472 qcam_set_ack(qcam, 0);
457 if (qcam_await_ready1(q, 1)) { 473 if (qcam_await_ready1(qcam, 1)) {
458 printk(KERN_ERR "qcam: no ack after EOF\n"); 474 v4l2_err(v4l2_dev, "no ack after EOF\n");
459 parport_data_forward(q->pport); 475 parport_data_forward(qcam->pport);
460 qc_setup(q); 476 qc_setup(qcam);
461 return len; 477 return len;
462 } 478 }
463 parport_data_forward(q->pport); 479 parport_data_forward(qcam->pport);
464 mdelay(3); 480 mdelay(3);
465 qcam_set_ack(q, 1); 481 qcam_set_ack(qcam, 1);
466 if (qcam_await_ready1(q, 0)) { 482 if (qcam_await_ready1(qcam, 0)) {
467 printk(KERN_ERR "qcam: no ack to port turnaround\n"); 483 v4l2_err(v4l2_dev, "no ack to port turnaround\n");
468 qc_setup(q); 484 qc_setup(qcam);
469 return len; 485 return len;
470 } 486 }
471 } else { 487 } else {
472 int l; 488 int l;
473 489
474 do { 490 do {
475 l = qcam_read_bytes(q, tmpbuf, 1); 491 l = qcam_read_bytes(qcam, tmpbuf, 1);
476 cond_resched(); 492 cond_resched();
477 } while (l && tmpbuf[0] == 0x7e); 493 } while (l && tmpbuf[0] == 0x7e);
478 l = qcam_read_bytes(q, tmpbuf + 1, 2); 494 l = qcam_read_bytes(qcam, tmpbuf + 1, 2);
479 if (force_rgb) { 495 if (force_rgb) {
480 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) 496 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
481 printk(KERN_ERR "qcam: bad EOF\n"); 497 v4l2_err(v4l2_dev, "bad EOF\n");
482 } else { 498 } else {
483 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) 499 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
484 printk(KERN_ERR "qcam: bad EOF\n"); 500 v4l2_err(v4l2_dev, "bad EOF\n");
485 } 501 }
486 } 502 }
487 503
488 qcam_write_data(q, 0); 504 qcam_write_data(qcam, 0);
489 return len; 505 return len;
490} 506}
491 507
@@ -493,184 +509,202 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
493 * Video4linux interfacing 509 * Video4linux interfacing
494 */ 510 */
495 511
496static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) 512static int qcam_querycap(struct file *file, void *priv,
513 struct v4l2_capability *vcap)
497{ 514{
498 struct video_device *dev = video_devdata(file); 515 struct qcam *qcam = video_drvdata(file);
499 struct qcam_device *qcam = (struct qcam_device *)dev;
500 516
501 switch (cmd) { 517 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
502 case VIDIOCGCAP: 518 strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card));
503 { 519 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
504 struct video_capability *b = arg; 520 vcap->version = KERNEL_VERSION(0, 0, 3);
521 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
522 return 0;
523}
505 524
506 strcpy(b->name, "Quickcam"); 525static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
507 b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; 526{
508 b->channels = 1; 527 if (vin->index > 0)
509 b->audios = 0; 528 return -EINVAL;
510 b->maxwidth = 320; 529 strlcpy(vin->name, "Camera", sizeof(vin->name));
511 b->maxheight = 240; 530 vin->type = V4L2_INPUT_TYPE_CAMERA;
512 b->minwidth = 80; 531 vin->audioset = 0;
513 b->minheight = 60; 532 vin->tuner = 0;
514 return 0; 533 vin->std = 0;
515 } 534 vin->status = 0;
516 case VIDIOCGCHAN: 535 return 0;
517 { 536}
518 struct video_channel *v = arg;
519
520 if (v->channel != 0)
521 return -EINVAL;
522 v->flags = 0;
523 v->tuners = 0;
524 /* Good question.. its composite or SVHS so.. */
525 v->type = VIDEO_TYPE_CAMERA;
526 strcpy(v->name, "Camera");
527 return 0;
528 }
529 case VIDIOCSCHAN:
530 {
531 struct video_channel *v = arg;
532 537
533 if (v->channel != 0) 538static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
534 return -EINVAL; 539{
535 return 0; 540 *inp = 0;
536 } 541 return 0;
537 case VIDIOCGTUNER: 542}
538 { 543
539 struct video_tuner *v = arg; 544static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
540 545{
541 if (v->tuner) 546 return (inp > 0) ? -EINVAL : 0;
542 return -EINVAL; 547}
543 memset(v, 0, sizeof(*v)); 548
544 strcpy(v->name, "Format"); 549static int qcam_queryctrl(struct file *file, void *priv,
545 v->mode = VIDEO_MODE_AUTO; 550 struct v4l2_queryctrl *qc)
546 return 0; 551{
552 switch (qc->id) {
553 case V4L2_CID_BRIGHTNESS:
554 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 240);
555 case V4L2_CID_CONTRAST:
556 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
557 case V4L2_CID_GAMMA:
558 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
547 } 559 }
548 case VIDIOCSTUNER: 560 return -EINVAL;
549 { 561}
550 struct video_tuner *v = arg; 562
551 563static int qcam_g_ctrl(struct file *file, void *priv,
552 if (v->tuner) 564 struct v4l2_control *ctrl)
553 return -EINVAL; 565{
554 if (v->mode != VIDEO_MODE_AUTO) 566 struct qcam *qcam = video_drvdata(file);
555 return -EINVAL; 567 int ret = 0;
556 return 0; 568
569 switch (ctrl->id) {
570 case V4L2_CID_BRIGHTNESS:
571 ctrl->value = qcam->brightness;
572 break;
573 case V4L2_CID_CONTRAST:
574 ctrl->value = qcam->contrast;
575 break;
576 case V4L2_CID_GAMMA:
577 ctrl->value = qcam->whitebal;
578 break;
579 default:
580 ret = -EINVAL;
581 break;
557 } 582 }
558 case VIDIOCGPICT: 583 return ret;
559 { 584}
560 struct video_picture *p = arg; 585
561 586static int qcam_s_ctrl(struct file *file, void *priv,
562 p->colour = 0x8000; 587 struct v4l2_control *ctrl)
563 p->hue = 0x8000; 588{
564 p->brightness = qcam->brightness << 8; 589 struct qcam *qcam = video_drvdata(file);
565 p->contrast = qcam->contrast << 8; 590 int ret = 0;
566 p->whiteness = qcam->whitebal << 8; 591
567 p->depth = 24; 592 mutex_lock(&qcam->lock);
568 p->palette = VIDEO_PALETTE_RGB24; 593 switch (ctrl->id) {
569 return 0; 594 case V4L2_CID_BRIGHTNESS:
595 qcam->brightness = ctrl->value;
596 break;
597 case V4L2_CID_CONTRAST:
598 qcam->contrast = ctrl->value;
599 break;
600 case V4L2_CID_GAMMA:
601 qcam->whitebal = ctrl->value;
602 break;
603 default:
604 ret = -EINVAL;
605 break;
570 } 606 }
571 case VIDIOCSPICT: 607 if (ret == 0) {
572 {
573 struct video_picture *p = arg;
574
575 /*
576 * Sanity check args
577 */
578 if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
579 return -EINVAL;
580
581 /*
582 * Now load the camera.
583 */
584 qcam->brightness = p->brightness >> 8;
585 qcam->contrast = p->contrast >> 8;
586 qcam->whitebal = p->whiteness >> 8;
587
588 mutex_lock(&qcam->lock);
589 parport_claim_or_block(qcam->pdev); 608 parport_claim_or_block(qcam->pdev);
590 qc_setup(qcam); 609 qc_setup(qcam);
591 parport_release(qcam->pdev); 610 parport_release(qcam->pdev);
592 mutex_unlock(&qcam->lock);
593 return 0;
594 } 611 }
595 case VIDIOCSWIN: 612 mutex_unlock(&qcam->lock);
596 { 613 return ret;
597 struct video_window *vw = arg; 614}
598
599 if (vw->flags)
600 return -EINVAL;
601 if (vw->clipcount)
602 return -EINVAL;
603 if (vw->height < 60 || vw->height > 240)
604 return -EINVAL;
605 if (vw->width < 80 || vw->width > 320)
606 return -EINVAL;
607
608 qcam->width = 80;
609 qcam->height = 60;
610 qcam->mode = QC_DECIMATION_4;
611 615
612 if (vw->width >= 160 && vw->height >= 120) { 616static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
613 qcam->width = 160; 617{
614 qcam->height = 120; 618 struct qcam *qcam = video_drvdata(file);
615 qcam->mode = QC_DECIMATION_2; 619 struct v4l2_pix_format *pix = &fmt->fmt.pix;
616 } 620
617 if (vw->width >= 320 && vw->height >= 240) { 621 pix->width = qcam->width;
618 qcam->width = 320; 622 pix->height = qcam->height;
619 qcam->height = 240; 623 pix->pixelformat = V4L2_PIX_FMT_RGB24;
620 qcam->mode = QC_DECIMATION_1; 624 pix->field = V4L2_FIELD_NONE;
621 } 625 pix->bytesperline = 3 * qcam->width;
622 qcam->mode |= QC_MILLIONS; 626 pix->sizeimage = 3 * qcam->width * qcam->height;
623#if 0 627 /* Just a guess */
624 if (vw->width >= 640 && vw->height >= 480) { 628 pix->colorspace = V4L2_COLORSPACE_SRGB;
625 qcam->width = 640; 629 return 0;
626 qcam->height = 480; 630}
627 qcam->mode = QC_BILLIONS | QC_DECIMATION_1; 631
628 } 632static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
629#endif 633{
630 /* Ok we figured out what to use from our 634 struct v4l2_pix_format *pix = &fmt->fmt.pix;
631 wide choice */ 635
632 mutex_lock(&qcam->lock); 636 if (pix->height < 60 || pix->width < 80) {
633 parport_claim_or_block(qcam->pdev); 637 pix->height = 60;
634 qc_setup(qcam); 638 pix->width = 80;
635 parport_release(qcam->pdev); 639 } else if (pix->height < 120 || pix->width < 160) {
636 mutex_unlock(&qcam->lock); 640 pix->height = 120;
637 return 0; 641 pix->width = 160;
638 } 642 } else {
639 case VIDIOCGWIN: 643 pix->height = 240;
640 { 644 pix->width = 320;
641 struct video_window *vw = arg;
642 memset(vw, 0, sizeof(*vw));
643 vw->width = qcam->width;
644 vw->height = qcam->height;
645 return 0;
646 } 645 }
647 case VIDIOCKEY: 646 pix->pixelformat = V4L2_PIX_FMT_RGB24;
648 return 0; 647 pix->field = V4L2_FIELD_NONE;
649 case VIDIOCCAPTURE: 648 pix->bytesperline = 3 * pix->width;
650 case VIDIOCGFBUF: 649 pix->sizeimage = 3 * pix->width * pix->height;
651 case VIDIOCSFBUF: 650 /* Just a guess */
652 case VIDIOCGFREQ: 651 pix->colorspace = V4L2_COLORSPACE_SRGB;
653 case VIDIOCSFREQ: 652 return 0;
654 case VIDIOCGAUDIO: 653}
655 case VIDIOCSAUDIO: 654
656 return -EINVAL; 655static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
656{
657 struct qcam *qcam = video_drvdata(file);
658 struct v4l2_pix_format *pix = &fmt->fmt.pix;
659 int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
660
661 if (ret)
662 return ret;
663 switch (pix->height) {
664 case 60:
665 qcam->mode = QC_DECIMATION_4;
666 break;
667 case 120:
668 qcam->mode = QC_DECIMATION_2;
669 break;
657 default: 670 default:
658 return -ENOIOCTLCMD; 671 qcam->mode = QC_DECIMATION_1;
672 break;
659 } 673 }
674
675 mutex_lock(&qcam->lock);
676 qcam->mode |= QC_MILLIONS;
677 qcam->height = pix->height;
678 qcam->width = pix->width;
679 parport_claim_or_block(qcam->pdev);
680 qc_setup(qcam);
681 parport_release(qcam->pdev);
682 mutex_unlock(&qcam->lock);
660 return 0; 683 return 0;
661} 684}
662 685
663static long qcam_ioctl(struct file *file, 686static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
664 unsigned int cmd, unsigned long arg)
665{ 687{
666 return video_usercopy(file, cmd, arg, qcam_do_ioctl); 688 static struct v4l2_fmtdesc formats[] = {
689 { 0, 0, 0,
690 "RGB 8:8:8", V4L2_PIX_FMT_RGB24,
691 { 0, 0, 0, 0 }
692 },
693 };
694 enum v4l2_buf_type type = fmt->type;
695
696 if (fmt->index > 0)
697 return -EINVAL;
698
699 *fmt = formats[fmt->index];
700 fmt->type = type;
701 return 0;
667} 702}
668 703
669static ssize_t qcam_read(struct file *file, char __user *buf, 704static ssize_t qcam_read(struct file *file, char __user *buf,
670 size_t count, loff_t *ppos) 705 size_t count, loff_t *ppos)
671{ 706{
672 struct video_device *v = video_devdata(file); 707 struct qcam *qcam = video_drvdata(file);
673 struct qcam_device *qcam = (struct qcam_device *)v;
674 int len; 708 int len;
675 709
676 mutex_lock(&qcam->lock); 710 mutex_lock(&qcam->lock);
@@ -682,81 +716,80 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
682 return len; 716 return len;
683} 717}
684 718
685static int qcam_exclusive_open(struct file *file)
686{
687 struct video_device *dev = video_devdata(file);
688 struct qcam_device *qcam = (struct qcam_device *)dev;
689
690 return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0;
691}
692
693static int qcam_exclusive_release(struct file *file)
694{
695 struct video_device *dev = video_devdata(file);
696 struct qcam_device *qcam = (struct qcam_device *)dev;
697
698 clear_bit(0, &qcam->in_use);
699 return 0;
700}
701
702/* video device template */
703static const struct v4l2_file_operations qcam_fops = { 719static const struct v4l2_file_operations qcam_fops = {
704 .owner = THIS_MODULE, 720 .owner = THIS_MODULE,
705 .open = qcam_exclusive_open, 721 .ioctl = video_ioctl2,
706 .release = qcam_exclusive_release,
707 .ioctl = qcam_ioctl,
708 .read = qcam_read, 722 .read = qcam_read,
709}; 723};
710 724
711static struct video_device qcam_template = { 725static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
712 .name = "Colour QuickCam", 726 .vidioc_querycap = qcam_querycap,
713 .fops = &qcam_fops, 727 .vidioc_g_input = qcam_g_input,
714 .release = video_device_release_empty, 728 .vidioc_s_input = qcam_s_input,
729 .vidioc_enum_input = qcam_enum_input,
730 .vidioc_queryctrl = qcam_queryctrl,
731 .vidioc_g_ctrl = qcam_g_ctrl,
732 .vidioc_s_ctrl = qcam_s_ctrl,
733 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
734 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
735 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
736 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
715}; 737};
716 738
717/* Initialize the QuickCam driver control structure. */ 739/* Initialize the QuickCam driver control structure. */
718 740
719static struct qcam_device *qcam_init(struct parport *port) 741static struct qcam *qcam_init(struct parport *port)
720{ 742{
721 struct qcam_device *q; 743 struct qcam *qcam;
744 struct v4l2_device *v4l2_dev;
722 745
723 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); 746 qcam = kzalloc(sizeof(*qcam), GFP_KERNEL);
724 if (q == NULL) 747 if (qcam == NULL)
725 return NULL; 748 return NULL;
726 749
727 q->pport = port; 750 v4l2_dev = &qcam->v4l2_dev;
728 q->pdev = parport_register_device(port, "c-qcam", NULL, NULL, 751 strlcpy(v4l2_dev->name, "c-qcam", sizeof(v4l2_dev->name));
752
753 if (v4l2_device_register(NULL, v4l2_dev) < 0) {
754 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
755 return NULL;
756 }
757
758 qcam->pport = port;
759 qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
729 NULL, 0, NULL); 760 NULL, 0, NULL);
730 761
731 q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0; 762 qcam->bidirectional = (qcam->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0;
732 763
733 if (q->pdev == NULL) { 764 if (qcam->pdev == NULL) {
734 printk(KERN_ERR "c-qcam: couldn't register for %s.\n", 765 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
735 port->name); 766 kfree(qcam);
736 kfree(q);
737 return NULL; 767 return NULL;
738 } 768 }
739 769
740 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); 770 strlcpy(qcam->vdev.name, "Colour QuickCam", sizeof(qcam->vdev.name));
741 771 qcam->vdev.v4l2_dev = v4l2_dev;
742 mutex_init(&q->lock); 772 qcam->vdev.fops = &qcam_fops;
743 q->width = q->ccd_width = 320; 773 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
744 q->height = q->ccd_height = 240; 774 qcam->vdev.release = video_device_release_empty;
745 q->mode = QC_MILLIONS | QC_DECIMATION_1; 775 video_set_drvdata(&qcam->vdev, qcam);
746 q->contrast = 192; 776
747 q->brightness = 240; 777 mutex_init(&qcam->lock);
748 q->whitebal = 128; 778 qcam->width = qcam->ccd_width = 320;
749 q->top = 1; 779 qcam->height = qcam->ccd_height = 240;
750 q->left = 14; 780 qcam->mode = QC_MILLIONS | QC_DECIMATION_1;
751 return q; 781 qcam->contrast = 192;
782 qcam->brightness = 240;
783 qcam->whitebal = 128;
784 qcam->top = 1;
785 qcam->left = 14;
786 return qcam;
752} 787}
753 788
754static struct qcam_device *qcams[MAX_CAMS];
755static unsigned int num_cams;
756
757static int init_cqcam(struct parport *port) 789static int init_cqcam(struct parport *port)
758{ 790{
759 struct qcam_device *qcam; 791 struct qcam *qcam;
792 struct v4l2_device *v4l2_dev;
760 793
761 if (parport[0] != -1) { 794 if (parport[0] != -1) {
762 /* The user gave specific instructions */ 795 /* The user gave specific instructions */
@@ -777,6 +810,8 @@ static int init_cqcam(struct parport *port)
777 if (qcam == NULL) 810 if (qcam == NULL)
778 return -ENODEV; 811 return -ENODEV;
779 812
813 v4l2_dev = &qcam->v4l2_dev;
814
780 parport_claim_or_block(qcam->pdev); 815 parport_claim_or_block(qcam->pdev);
781 816
782 qc_reset(qcam); 817 qc_reset(qcam);
@@ -793,14 +828,14 @@ static int init_cqcam(struct parport *port)
793 parport_release(qcam->pdev); 828 parport_release(qcam->pdev);
794 829
795 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { 830 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
796 printk(KERN_ERR "Unable to register Colour QuickCam on %s\n", 831 v4l2_err(v4l2_dev, "Unable to register Colour QuickCam on %s\n",
797 qcam->pport->name); 832 qcam->pport->name);
798 parport_unregister_device(qcam->pdev); 833 parport_unregister_device(qcam->pdev);
799 kfree(qcam); 834 kfree(qcam);
800 return -ENODEV; 835 return -ENODEV;
801 } 836 }
802 837
803 printk(KERN_INFO "%s: Colour QuickCam found on %s\n", 838 v4l2_info(v4l2_dev, "%s: Colour QuickCam found on %s\n",
804 video_device_node_name(&qcam->vdev), qcam->pport->name); 839 video_device_node_name(&qcam->vdev), qcam->pport->name);
805 840
806 qcams[num_cams++] = qcam; 841 qcams[num_cams++] = qcam;
@@ -808,7 +843,7 @@ static int init_cqcam(struct parport *port)
808 return 0; 843 return 0;
809} 844}
810 845
811static void close_cqcam(struct qcam_device *qcam) 846static void close_cqcam(struct qcam *qcam)
812{ 847{
813 video_unregister_device(&qcam->vdev); 848 video_unregister_device(&qcam->vdev);
814 parport_unregister_device(qcam->pdev); 849 parport_unregister_device(qcam->pdev);
@@ -833,7 +868,7 @@ static struct parport_driver cqcam_driver = {
833 868
834static int __init cqcam_init(void) 869static int __init cqcam_init(void)
835{ 870{
836 printk(BANNER "\n"); 871 printk(KERN_INFO BANNER "\n");
837 872
838 return parport_register_driver(&cqcam_driver); 873 return parport_register_driver(&cqcam_driver);
839} 874}
@@ -852,14 +887,5 @@ MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
852MODULE_DESCRIPTION(BANNER); 887MODULE_DESCRIPTION(BANNER);
853MODULE_LICENSE("GPL"); 888MODULE_LICENSE("GPL");
854 889
855/* FIXME: parport=auto would never have worked, surely? --RR */
856MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n"
857 "probe=<0|1|2> for camera detection method\n"
858 "force_rgb=<0|1> for RGB data format (default BGR)");
859module_param_array(parport, int, NULL, 0);
860module_param(probe, int, 0);
861module_param(force_rgb, bool, 0);
862module_param(video_nr, int, 0);
863
864module_init(cqcam_init); 890module_init(cqcam_init);
865module_exit(cqcam_cleanup); 891module_exit(cqcam_cleanup);
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
index b5d7cbf4528a..d50d69da387b 100644
--- a/drivers/media/video/cx18/cx18-alsa-main.c
+++ b/drivers/media/video/cx18/cx18-alsa-main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA interface to cx18 PCM capture streams 2 * ALSA interface to cx18 PCM capture streams
3 * 3 *
4 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 4 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
5 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> 5 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
6 * 6 *
7 * Portions of this work were sponsored by ONELAN Limited. 7 * Portions of this work were sponsored by ONELAN Limited.
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/video/cx18/cx18-alsa-mixer.c
index ef21114309fe..341bddc00b77 100644
--- a/drivers/media/video/cx18/cx18-alsa-mixer.c
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.c
@@ -2,7 +2,7 @@
2 * ALSA mixer controls for the 2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams 3 * ALSA interface to cx18 PCM capture streams
4 * 4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/video/cx18/cx18-alsa-mixer.h
index 2d418db000fe..ec9238793f6f 100644
--- a/drivers/media/video/cx18/cx18-alsa-mixer.h
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.h
@@ -2,7 +2,7 @@
2 * ALSA mixer controls for the 2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams 3 * ALSA interface to cx18 PCM capture streams
4 * 4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c
index 2bd312daeb1e..8f55692db36d 100644
--- a/drivers/media/video/cx18/cx18-alsa-pcm.c
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.c
@@ -2,7 +2,7 @@
2 * ALSA PCM device for the 2 * ALSA PCM device for the
3 * ALSA interface to cx18 PCM capture streams 3 * ALSA interface to cx18 PCM capture streams
4 * 4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
6 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> 6 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 * 7 *
8 * Portions of this work were sponsored by ONELAN Limited. 8 * Portions of this work were sponsored by ONELAN Limited.
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/video/cx18/cx18-alsa-pcm.h
index 325662c647a0..d26e51f94577 100644
--- a/drivers/media/video/cx18/cx18-alsa-pcm.h
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.h
@@ -2,7 +2,7 @@
2 * ALSA PCM device for the 2 * ALSA PCM device for the
3 * ALSA interface to cx18 PCM capture streams 3 * ALSA interface to cx18 PCM capture streams
4 * 4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h
index 88a1cde7540b..447da374c9e8 100644
--- a/drivers/media/video/cx18/cx18-alsa.h
+++ b/drivers/media/video/cx18/cx18-alsa.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA interface to cx18 PCM capture streams 2 * ALSA interface to cx18 PCM capture streams
3 * 3 *
4 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 4 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index 9e30983f2ff6..43d09a24b262 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -4,7 +4,7 @@
4 * Derived from cx25840-audio.c 4 * Derived from cx25840-audio.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 0e5006b14279..a41951cab276 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -4,7 +4,7 @@
4 * Derived from cx25840-core.c 4 * Derived from cx25840-core.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -1021,86 +1021,74 @@ static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1021 return -EINVAL; 1021 return -EINVAL;
1022} 1022}
1023 1023
1024static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 1024static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
1025{
1026 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1027 return -EINVAL;
1028 return cx18_av_g_sliced_fmt(sd, &fmt->fmt.sliced);
1029}
1030
1031static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1032{ 1025{
1033 struct cx18_av_state *state = to_cx18_av_state(sd); 1026 struct cx18_av_state *state = to_cx18_av_state(sd);
1034 struct cx18 *cx = v4l2_get_subdevdata(sd); 1027 struct cx18 *cx = v4l2_get_subdevdata(sd);
1035
1036 struct v4l2_pix_format *pix;
1037 int HSC, VSC, Vsrc, Hsrc, filter, Vlines; 1028 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
1038 int is_50Hz = !(state->std & V4L2_STD_525_60); 1029 int is_50Hz = !(state->std & V4L2_STD_525_60);
1039 1030
1040 switch (fmt->type) { 1031 if (fmt->code != V4L2_MBUS_FMT_FIXED)
1041 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1032 return -EINVAL;
1042 pix = &(fmt->fmt.pix);
1043 1033
1044 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4; 1034 fmt->field = V4L2_FIELD_INTERLACED;
1045 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4; 1035 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1046 1036
1047 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4; 1037 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
1048 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4; 1038 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
1049 1039
1050 /* 1040 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
1051 * This adjustment reflects the excess of vactive, set in 1041 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
1052 * cx18_av_std_setup(), above standard values:
1053 *
1054 * 480 + 1 for 60 Hz systems
1055 * 576 + 3 for 50 Hz systems
1056 */
1057 Vlines = pix->height + (is_50Hz ? 3 : 1);
1058
1059 /*
1060 * Invalid height and width scaling requests are:
1061 * 1. width less than 1/16 of the source width
1062 * 2. width greater than the source width
1063 * 3. height less than 1/8 of the source height
1064 * 4. height greater than the source height
1065 */
1066 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
1067 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
1068 CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
1069 pix->width, pix->height);
1070 return -ERANGE;
1071 }
1072 1042
1073 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); 1043 /*
1074 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); 1044 * This adjustment reflects the excess of vactive, set in
1075 VSC &= 0x1fff; 1045 * cx18_av_std_setup(), above standard values:
1046 *
1047 * 480 + 1 for 60 Hz systems
1048 * 576 + 3 for 50 Hz systems
1049 */
1050 Vlines = fmt->height + (is_50Hz ? 3 : 1);
1076 1051
1077 if (pix->width >= 385) 1052 /*
1078 filter = 0; 1053 * Invalid height and width scaling requests are:
1079 else if (pix->width > 192) 1054 * 1. width less than 1/16 of the source width
1080 filter = 1; 1055 * 2. width greater than the source width
1081 else if (pix->width > 96) 1056 * 3. height less than 1/8 of the source height
1082 filter = 2; 1057 * 4. height greater than the source height
1083 else 1058 */
1084 filter = 3; 1059 if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
1060 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
1061 CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
1062 fmt->width, fmt->height);
1063 return -ERANGE;
1064 }
1085 1065
1086 CX18_DEBUG_INFO_DEV(sd, 1066 HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
1087 "decoder set size %dx%d -> scale %ux%u\n", 1067 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
1088 pix->width, pix->height, HSC, VSC); 1068 VSC &= 0x1fff;
1089
1090 /* HSCALE=HSC */
1091 cx18_av_write(cx, 0x418, HSC & 0xff);
1092 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
1093 cx18_av_write(cx, 0x41a, HSC >> 16);
1094 /* VSCALE=VSC */
1095 cx18_av_write(cx, 0x41c, VSC & 0xff);
1096 cx18_av_write(cx, 0x41d, VSC >> 8);
1097 /* VS_INTRLACE=1 VFILT=filter */
1098 cx18_av_write(cx, 0x41e, 0x8 | filter);
1099 break;
1100 1069
1101 default: 1070 if (fmt->width >= 385)
1102 return -EINVAL; 1071 filter = 0;
1103 } 1072 else if (fmt->width > 192)
1073 filter = 1;
1074 else if (fmt->width > 96)
1075 filter = 2;
1076 else
1077 filter = 3;
1078
1079 CX18_DEBUG_INFO_DEV(sd,
1080 "decoder set size %dx%d -> scale %ux%u\n",
1081 fmt->width, fmt->height, HSC, VSC);
1082
1083 /* HSCALE=HSC */
1084 cx18_av_write(cx, 0x418, HSC & 0xff);
1085 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
1086 cx18_av_write(cx, 0x41a, HSC >> 16);
1087 /* VSCALE=VSC */
1088 cx18_av_write(cx, 0x41c, VSC & 0xff);
1089 cx18_av_write(cx, 0x41d, VSC >> 8);
1090 /* VS_INTRLACE=1 VFILT=filter */
1091 cx18_av_write(cx, 0x41e, 0x8 | filter);
1104 return 0; 1092 return 0;
1105} 1093}
1106 1094
@@ -1398,8 +1386,7 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
1398static const struct v4l2_subdev_video_ops cx18_av_video_ops = { 1386static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
1399 .s_routing = cx18_av_s_video_routing, 1387 .s_routing = cx18_av_s_video_routing,
1400 .s_stream = cx18_av_s_stream, 1388 .s_stream = cx18_av_s_stream,
1401 .g_fmt = cx18_av_g_fmt, 1389 .s_mbus_fmt = cx18_av_s_mbus_fmt,
1402 .s_fmt = cx18_av_s_fmt,
1403}; 1390};
1404 1391
1405static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = { 1392static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = {
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index c106967bdcc3..1956991795e3 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -4,7 +4,7 @@
4 * Derived from cx25840-core.h 4 * Derived from cx25840-core.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index b9e8cc5d264a..280aa4d22488 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -2,7 +2,7 @@
2 * cx18 ADEC firmware functions 2 * cx18 ADEC firmware functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 74e122b5fc49..6b805afe5d20 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -4,7 +4,7 @@
4 * Derived from ivtv-cards.c 4 * Derived from ivtv-cards.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 796e517300ac..3e750068f275 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -4,7 +4,7 @@
4 * Derived from ivtv-cards.c 4 * Derived from ivtv-cards.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 4b4b46544d5a..67043c7b452b 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -297,14 +297,13 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
297 if (p.video_encoding != cx->params.video_encoding) { 297 if (p.video_encoding != cx->params.video_encoding) {
298 int is_mpeg1 = p.video_encoding == 298 int is_mpeg1 = p.video_encoding ==
299 V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 299 V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
300 struct v4l2_format fmt; 300 struct v4l2_mbus_framefmt fmt;
301 301
302 /* fix videodecoder resolution */ 302 /* fix videodecoder resolution */
303 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 303 fmt.width = cx->params.width / (is_mpeg1 ? 2 : 1);
304 fmt.fmt.pix.width = cx->params.width 304 fmt.height = cx->params.height;
305 / (is_mpeg1 ? 2 : 1); 305 fmt.code = V4L2_MBUS_FMT_FIXED;
306 fmt.fmt.pix.height = cx->params.height; 306 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
307 v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt);
308 } 307 }
309 priv.cx = cx; 308 priv.cx = cx;
310 priv.s = &cx->streams[id->type]; 309 priv.s = &cx->streams[id->type];
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index c95a86ba33b0..df60f27337cf 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -4,7 +4,7 @@
4 * Derived from ivtv-driver.c 4 * Derived from ivtv-driver.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index b9728e8eee40..9bc51a99376b 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -4,7 +4,7 @@
4 * Derived from ivtv-driver.h 4 * Derived from ivtv-driver.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 0ae2c2e1eab5..6d19f040d70f 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -2,7 +2,7 @@
2 * cx18 functions for DVB support 2 * cx18 functions for DVB support
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index e12a15020cda..9f23b90732f2 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -4,7 +4,7 @@
4 * Derived from ivtv-fileops.c 4 * Derived from ivtv-fileops.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 83cd559cc609..1b3fb502e6be 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -2,7 +2,7 @@
2 * cx18 firmware functions 2 * cx18 firmware functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 86a204b5448e..5374aeb0cd22 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -4,7 +4,7 @@
4 * Derived from ivtv-gpio.c 4 * Derived from ivtv-gpio.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
index f9a5ca3566af..4aea2ef88e8d 100644
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -4,7 +4,7 @@
4 * Derived from ivtv-gpio.h 4 * Derived from ivtv-gpio.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index cfa1f289b0f5..809f7d37129c 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -4,7 +4,7 @@
4 * Derived from ivtv-i2c.c 4 * Derived from ivtv-i2c.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
index ec5b3d7bcc6b..49b9dbd06248 100644
--- a/drivers/media/video/cx18/cx18-io.c
+++ b/drivers/media/video/cx18/cx18-io.c
@@ -2,7 +2,7 @@
2 * cx18 driver PCI memory mapped IO access routines 2 * cx18 driver PCI memory mapped IO access routines
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
index 2635b3a8cc96..18974d886cf7 100644
--- a/drivers/media/video/cx18/cx18-io.h
+++ b/drivers/media/video/cx18/cx18-io.h
@@ -2,7 +2,7 @@
2 * cx18 driver PCI memory mapped IO access routines 2 * cx18 driver PCI memory mapped IO access routines
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
28/* 28/*
29 * Readback and retry of MMIO access for reliability: 29 * Readback and retry of MMIO access for reliability:
30 * The concept was suggested by Steve Toth <stoth@linuxtv.org>. 30 * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
31 * The implmentation is the fault of Andy Walls <awalls@radix.net>. 31 * The implmentation is the fault of Andy Walls <awalls@md.metrocast.net>.
32 * 32 *
33 * *write* functions are implied to retry the mmio unless suffixed with _noretry 33 * *write* functions are implied to retry the mmio unless suffixed with _noretry
34 * *read* functions never retry the mmio (it never helps to do so) 34 * *read* functions never retry the mmio (it never helps to do so)
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 2530fc54daaf..20eaf38ba959 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -4,7 +4,7 @@
4 * Derived from ivtv-ioctl.c 4 * Derived from ivtv-ioctl.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
@@ -274,6 +274,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
274{ 274{
275 struct cx18_open_id *id = fh; 275 struct cx18_open_id *id = fh;
276 struct cx18 *cx = id->cx; 276 struct cx18 *cx = id->cx;
277 struct v4l2_mbus_framefmt mbus_fmt;
277 int ret; 278 int ret;
278 int w, h; 279 int w, h;
279 280
@@ -293,9 +294,10 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
293 if (atomic_read(&cx->ana_capturing) > 0) 294 if (atomic_read(&cx->ana_capturing) > 0)
294 return -EBUSY; 295 return -EBUSY;
295 296
296 cx->params.width = w; 297 mbus_fmt.width = cx->params.width = w;
297 cx->params.height = h; 298 mbus_fmt.height = cx->params.height = h;
298 v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); 299 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
300 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
299 return cx18_g_fmt_vid_cap(file, fh, fmt); 301 return cx18_g_fmt_vid_cap(file, fh, fmt);
300} 302}
301 303
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h
index e2ca0d152116..dcb2559ad520 100644
--- a/drivers/media/video/cx18/cx18-ioctl.h
+++ b/drivers/media/video/cx18/cx18-ioctl.h
@@ -4,7 +4,7 @@
4 * Derived from ivtv-ioctl.h 4 * Derived from ivtv-ioctl.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
index af2f504eda2b..80edfe93a3d8 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -2,7 +2,7 @@
2 * cx18 interrupt handling 2 * cx18 interrupt handling
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h
index 91f0b5278ef9..30e7eaf8cb55 100644
--- a/drivers/media/video/cx18/cx18-irq.h
+++ b/drivers/media/video/cx18/cx18-irq.h
@@ -2,7 +2,7 @@
2 * cx18 interrupt handling 2 * cx18 interrupt handling
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 6dcce297752f..956aa190ecca 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -2,7 +2,7 @@
2 * cx18 mailbox functions 2 * cx18 mailbox functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index 33a3491c4537..077952fcbcca 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -2,7 +2,7 @@
2 * cx18 mailbox functions 2 * cx18 mailbox functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index aefc8c8cf3c1..8884537bd62f 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -4,7 +4,7 @@
4 * Derived from ivtv-queue.c 4 * Derived from ivtv-queue.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 88a6d34ad3bb..4201ddc16091 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -4,7 +4,7 @@
4 * Derived from ivtv-queue.h 4 * Derived from ivtv-queue.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c
index 34b4d03c55cd..85cc59637e54 100644
--- a/drivers/media/video/cx18/cx18-scb.c
+++ b/drivers/media/video/cx18/cx18-scb.c
@@ -2,7 +2,7 @@
2 * cx18 System Control Block initialization 2 * cx18 System Control Block initialization
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
index 368f23d08709..08877652e321 100644
--- a/drivers/media/video/cx18/cx18-scb.h
+++ b/drivers/media/video/cx18/cx18-scb.h
@@ -2,7 +2,7 @@
2 * cx18 System Control Block initialization 2 * cx18 System Control Block initialization
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 5 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index f5c91261b2db..9045f1ece0eb 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -4,7 +4,7 @@
4 * Derived from ivtv-streams.c 4 * Derived from ivtv-streams.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 0bff0fa29763..77412bee5963 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -4,7 +4,7 @@
4 * Derived from ivtv-streams.h 4 * Derived from ivtv-streams.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net> 7 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 10 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 2782709b263f..e76014561aa7 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -993,6 +993,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
993 struct cx231xx *dev = fh->dev; 993 struct cx231xx *dev = fh->dev;
994 int rc; 994 int rc;
995 struct cx231xx_fmt *fmt; 995 struct cx231xx_fmt *fmt;
996 struct v4l2_mbus_framefmt mbus_fmt;
996 997
997 rc = check_dev(dev); 998 rc = check_dev(dev);
998 if (rc < 0) 999 if (rc < 0)
@@ -1026,7 +1027,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1026 dev->format = fmt; 1027 dev->format = fmt;
1027 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); 1028 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
1028 1029
1029 call_all(dev, video, s_fmt, f); 1030 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
1031 call_all(dev, video, s_mbus_fmt, &mbus_fmt);
1032 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
1030 1033
1031 /* Set the correct alternate setting for this resolution */ 1034 /* Set the correct alternate setting for this resolution */
1032 cx231xx_resolution_set(dev); 1035 cx231xx_resolution_set(dev);
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index 022b480918cd..2bf44ef10fec 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -1113,7 +1113,6 @@ invalid:
1113void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) 1113void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
1114{ 1114{
1115 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 1115 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
1116 int temporal = p->video_temporal_filter;
1117 1116
1118 /* Stream */ 1117 /* Stream */
1119 printk(KERN_INFO "%s: Stream: %s", 1118 printk(KERN_INFO "%s: Stream: %s",
@@ -1179,14 +1178,11 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
1179 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), 1178 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
1180 p->video_spatial_filter); 1179 p->video_spatial_filter);
1181 1180
1182 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480))
1183 temporal = 0;
1184
1185 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n", 1181 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
1186 prefix, 1182 prefix,
1187 cx2341x_menu_item(p, 1183 cx2341x_menu_item(p,
1188 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), 1184 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
1189 temporal); 1185 p->video_temporal_filter);
1190 printk(KERN_INFO 1186 printk(KERN_INFO
1191 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", 1187 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
1192 prefix, 1188 prefix,
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 9e1460828b2f..0a199d774d9b 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -991,6 +991,8 @@ static int dvb_register(struct cx23885_tsport *port)
991 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, 991 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
992 &dev->pci->dev, adapter_nr, 0, 992 &dev->pci->dev, adapter_nr, 0,
993 cx23885_dvb_fe_ioctl_override); 993 cx23885_dvb_fe_ioctl_override);
994 if (!ret)
995 return ret;
994 996
995 /* init CI & MAC */ 997 /* init CI & MAC */
996 switch (dev->board) { 998 switch (dev->board) {
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 4172cb387420..d4746e064516 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -365,7 +365,17 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
365 365
366 memset(&info, 0, sizeof(struct i2c_board_info)); 366 memset(&info, 0, sizeof(struct i2c_board_info));
367 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 367 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
368 i2c_new_probed_device(&bus->i2c_adap, &info, addr_list); 368 /*
369 * We can't call i2c_new_probed_device() because it uses
370 * quick writes for probing and the IR receiver device only
371 * replies to reads.
372 */
373 if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0,
374 I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK,
375 NULL) >= 0) {
376 info.addr = addr_list[0];
377 i2c_new_device(&bus->i2c_adap, &info);
378 }
369 } 379 }
370 380
371 return bus->i2c_rc; 381 return bus->i2c_rc;
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 8d306d8bb61c..5de6ba98f7a8 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Most of this file is 6 * Most of this file is
7 * 7 *
8 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 8 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
9 * 9 *
10 * However, the cx23885_input_{init,fini} functions contained herein are 10 * However, the cx23885_input_{init,fini} functions contained herein are
11 * derived from Linux kernel files linux/media/video/.../...-input.c marked as: 11 * derived from Linux kernel files linux/media/video/.../...-input.c marked as:
diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/video/cx23885/cx23885-input.h
index 3572cb1ecfc2..75ef15d3f523 100644
--- a/drivers/media/video/cx23885/cx23885-input.h
+++ b/drivers/media/video/cx23885/cx23885-input.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Infrared remote control input device 4 * Infrared remote control input device
5 * 5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 6 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c
index dfb4627fb340..44812ca78899 100644
--- a/drivers/media/video/cx23885/cx23885-ioctl.c
+++ b/drivers/media/video/cx23885/cx23885-ioctl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Various common ioctl() support functions 4 * Various common ioctl() support functions
5 * 5 *
6 * Copyright (c) 2009 Andy Walls <awalls@radix.net> 6 * Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/video/cx23885/cx23885-ioctl.h
index 80b0f4923c6a..315be0ca5a04 100644
--- a/drivers/media/video/cx23885/cx23885-ioctl.h
+++ b/drivers/media/video/cx23885/cx23885-ioctl.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Various common ioctl() support functions 4 * Various common ioctl() support functions
5 * 5 *
6 * Copyright (c) 2009 Andy Walls <awalls@radix.net> 6 * Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c
index 6ae982cc9856..9a677eb080af 100644
--- a/drivers/media/video/cx23885/cx23885-ir.c
+++ b/drivers/media/video/cx23885/cx23885-ir.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Infrared device support routines - non-input, non-vl42_subdev routines 4 * Infrared device support routines - non-input, non-vl42_subdev routines
5 * 5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 6 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/video/cx23885/cx23885-ir.h
index 9b8a6d5d1ef6..0c9d8bda9e28 100644
--- a/drivers/media/video/cx23885/cx23885-ir.h
+++ b/drivers/media/video/cx23885/cx23885-ir.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Infrared device support routines - non-input, non-vl42_subdev routines 4 * Infrared device support routines - non-input, non-vl42_subdev routines
5 * 5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 6 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 543b854f6a62..4e44dcda3875 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -976,6 +976,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
976{ 976{
977 struct cx23885_fh *fh = priv; 977 struct cx23885_fh *fh = priv;
978 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; 978 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
979 struct v4l2_mbus_framefmt mbus_fmt;
979 int err; 980 int err;
980 981
981 dprintk(2, "%s()\n", __func__); 982 dprintk(2, "%s()\n", __func__);
@@ -989,7 +990,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
989 fh->vidq.field = f->fmt.pix.field; 990 fh->vidq.field = f->fmt.pix.field;
990 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, 991 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
991 fh->width, fh->height, fh->vidq.field); 992 fh->width, fh->height, fh->vidq.field);
992 call_all(dev, video, s_fmt, f); 993 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
994 call_all(dev, video, s_mbus_fmt, &mbus_fmt);
995 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
993 return 0; 996 return 0;
994} 997}
995 998
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
index ad728d767d69..f63d378257a7 100644
--- a/drivers/media/video/cx23885/cx23888-ir.c
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * CX23888 Integrated Consumer Infrared Controller 4 * CX23888 Integrated Consumer Infrared Controller
5 * 5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 6 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/video/cx23885/cx23888-ir.h
index 3d446f9eb94b..d2de41caaf1d 100644
--- a/drivers/media/video/cx23885/cx23888-ir.h
+++ b/drivers/media/video/cx23885/cx23888-ir.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * CX23888 Integrated Consumer Infrared Controller 4 * CX23888 Integrated Consumer Infrared Controller
5 * 5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net> 6 * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 8b6fb3544376..bb4872b2ceb0 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1014,75 +1014,59 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1014 1014
1015/* ----------------------------------------------------------------------- */ 1015/* ----------------------------------------------------------------------- */
1016 1016
1017static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 1017static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
1018{
1019 switch (fmt->type) {
1020 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1021 return cx25840_g_sliced_fmt(sd, &fmt->fmt.sliced);
1022 default:
1023 return -EINVAL;
1024 }
1025 return 0;
1026}
1027
1028static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1029{ 1018{
1030 struct cx25840_state *state = to_state(sd); 1019 struct cx25840_state *state = to_state(sd);
1031 struct i2c_client *client = v4l2_get_subdevdata(sd); 1020 struct i2c_client *client = v4l2_get_subdevdata(sd);
1032 struct v4l2_pix_format *pix;
1033 int HSC, VSC, Vsrc, Hsrc, filter, Vlines; 1021 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
1034 int is_50Hz = !(state->std & V4L2_STD_525_60); 1022 int is_50Hz = !(state->std & V4L2_STD_525_60);
1035 1023
1036 switch (fmt->type) { 1024 if (fmt->code != V4L2_MBUS_FMT_FIXED)
1037 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1025 return -EINVAL;
1038 pix = &(fmt->fmt.pix);
1039
1040 Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
1041 Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
1042
1043 Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
1044 Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
1045 1026
1046 Vlines = pix->height + (is_50Hz ? 4 : 7); 1027 fmt->field = V4L2_FIELD_INTERLACED;
1028 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1047 1029
1048 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || 1030 Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
1049 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { 1031 Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
1050 v4l_err(client, "%dx%d is not a valid size!\n",
1051 pix->width, pix->height);
1052 return -ERANGE;
1053 }
1054 1032
1055 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); 1033 Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
1056 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); 1034 Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
1057 VSC &= 0x1fff;
1058 1035
1059 if (pix->width >= 385) 1036 Vlines = fmt->height + (is_50Hz ? 4 : 7);
1060 filter = 0;
1061 else if (pix->width > 192)
1062 filter = 1;
1063 else if (pix->width > 96)
1064 filter = 2;
1065 else
1066 filter = 3;
1067
1068 v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n",
1069 pix->width, pix->height, HSC, VSC);
1070
1071 /* HSCALE=HSC */
1072 cx25840_write(client, 0x418, HSC & 0xff);
1073 cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
1074 cx25840_write(client, 0x41a, HSC >> 16);
1075 /* VSCALE=VSC */
1076 cx25840_write(client, 0x41c, VSC & 0xff);
1077 cx25840_write(client, 0x41d, VSC >> 8);
1078 /* VS_INTRLACE=1 VFILT=filter */
1079 cx25840_write(client, 0x41e, 0x8 | filter);
1080 break;
1081 1037
1082 default: 1038 if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
1083 return -EINVAL; 1039 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
1040 v4l_err(client, "%dx%d is not a valid size!\n",
1041 fmt->width, fmt->height);
1042 return -ERANGE;
1084 } 1043 }
1085 1044
1045 HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
1046 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
1047 VSC &= 0x1fff;
1048
1049 if (fmt->width >= 385)
1050 filter = 0;
1051 else if (fmt->width > 192)
1052 filter = 1;
1053 else if (fmt->width > 96)
1054 filter = 2;
1055 else
1056 filter = 3;
1057
1058 v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n",
1059 fmt->width, fmt->height, HSC, VSC);
1060
1061 /* HSCALE=HSC */
1062 cx25840_write(client, 0x418, HSC & 0xff);
1063 cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
1064 cx25840_write(client, 0x41a, HSC >> 16);
1065 /* VSCALE=VSC */
1066 cx25840_write(client, 0x41c, VSC & 0xff);
1067 cx25840_write(client, 0x41d, VSC >> 8);
1068 /* VS_INTRLACE=1 VFILT=filter */
1069 cx25840_write(client, 0x41e, 0x8 | filter);
1086 return 0; 1070 return 0;
1087} 1071}
1088 1072
@@ -1627,8 +1611,7 @@ static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
1627 1611
1628static const struct v4l2_subdev_video_ops cx25840_video_ops = { 1612static const struct v4l2_subdev_video_ops cx25840_video_ops = {
1629 .s_routing = cx25840_s_video_routing, 1613 .s_routing = cx25840_s_video_routing,
1630 .g_fmt = cx25840_g_fmt, 1614 .s_mbus_fmt = cx25840_s_mbus_fmt,
1631 .s_fmt = cx25840_s_fmt,
1632 .s_stream = cx25840_s_stream, 1615 .s_stream = cx25840_s_stream,
1633}; 1616};
1634 1617
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index ee1ca39db06a..fb39f1184558 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -188,10 +188,24 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
188 0x18, 0x6b, 0x71, 188 0x18, 0x6b, 0x71,
189 I2C_CLIENT_END 189 I2C_CLIENT_END
190 }; 190 };
191 const unsigned short *addrp;
191 192
192 memset(&info, 0, sizeof(struct i2c_board_info)); 193 memset(&info, 0, sizeof(struct i2c_board_info));
193 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 194 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
194 i2c_new_probed_device(&core->i2c_adap, &info, addr_list); 195 /*
196 * We can't call i2c_new_probed_device() because it uses
197 * quick writes for probing and at least some R receiver
198 * devices only reply to reads.
199 */
200 for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) {
201 if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0,
202 I2C_SMBUS_READ, 0,
203 I2C_SMBUS_QUICK, NULL) >= 0) {
204 info.addr = *addrp;
205 i2c_new_device(&core->i2c_adap, &info);
206 break;
207 }
208 }
195 } 209 }
196 return core->i2c_rc; 210 return core->i2c_rc;
197} 211}
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 331e1cac4272..44c63cbd6dda 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1186,8 +1186,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
1186 mutex_lock(&em28xx_devlist_mutex); 1186 mutex_lock(&em28xx_devlist_mutex);
1187 list_add_tail(&ops->next, &em28xx_extension_devlist); 1187 list_add_tail(&ops->next, &em28xx_extension_devlist);
1188 list_for_each_entry(dev, &em28xx_devlist, devlist) { 1188 list_for_each_entry(dev, &em28xx_devlist, devlist) {
1189 if (dev) 1189 ops->init(dev);
1190 ops->init(dev);
1191 } 1190 }
1192 printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); 1191 printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
1193 mutex_unlock(&em28xx_devlist_mutex); 1192 mutex_unlock(&em28xx_devlist_mutex);
@@ -1201,10 +1200,8 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
1201 1200
1202 mutex_lock(&em28xx_devlist_mutex); 1201 mutex_lock(&em28xx_devlist_mutex);
1203 list_for_each_entry(dev, &em28xx_devlist, devlist) { 1202 list_for_each_entry(dev, &em28xx_devlist, devlist) {
1204 if (dev) 1203 ops->fini(dev);
1205 ops->fini(dev);
1206 } 1204 }
1207
1208 printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); 1205 printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
1209 list_del(&ops->next); 1206 list_del(&ops->next);
1210 mutex_unlock(&em28xx_devlist_mutex); 1207 mutex_unlock(&em28xx_devlist_mutex);
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 785eeb4c2014..95354a339e3d 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -1453,9 +1453,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
1453 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, 1453 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1454 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, 1454 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1455 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, 1455 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1456#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1457 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, 1456 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1458#endif
1459 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, 1457 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1460#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1458#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1461 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, 1459 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index bb923efb75bd..176c5b3d5e6f 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -3022,16 +3022,18 @@ static const __devinitdata struct usb_device_id device_table[] = {
3022/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ 3022/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
3023/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ 3023/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
3024/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */ 3024/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
3025 {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
3025 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)}, 3026 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
3026/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */ 3027/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
3027/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */ 3028/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
3029/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
3028 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)}, 3030 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
3029#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 3031#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
3030 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)}, 3032 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
3031 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)}, 3033 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
3032#endif 3034#endif
3033 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/ 3035 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
3034/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */ 3036/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, * / GC0305*/
3035/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */ 3037/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
3036 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/ 3038 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
3037 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/ 3039 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
@@ -3058,6 +3060,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
3058 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, 3060 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
3059 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, 3061 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
3060 {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/ 3062 {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
3063 /* or GC0305 / GC0307 */
3061 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ 3064 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
3062 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ 3065 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
3063 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/ 3066 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 7cfccfd1b870..c338f3f62e77 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -366,7 +366,7 @@ static int hdpvr_open(struct file *file)
366 366
367 dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file)); 367 dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
368 if (!dev) { 368 if (!dev) {
369 v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n"); 369 pr_err("open failing with with ENODEV\n");
370 retval = -ENODEV; 370 retval = -ENODEV;
371 goto err; 371 goto err;
372 } 372 }
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index b59475bfc243..b588e30cbcf0 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -267,13 +267,13 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
267 if (p.video_encoding != itv->params.video_encoding) { 267 if (p.video_encoding != itv->params.video_encoding) {
268 int is_mpeg1 = p.video_encoding == 268 int is_mpeg1 = p.video_encoding ==
269 V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 269 V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
270 struct v4l2_format fmt; 270 struct v4l2_mbus_framefmt fmt;
271 271
272 /* fix videodecoder resolution */ 272 /* fix videodecoder resolution */
273 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 273 fmt.width = itv->params.width / (is_mpeg1 ? 2 : 1);
274 fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); 274 fmt.height = itv->params.height;
275 fmt.fmt.pix.height = itv->params.height; 275 fmt.code = V4L2_MBUS_FMT_FIXED;
276 v4l2_subdev_call(itv->sd_video, video, s_fmt, &fmt); 276 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt);
277 } 277 }
278 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); 278 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
279 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) 279 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index abf410943cc9..3c2cc270ccd5 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -823,6 +823,12 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
823 823
824 IVTV_DEBUG_FILE("close() of %s\n", s->name); 824 IVTV_DEBUG_FILE("close() of %s\n", s->name);
825 825
826 if (id->type == IVTV_DEC_STREAM_TYPE_YUV &&
827 test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {
828 /* Restore registers we've changed & clean up any mess */
829 ivtv_yuv_close(itv);
830 }
831
826 /* Stop decoding */ 832 /* Stop decoding */
827 if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 833 if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
828 IVTV_DEBUG_INFO("close stopping decode\n"); 834 IVTV_DEBUG_INFO("close stopping decode\n");
@@ -832,10 +838,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
832 } 838 }
833 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); 839 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
834 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 840 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
835 if (id->type == IVTV_DEC_STREAM_TYPE_YUV && test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) { 841
836 /* Restore registers we've changed & clean up any mess we've made */
837 ivtv_yuv_close(itv);
838 }
839 if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames) 842 if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames)
840 itv->output_mode = OUT_NONE; 843 itv->output_mode = OUT_NONE;
841 844
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index fa9f0d958f96..11ac2fa33ef7 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -569,6 +569,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
569 struct ivtv_open_id *id = fh; 569 struct ivtv_open_id *id = fh;
570 struct ivtv *itv = id->itv; 570 struct ivtv *itv = id->itv;
571 struct cx2341x_mpeg_params *p = &itv->params; 571 struct cx2341x_mpeg_params *p = &itv->params;
572 struct v4l2_mbus_framefmt mbus_fmt;
572 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); 573 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
573 int w = fmt->fmt.pix.width; 574 int w = fmt->fmt.pix.width;
574 int h = fmt->fmt.pix.height; 575 int h = fmt->fmt.pix.height;
@@ -586,7 +587,10 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
586 p->height = h; 587 p->height = h;
587 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) 588 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
588 fmt->fmt.pix.width /= 2; 589 fmt->fmt.pix.width /= 2;
589 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); 590 mbus_fmt.width = fmt->fmt.pix.width;
591 mbus_fmt.height = h;
592 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
593 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
590 return ivtv_g_fmt_vid_cap(file, fh, fmt); 594 return ivtv_g_fmt_vid_cap(file, fh, fmt);
591} 595}
592 596
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index de4288cc1889..9ecacab4b89b 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -618,12 +618,17 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
618 struct ivtv *itv = s->itv; 618 struct ivtv *itv = s->itv;
619 struct cx2341x_mpeg_params *p = &itv->params; 619 struct cx2341x_mpeg_params *p = &itv->params;
620 int datatype; 620 int datatype;
621 u16 width;
622 u16 height;
621 623
622 if (s->vdev == NULL) 624 if (s->vdev == NULL)
623 return -EINVAL; 625 return -EINVAL;
624 626
625 IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); 627 IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
626 628
629 width = p->width;
630 height = p->height;
631
627 /* set audio mode to left/stereo for dual/stereo mode. */ 632 /* set audio mode to left/stereo for dual/stereo mode. */
628 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); 633 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
629 634
@@ -646,7 +651,14 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
646 2 = yuv_from_host */ 651 2 = yuv_from_host */
647 switch (s->type) { 652 switch (s->type) {
648 case IVTV_DEC_STREAM_TYPE_YUV: 653 case IVTV_DEC_STREAM_TYPE_YUV:
649 datatype = itv->output_mode == OUT_PASSTHROUGH ? 1 : 2; 654 if (itv->output_mode == OUT_PASSTHROUGH) {
655 datatype = 1;
656 } else {
657 /* Fake size to avoid switching video standard */
658 datatype = 2;
659 width = 720;
660 height = itv->is_out_50hz ? 576 : 480;
661 }
650 IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype); 662 IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype);
651 break; 663 break;
652 case IVTV_DEC_STREAM_TYPE_MPG: 664 case IVTV_DEC_STREAM_TYPE_MPG:
@@ -655,9 +667,13 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
655 break; 667 break;
656 } 668 }
657 if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, 669 if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
658 p->width, p->height, p->audio_properties)) { 670 width, height, p->audio_properties)) {
659 IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); 671 IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
660 } 672 }
673
674 /* Decoder sometimes dies here, so wait a moment */
675 ivtv_msleep_timeout(10, 0);
676
661 return 0; 677 return 0;
662} 678}
663 679
@@ -697,6 +713,9 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
697 /* start playback */ 713 /* start playback */
698 ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0); 714 ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0);
699 715
716 /* Let things settle before we actually start */
717 ivtv_msleep_timeout(10, 0);
718
700 /* Clear the following Interrupt mask bits for decoding */ 719 /* Clear the following Interrupt mask bits for decoding */
701 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE); 720 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
702 IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask); 721 IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask);
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 49e1a283ed36..9ff3425891ed 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -1066,7 +1066,11 @@ static int ivtvfb_init_io(struct ivtv *itv)
1066 } 1066 }
1067 mutex_unlock(&itv->serialize_lock); 1067 mutex_unlock(&itv->serialize_lock);
1068 1068
1069 ivtvfb_get_framebuffer(itv, &oi->video_rbase, &oi->video_buffer_size); 1069 if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
1070 &oi->video_buffer_size) < 0) {
1071 IVTVFB_ERR("Firmware failed to respond\n");
1072 return -EIO;
1073 }
1070 1074
1071 /* The osd buffer size depends on the number of video buffers allocated 1075 /* The osd buffer size depends on the number of video buffers allocated
1072 on the PVR350 itself. For now we'll hardcode the smallest osd buffer 1076 on the PVR350 itself. For now we'll hardcode the smallest osd buffer
@@ -1158,8 +1162,11 @@ static int ivtvfb_init_card(struct ivtv *itv)
1158 } 1162 }
1159 1163
1160 /* Find & setup the OSD buffer */ 1164 /* Find & setup the OSD buffer */
1161 if ((rc = ivtvfb_init_io(itv))) 1165 rc = ivtvfb_init_io(itv);
1166 if (rc) {
1167 ivtvfb_release_buffers(itv);
1162 return rc; 1168 return rc;
1169 }
1163 1170
1164 /* Set the startup video mode information */ 1171 /* Set the startup video mode information */
1165 if ((rc = ivtvfb_init_vidmode(itv))) { 1172 if ((rc = ivtvfb_init_vidmode(itv))) {
@@ -1210,6 +1217,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1210{ 1217{
1211 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); 1218 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1212 struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); 1219 struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1220 struct osd_info *oi = itv->osd_info;
1213 1221
1214 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { 1222 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
1215 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { 1223 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
@@ -1218,7 +1226,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1218 return 0; 1226 return 0;
1219 } 1227 }
1220 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); 1228 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1221 ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); 1229 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
1222 ivtvfb_release_buffers(itv); 1230 ivtvfb_release_buffers(itv);
1223 itv->osd_video_pbase = 0; 1231 itv->osd_video_pbase = 0;
1224 } 1232 }
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index b62c0bd3f8ea..79f096ddcf5d 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -701,13 +701,13 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
701#endif 701#endif
702}; 702};
703 703
704static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index, 704static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
705 enum v4l2_mbus_pixelcode *code) 705 enum v4l2_mbus_pixelcode *code)
706{ 706{
707 struct i2c_client *client = sd->priv; 707 struct i2c_client *client = sd->priv;
708 struct mt9m001 *mt9m001 = to_mt9m001(client); 708 struct mt9m001 *mt9m001 = to_mt9m001(client);
709 709
710 if ((unsigned int)index >= mt9m001->num_fmts) 710 if (index >= mt9m001->num_fmts)
711 return -EINVAL; 711 return -EINVAL;
712 712
713 *code = mt9m001->fmts[index].code; 713 *code = mt9m001->fmts[index].code;
@@ -785,7 +785,6 @@ static int mt9m001_probe(struct i2c_client *client,
785 ret = mt9m001_video_probe(icd, client); 785 ret = mt9m001_video_probe(icd, client);
786 if (ret) { 786 if (ret) {
787 icd->ops = NULL; 787 icd->ops = NULL;
788 i2c_set_clientdata(client, NULL);
789 kfree(mt9m001); 788 kfree(mt9m001);
790 } 789 }
791 790
@@ -799,7 +798,6 @@ static int mt9m001_remove(struct i2c_client *client)
799 798
800 icd->ops = NULL; 799 icd->ops = NULL;
801 mt9m001_video_remove(icd); 800 mt9m001_video_remove(icd);
802 i2c_set_clientdata(client, NULL);
803 client->driver = NULL; 801 client->driver = NULL;
804 kfree(mt9m001); 802 kfree(mt9m001);
805 803
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index d35f536f9fc3..fbd0fc794720 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -999,10 +999,10 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
999#endif 999#endif
1000}; 1000};
1001 1001
1002static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index, 1002static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1003 enum v4l2_mbus_pixelcode *code) 1003 enum v4l2_mbus_pixelcode *code)
1004{ 1004{
1005 if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts)) 1005 if (index >= ARRAY_SIZE(mt9m111_colour_fmts))
1006 return -EINVAL; 1006 return -EINVAL;
1007 1007
1008 *code = mt9m111_colour_fmts[index].code; 1008 *code = mt9m111_colour_fmts[index].code;
@@ -1068,7 +1068,6 @@ static int mt9m111_probe(struct i2c_client *client,
1068 ret = mt9m111_video_probe(icd, client); 1068 ret = mt9m111_video_probe(icd, client);
1069 if (ret) { 1069 if (ret) {
1070 icd->ops = NULL; 1070 icd->ops = NULL;
1071 i2c_set_clientdata(client, NULL);
1072 kfree(mt9m111); 1071 kfree(mt9m111);
1073 } 1072 }
1074 1073
@@ -1081,7 +1080,6 @@ static int mt9m111_remove(struct i2c_client *client)
1081 struct soc_camera_device *icd = client->dev.platform_data; 1080 struct soc_camera_device *icd = client->dev.platform_data;
1082 1081
1083 icd->ops = NULL; 1082 icd->ops = NULL;
1084 i2c_set_clientdata(client, NULL);
1085 client->driver = NULL; 1083 client->driver = NULL;
1086 kfree(mt9m111); 1084 kfree(mt9m111);
1087 1085
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 78b4e091d2d5..a9a28b214235 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -798,7 +798,7 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
798#endif 798#endif
799}; 799};
800 800
801static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index, 801static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
802 enum v4l2_mbus_pixelcode *code) 802 enum v4l2_mbus_pixelcode *code)
803{ 803{
804 if (index) 804 if (index)
@@ -883,7 +883,6 @@ static int mt9t031_probe(struct i2c_client *client,
883 if (ret) { 883 if (ret) {
884 if (icd) 884 if (icd)
885 icd->ops = NULL; 885 icd->ops = NULL;
886 i2c_set_clientdata(client, NULL);
887 kfree(mt9t031); 886 kfree(mt9t031);
888 } 887 }
889 888
@@ -897,7 +896,6 @@ static int mt9t031_remove(struct i2c_client *client)
897 896
898 if (icd) 897 if (icd)
899 icd->ops = NULL; 898 icd->ops = NULL;
900 i2c_set_clientdata(client, NULL);
901 client->driver = NULL; 899 client->driver = NULL;
902 kfree(mt9t031); 900 kfree(mt9t031);
903 901
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index 7438f8d775ba..e4bf1db9a87b 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -1017,10 +1017,10 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd,
1017 return 0; 1017 return 0;
1018} 1018}
1019 1019
1020static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index, 1020static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1021 enum v4l2_mbus_pixelcode *code) 1021 enum v4l2_mbus_pixelcode *code)
1022{ 1022{
1023 if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts)) 1023 if (index >= ARRAY_SIZE(mt9t112_cfmts))
1024 return -EINVAL; 1024 return -EINVAL;
1025 1025
1026 *code = mt9t112_cfmts[index].code; 1026 *code = mt9t112_cfmts[index].code;
@@ -1119,7 +1119,6 @@ static int mt9t112_probe(struct i2c_client *client,
1119 ret = mt9t112_camera_probe(icd, client); 1119 ret = mt9t112_camera_probe(icd, client);
1120 if (ret) { 1120 if (ret) {
1121 icd->ops = NULL; 1121 icd->ops = NULL;
1122 i2c_set_clientdata(client, NULL);
1123 kfree(priv); 1122 kfree(priv);
1124 } 1123 }
1125 1124
@@ -1132,7 +1131,6 @@ static int mt9t112_remove(struct i2c_client *client)
1132 struct soc_camera_device *icd = client->dev.platform_data; 1131 struct soc_camera_device *icd = client->dev.platform_data;
1133 1132
1134 icd->ops = NULL; 1133 icd->ops = NULL;
1135 i2c_set_clientdata(client, NULL);
1136 kfree(priv); 1134 kfree(priv);
1137 return 0; 1135 return 0;
1138} 1136}
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c
index 72e55be0b4ab..f5e778d5ca9f 100644
--- a/drivers/media/video/mt9v011.c
+++ b/drivers/media/video/mt9v011.c
@@ -392,27 +392,25 @@ static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
392 return 0; 392 return 0;
393} 393}
394 394
395static int mt9v011_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) 395static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
396 enum v4l2_mbus_pixelcode *code)
396{ 397{
397 if (fmt->index > 0) 398 if (index > 0)
398 return -EINVAL; 399 return -EINVAL;
399 400
400 fmt->flags = 0; 401 *code = V4L2_MBUS_FMT_SGRBG8_1X8;
401 strcpy(fmt->description, "8 bpp Bayer GRGR..BGBG");
402 fmt->pixelformat = V4L2_PIX_FMT_SGRBG8;
403
404 return 0; 402 return 0;
405} 403}
406 404
407static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 405static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
408{ 406{
409 struct v4l2_pix_format *pix = &fmt->fmt.pix; 407 if (fmt->code != V4L2_MBUS_FMT_SGRBG8_1X8)
410
411 if (pix->pixelformat != V4L2_PIX_FMT_SGRBG8)
412 return -EINVAL; 408 return -EINVAL;
413 409
414 v4l_bound_align_image(&pix->width, 48, 639, 1, 410 v4l_bound_align_image(&fmt->width, 48, 639, 1,
415 &pix->height, 32, 480, 1, 0); 411 &fmt->height, 32, 480, 1, 0);
412 fmt->field = V4L2_FIELD_NONE;
413 fmt->colorspace = V4L2_COLORSPACE_SRGB;
416 414
417 return 0; 415 return 0;
418} 416}
@@ -455,18 +453,17 @@ static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
455 return 0; 453 return 0;
456} 454}
457 455
458static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 456static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
459{ 457{
460 struct v4l2_pix_format *pix = &fmt->fmt.pix;
461 struct mt9v011 *core = to_mt9v011(sd); 458 struct mt9v011 *core = to_mt9v011(sd);
462 int rc; 459 int rc;
463 460
464 rc = mt9v011_try_fmt(sd, fmt); 461 rc = mt9v011_try_mbus_fmt(sd, fmt);
465 if (rc < 0) 462 if (rc < 0)
466 return -EINVAL; 463 return -EINVAL;
467 464
468 core->width = pix->width; 465 core->width = fmt->width;
469 core->height = pix->height; 466 core->height = fmt->height;
470 467
471 set_res(sd); 468 set_res(sd);
472 469
@@ -549,9 +546,9 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
549}; 546};
550 547
551static const struct v4l2_subdev_video_ops mt9v011_video_ops = { 548static const struct v4l2_subdev_video_ops mt9v011_video_ops = {
552 .enum_fmt = mt9v011_enum_fmt, 549 .enum_mbus_fmt = mt9v011_enum_mbus_fmt,
553 .try_fmt = mt9v011_try_fmt, 550 .try_mbus_fmt = mt9v011_try_mbus_fmt,
554 .s_fmt = mt9v011_s_fmt, 551 .s_mbus_fmt = mt9v011_s_mbus_fmt,
555 .g_parm = mt9v011_g_parm, 552 .g_parm = mt9v011_g_parm,
556 .s_parm = mt9v011_s_parm, 553 .s_parm = mt9v011_s_parm,
557}; 554};
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index e5bae4c9393b..e7cd23cd6394 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -838,13 +838,13 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
838#endif 838#endif
839}; 839};
840 840
841static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index, 841static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
842 enum v4l2_mbus_pixelcode *code) 842 enum v4l2_mbus_pixelcode *code)
843{ 843{
844 struct i2c_client *client = sd->priv; 844 struct i2c_client *client = sd->priv;
845 struct mt9v022 *mt9v022 = to_mt9v022(client); 845 struct mt9v022 *mt9v022 = to_mt9v022(client);
846 846
847 if ((unsigned int)index >= mt9v022->num_fmts) 847 if (index >= mt9v022->num_fmts)
848 return -EINVAL; 848 return -EINVAL;
849 849
850 *code = mt9v022->fmts[index].code; 850 *code = mt9v022->fmts[index].code;
@@ -920,7 +920,6 @@ static int mt9v022_probe(struct i2c_client *client,
920 ret = mt9v022_video_probe(icd, client); 920 ret = mt9v022_video_probe(icd, client);
921 if (ret) { 921 if (ret) {
922 icd->ops = NULL; 922 icd->ops = NULL;
923 i2c_set_clientdata(client, NULL);
924 kfree(mt9v022); 923 kfree(mt9v022);
925 } 924 }
926 925
@@ -934,7 +933,6 @@ static int mt9v022_remove(struct i2c_client *client)
934 933
935 icd->ops = NULL; 934 icd->ops = NULL;
936 mt9v022_video_remove(icd); 935 mt9v022_video_remove(icd);
937 i2c_set_clientdata(client, NULL);
938 client->driver = NULL; 936 client->driver = NULL;
939 kfree(mt9v022); 937 kfree(mt9v022);
940 938
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index d477e3058002..a9be14c23912 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -672,7 +672,7 @@ static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
672 fmt->packing == SOC_MBUS_PACKING_EXTEND16); 672 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
673} 673}
674 674
675static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, 675static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
676 struct soc_camera_format_xlate *xlate) 676 struct soc_camera_format_xlate *xlate)
677{ 677{
678 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 678 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -689,7 +689,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
689 fmt = soc_mbus_get_fmtdesc(code); 689 fmt = soc_mbus_get_fmtdesc(code);
690 if (!fmt) { 690 if (!fmt) {
691 dev_err(icd->dev.parent, 691 dev_err(icd->dev.parent,
692 "Invalid format code #%d: %d\n", idx, code); 692 "Invalid format code #%u: %d\n", idx, code);
693 return 0; 693 return 0;
694 } 694 }
695 695
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 4c0ab499228b..e7db0554949a 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -2371,12 +2371,11 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev)
2371 2371
2372 for (k = 0; k < pdev->num_resources; k++) { 2372 for (k = 0; k < pdev->num_resources; k++) {
2373 2373
2374 vout = kmalloc(sizeof(struct omap_vout_device), GFP_KERNEL); 2374 vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
2375 if (!vout) { 2375 if (!vout) {
2376 dev_err(&pdev->dev, ": could not allocate memory\n"); 2376 dev_err(&pdev->dev, ": could not allocate memory\n");
2377 return -ENOMEM; 2377 return -ENOMEM;
2378 } 2378 }
2379 memset(vout, 0, sizeof(struct omap_vout_device));
2380 2379
2381 vout->vid = k; 2380 vout->vid = k;
2382 vid_dev->vouts[k] = vout; 2381 vid_dev->vouts[k] = vout;
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 7f8ece30c77b..34034a710214 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -1092,10 +1092,10 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1092#endif 1092#endif
1093}; 1093};
1094 1094
1095static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index, 1095static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1096 enum v4l2_mbus_pixelcode *code) 1096 enum v4l2_mbus_pixelcode *code)
1097{ 1097{
1098 if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts)) 1098 if (index >= ARRAY_SIZE(ov772x_cfmts))
1099 return -EINVAL; 1099 return -EINVAL;
1100 1100
1101 *code = ov772x_cfmts[index].code; 1101 *code = ov772x_cfmts[index].code;
@@ -1159,7 +1159,6 @@ static int ov772x_probe(struct i2c_client *client,
1159 ret = ov772x_video_probe(icd, client); 1159 ret = ov772x_video_probe(icd, client);
1160 if (ret) { 1160 if (ret) {
1161 icd->ops = NULL; 1161 icd->ops = NULL;
1162 i2c_set_clientdata(client, NULL);
1163 kfree(priv); 1162 kfree(priv);
1164 } 1163 }
1165 1164
@@ -1172,7 +1171,6 @@ static int ov772x_remove(struct i2c_client *client)
1172 struct soc_camera_device *icd = client->dev.platform_data; 1171 struct soc_camera_device *icd = client->dev.platform_data;
1173 1172
1174 icd->ops = NULL; 1173 icd->ops = NULL;
1175 i2c_set_clientdata(client, NULL);
1176 kfree(priv); 1174 kfree(priv);
1177 return 0; 1175 return 0;
1178} 1176}
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
index 36599a65f548..7ce9e05b4781 100644
--- a/drivers/media/video/ov9640.c
+++ b/drivers/media/video/ov9640.c
@@ -614,10 +614,10 @@ static int ov9640_try_fmt(struct v4l2_subdev *sd,
614 return 0; 614 return 0;
615} 615}
616 616
617static int ov9640_enum_fmt(struct v4l2_subdev *sd, int index, 617static int ov9640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
618 enum v4l2_mbus_pixelcode *code) 618 enum v4l2_mbus_pixelcode *code)
619{ 619{
620 if ((unsigned int)index >= ARRAY_SIZE(ov9640_codes)) 620 if (index >= ARRAY_SIZE(ov9640_codes))
621 return -EINVAL; 621 return -EINVAL;
622 622
623 *code = ov9640_codes[index]; 623 *code = ov9640_codes[index];
@@ -783,7 +783,6 @@ static int ov9640_probe(struct i2c_client *client,
783 783
784 if (ret) { 784 if (ret) {
785 icd->ops = NULL; 785 icd->ops = NULL;
786 i2c_set_clientdata(client, NULL);
787 kfree(priv); 786 kfree(priv);
788 } 787 }
789 788
@@ -794,7 +793,6 @@ static int ov9640_remove(struct i2c_client *client)
794{ 793{
795 struct ov9640_priv *priv = i2c_get_clientdata(client); 794 struct ov9640_priv *priv = i2c_get_clientdata(client);
796 795
797 i2c_set_clientdata(client, NULL);
798 kfree(priv); 796 kfree(priv);
799 return 0; 797 return 0;
800} 798}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 6bc16c13ccef..3092abfd66a2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -117,6 +117,7 @@ static const struct pvr2_device_desc pvr2_device_24xxx = {
117static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = { 117static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = {
118 { .module_id = PVR2_CLIENT_ID_CX25840 }, 118 { .module_id = PVR2_CLIENT_ID_CX25840 },
119 { .module_id = PVR2_CLIENT_ID_TUNER }, 119 { .module_id = PVR2_CLIENT_ID_TUNER },
120 { .module_id = PVR2_CLIENT_ID_DEMOD },
120}; 121};
121 122
122static const struct pvr2_device_desc pvr2_device_gotview_2 = { 123static const struct pvr2_device_desc pvr2_device_gotview_2 = {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index e5b9594eb5f6..273c8d4b3853 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -177,6 +177,11 @@ struct pvr2_device_desc {
177 unsigned int flag_has_composite:1; /* Has composite input */ 177 unsigned int flag_has_composite:1; /* Has composite input */
178 unsigned int flag_has_svideo:1; /* Has s-video input */ 178 unsigned int flag_has_svideo:1; /* Has s-video input */
179 unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */ 179 unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */
180
181 /* If this driver is considered experimental, i.e. not all aspects
182 are working correctly and/or it is untested, mark that fact
183 with this flag. */
184 unsigned int flag_is_experimental:1;
180}; 185};
181 186
182extern struct usb_device_id pvr2_device_table[]; 187extern struct usb_device_id pvr2_device_table[];
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 301ef197d038..70ea578d6266 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2459,6 +2459,19 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2459 hdw,hdw_desc->description); 2459 hdw,hdw_desc->description);
2460 pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s", 2460 pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s",
2461 hdw_desc->description); 2461 hdw_desc->description);
2462 if (hdw_desc->flag_is_experimental) {
2463 pvr2_trace(PVR2_TRACE_INFO, "**********");
2464 pvr2_trace(PVR2_TRACE_INFO,
2465 "WARNING: Support for this device (%s) is"
2466 " experimental.", hdw_desc->description);
2467 pvr2_trace(PVR2_TRACE_INFO,
2468 "Important functionality might not be"
2469 " entirely working.");
2470 pvr2_trace(PVR2_TRACE_INFO,
2471 "Please consider contacting the driver author to"
2472 " help with further stabilization of the driver.");
2473 pvr2_trace(PVR2_TRACE_INFO, "**********");
2474 }
2462 if (!hdw) goto fail; 2475 if (!hdw) goto fail;
2463 2476
2464 init_timer(&hdw->quiescent_timer); 2477 init_timer(&hdw->quiescent_timer);
@@ -3056,14 +3069,14 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
3056 } 3069 }
3057 3070
3058 if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) { 3071 if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) {
3059 struct v4l2_format fmt; 3072 struct v4l2_mbus_framefmt fmt;
3060 memset(&fmt, 0, sizeof(fmt)); 3073 memset(&fmt, 0, sizeof(fmt));
3061 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 3074 fmt.width = hdw->res_hor_val;
3062 fmt.fmt.pix.width = hdw->res_hor_val; 3075 fmt.height = hdw->res_ver_val;
3063 fmt.fmt.pix.height = hdw->res_ver_val; 3076 fmt.code = V4L2_MBUS_FMT_FIXED;
3064 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", 3077 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)",
3065 fmt.fmt.pix.width, fmt.fmt.pix.height); 3078 fmt.width, fmt.height);
3066 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt); 3079 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt);
3067 } 3080 }
3068 3081
3069 if (hdw->srate_dirty || hdw->force_dirty) { 3082 if (hdw->srate_dirty || hdw->force_dirty) {
@@ -4084,12 +4097,20 @@ void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
4084 4097
4085void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) 4098void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
4086{ 4099{
4087 char da[1]; 4100 char *da;
4088 unsigned int pipe; 4101 unsigned int pipe;
4089 int ret; 4102 int ret;
4090 4103
4091 if (!hdw->usb_dev) return; 4104 if (!hdw->usb_dev) return;
4092 4105
4106 da = kmalloc(16, GFP_KERNEL);
4107
4108 if (da == NULL) {
4109 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
4110 "Unable to allocate memory to control CPU reset");
4111 return;
4112 }
4113
4093 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val); 4114 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
4094 4115
4095 da[0] = val ? 0x01 : 0x00; 4116 da[0] = val ? 0x01 : 0x00;
@@ -4103,6 +4124,8 @@ void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
4103 "cpureset_assert(%d) error=%d",val,ret); 4124 "cpureset_assert(%d) error=%d",val,ret);
4104 pvr2_hdw_render_useless(hdw); 4125 pvr2_hdw_render_useless(hdw);
4105 } 4126 }
4127
4128 kfree(da);
4106} 4129}
4107 4130
4108 4131
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index eeacd0f67855..2254194aad57 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -153,12 +153,12 @@ static void __exit pvr_exit(void)
153 153
154 usb_deregister(&pvr_driver); 154 usb_deregister(&pvr_driver);
155 155
156 pvr2_context_global_done();
157
156#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS 158#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
157 pvr2_sysfs_class_destroy(class_ptr); 159 pvr2_sysfs_class_destroy(class_ptr);
158#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ 160#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
159 161
160 pvr2_context_global_done();
161
162 pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete"); 162 pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete");
163} 163}
164 164
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 71f50565f637..3d7e5aab547f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -74,7 +74,7 @@ struct pvr2_sysfs_ctl_item {
74 int ctl_id; 74 int ctl_id;
75 struct pvr2_sysfs *chptr; 75 struct pvr2_sysfs *chptr;
76 struct pvr2_sysfs_ctl_item *item_next; 76 struct pvr2_sysfs_ctl_item *item_next;
77 struct attribute *attr_gen[7]; 77 struct attribute *attr_gen[8];
78 struct attribute_group grp; 78 struct attribute_group grp;
79 int created_ok; 79 int created_ok;
80 char name[80]; 80 char name[80];
@@ -511,6 +511,7 @@ static void pvr2_sysfs_release(struct device *class_dev)
511 511
512static void class_dev_destroy(struct pvr2_sysfs *sfp) 512static void class_dev_destroy(struct pvr2_sysfs *sfp)
513{ 513{
514 struct device *dev;
514 if (!sfp->class_dev) return; 515 if (!sfp->class_dev) return;
515#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 516#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
516 pvr2_sysfs_tear_down_debugifc(sfp); 517 pvr2_sysfs_tear_down_debugifc(sfp);
@@ -542,6 +543,9 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
542 } 543 }
543 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); 544 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
544 dev_set_drvdata(sfp->class_dev, NULL); 545 dev_set_drvdata(sfp->class_dev, NULL);
546 dev = sfp->class_dev->parent;
547 sfp->class_dev->parent = NULL;
548 put_device(dev);
545 device_unregister(sfp->class_dev); 549 device_unregister(sfp->class_dev);
546 sfp->class_dev = NULL; 550 sfp->class_dev = NULL;
547} 551}
@@ -631,10 +635,11 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
631 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); 635 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
632 636
633 class_dev->class = &class_ptr->class; 637 class_dev->class = &class_ptr->class;
638
634 dev_set_name(class_dev, "%s", 639 dev_set_name(class_dev, "%s",
635 pvr2_hdw_get_device_identifier(sfp->channel.hdw)); 640 pvr2_hdw_get_device_identifier(sfp->channel.hdw));
636 641
637 class_dev->parent = &usb_dev->dev; 642 class_dev->parent = get_device(&usb_dev->dev);
638 643
639 sfp->class_dev = class_dev; 644 sfp->class_dev = class_dev;
640 dev_set_drvdata(class_dev, sfp); 645 dev_set_drvdata(class_dev, sfp);
@@ -775,7 +780,8 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
775 struct pvr2_sysfs_class *clp; 780 struct pvr2_sysfs_class *clp;
776 clp = kzalloc(sizeof(*clp),GFP_KERNEL); 781 clp = kzalloc(sizeof(*clp),GFP_KERNEL);
777 if (!clp) return clp; 782 if (!clp) return clp;
778 pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp); 783 pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
784 clp);
779 clp->class.name = "pvrusb2"; 785 clp->class.name = "pvrusb2";
780 clp->class.class_release = pvr2_sysfs_class_release; 786 clp->class.class_release = pvr2_sysfs_class_release;
781 clp->class.dev_release = pvr2_sysfs_release; 787 clp->class.dev_release = pvr2_sysfs_release;
@@ -791,6 +797,7 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
791 797
792void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) 798void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
793{ 799{
800 pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp);
794 class_unregister(&clp->class); 801 class_unregister(&clp->class);
795} 802}
796 803
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 5ffa0d2b0b0d..aaafa0398fd5 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -883,6 +883,17 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
883{ 883{
884 struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw; 884 struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
885 enum pvr2_config cfg = dip->config; 885 enum pvr2_config cfg = dip->config;
886 char msg[80];
887 unsigned int mcnt;
888
889 /* Construct the unregistration message *before* we actually
890 perform the unregistration step. By doing it this way we don't
891 have to worry about potentially touching deleted resources. */
892 mcnt = scnprintf(msg, sizeof(msg) - 1,
893 "pvrusb2: unregistered device %s [%s]",
894 video_device_node_name(&dip->devbase),
895 pvr2_config_get_name(cfg));
896 msg[mcnt] = 0;
886 897
887 pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1); 898 pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
888 899
@@ -894,9 +905,7 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
894 are gone. */ 905 are gone. */
895 video_unregister_device(&dip->devbase); 906 video_unregister_device(&dip->devbase);
896 907
897 printk(KERN_INFO "pvrusb2: unregistered device %s [%s]\n", 908 printk(KERN_INFO "%s\n", msg);
898 video_device_node_name(&dip->devbase),
899 pvr2_config_get_name(cfg));
900 909
901} 910}
902 911
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 7fe70e718656..fb242f6cfb1f 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1247,7 +1247,7 @@ static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
1247 fmt->packing == SOC_MBUS_PACKING_EXTEND16); 1247 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
1248} 1248}
1249 1249
1250static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, 1250static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1251 struct soc_camera_format_xlate *xlate) 1251 struct soc_camera_format_xlate *xlate)
1252{ 1252{
1253 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1253 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -1264,7 +1264,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1264 1264
1265 fmt = soc_mbus_get_fmtdesc(code); 1265 fmt = soc_mbus_get_fmtdesc(code);
1266 if (!fmt) { 1266 if (!fmt) {
1267 dev_err(dev, "Invalid format code #%d: %d\n", idx, code); 1267 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1268 return 0; 1268 return 0;
1269 } 1269 }
1270 1270
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index bbd9c11e2c5a..47fd207ba3b1 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -481,10 +481,10 @@ static int reg_write_multiple(struct i2c_client *client,
481 return 0; 481 return 0;
482} 482}
483 483
484static int rj54n1_enum_fmt(struct v4l2_subdev *sd, int index, 484static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
485 enum v4l2_mbus_pixelcode *code) 485 enum v4l2_mbus_pixelcode *code)
486{ 486{
487 if ((unsigned int)index >= ARRAY_SIZE(rj54n1_colour_fmts)) 487 if (index >= ARRAY_SIZE(rj54n1_colour_fmts))
488 return -EINVAL; 488 return -EINVAL;
489 489
490 *code = rj54n1_colour_fmts[index].code; 490 *code = rj54n1_colour_fmts[index].code;
@@ -1444,7 +1444,6 @@ static int rj54n1_probe(struct i2c_client *client,
1444 ret = rj54n1_video_probe(icd, client, rj54n1_priv); 1444 ret = rj54n1_video_probe(icd, client, rj54n1_priv);
1445 if (ret < 0) { 1445 if (ret < 0) {
1446 icd->ops = NULL; 1446 icd->ops = NULL;
1447 i2c_set_clientdata(client, NULL);
1448 kfree(rj54n1); 1447 kfree(rj54n1);
1449 return ret; 1448 return ret;
1450 } 1449 }
@@ -1461,7 +1460,6 @@ static int rj54n1_remove(struct i2c_client *client)
1461 icd->ops = NULL; 1460 icd->ops = NULL;
1462 if (icl->free_bus) 1461 if (icl->free_bus)
1463 icl->free_bus(icl); 1462 icl->free_bus(icl);
1464 i2c_set_clientdata(client, NULL);
1465 client->driver = NULL; 1463 client->driver = NULL;
1466 kfree(rj54n1); 1464 kfree(rj54n1);
1467 1465
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 53b6fcde3800..76da74368680 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1117,13 +1117,6 @@ static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
1117 return 0; 1117 return 0;
1118} 1118}
1119 1119
1120static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1121{
1122 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1123 return -EINVAL;
1124 return saa711x_g_sliced_fmt(sd, &fmt->fmt.sliced);
1125}
1126
1127static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt) 1120static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
1128{ 1121{
1129 saa711x_set_lcr(sd, NULL); 1122 saa711x_set_lcr(sd, NULL);
@@ -1136,12 +1129,13 @@ static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
1136 return 0; 1129 return 0;
1137} 1130}
1138 1131
1139static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 1132static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
1140{ 1133{
1141 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1134 if (fmt->code != V4L2_MBUS_FMT_FIXED)
1142 return -EINVAL; 1135 return -EINVAL;
1143 1136 fmt->field = V4L2_FIELD_INTERLACED;
1144 return saa711x_set_size(sd, fmt->fmt.pix.width, fmt->fmt.pix.height); 1137 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1138 return saa711x_set_size(sd, fmt->width, fmt->height);
1145} 1139}
1146 1140
1147/* Decode the sliced VBI data stream as created by the saa7115. 1141/* Decode the sliced VBI data stream as created by the saa7115.
@@ -1556,8 +1550,7 @@ static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
1556static const struct v4l2_subdev_video_ops saa711x_video_ops = { 1550static const struct v4l2_subdev_video_ops saa711x_video_ops = {
1557 .s_routing = saa711x_s_routing, 1551 .s_routing = saa711x_s_routing,
1558 .s_crystal_freq = saa711x_s_crystal_freq, 1552 .s_crystal_freq = saa711x_s_crystal_freq,
1559 .g_fmt = saa711x_g_fmt, 1553 .s_mbus_fmt = saa711x_s_mbus_fmt,
1560 .s_fmt = saa711x_s_fmt,
1561 .s_stream = saa711x_s_stream, 1554 .s_stream = saa711x_s_stream,
1562 .querystd = saa711x_querystd, 1555 .querystd = saa711x_querystd,
1563 .g_input_status = saa711x_g_input_status, 1556 .g_input_status = saa711x_g_input_status,
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 87986ad62f86..79fffcf39ba8 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -645,13 +645,6 @@ static int saa7127_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
645 return 0; 645 return 0;
646} 646}
647 647
648static int saa7127_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
649{
650 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
651 return -EINVAL;
652 return saa7127_g_sliced_fmt(sd, &fmt->fmt.sliced);
653}
654
655static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data) 648static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
656{ 649{
657 switch (data->id) { 650 switch (data->id) {
@@ -731,7 +724,6 @@ static const struct v4l2_subdev_core_ops saa7127_core_ops = {
731}; 724};
732 725
733static const struct v4l2_subdev_video_ops saa7127_video_ops = { 726static const struct v4l2_subdev_video_ops saa7127_video_ops = {
734 .g_fmt = saa7127_g_fmt,
735 .s_std_output = saa7127_s_std_output, 727 .s_std_output = saa7127_s_std_output,
736 .s_routing = saa7127_s_routing, 728 .s_routing = saa7127_s_routing,
737 .s_stream = saa7127_s_stream, 729 .s_stream = saa7127_s_stream,
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 1eabff6b2456..40fd31ca7716 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -846,24 +846,28 @@ static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_control
846 return 0; 846 return 0;
847} 847}
848 848
849static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 849static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
850{ 850{
851 struct saa6752hs_state *h = to_state(sd); 851 struct saa6752hs_state *h = to_state(sd);
852 852
853 if (h->video_format == SAA6752HS_VF_UNKNOWN) 853 if (h->video_format == SAA6752HS_VF_UNKNOWN)
854 h->video_format = SAA6752HS_VF_D1; 854 h->video_format = SAA6752HS_VF_D1;
855 f->fmt.pix.width = 855 f->width = v4l2_format_table[h->video_format].fmt.pix.width;
856 v4l2_format_table[h->video_format].fmt.pix.width; 856 f->height = v4l2_format_table[h->video_format].fmt.pix.height;
857 f->fmt.pix.height = 857 f->code = V4L2_MBUS_FMT_FIXED;
858 v4l2_format_table[h->video_format].fmt.pix.height; 858 f->field = V4L2_FIELD_INTERLACED;
859 f->colorspace = V4L2_COLORSPACE_SMPTE170M;
859 return 0; 860 return 0;
860} 861}
861 862
862static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 863static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
863{ 864{
864 struct saa6752hs_state *h = to_state(sd); 865 struct saa6752hs_state *h = to_state(sd);
865 int dist_352, dist_480, dist_720; 866 int dist_352, dist_480, dist_720;
866 867
868 if (f->code != V4L2_MBUS_FMT_FIXED)
869 return -EINVAL;
870
867 /* 871 /*
868 FIXME: translate and round width/height into EMPRESS 872 FIXME: translate and round width/height into EMPRESS
869 subsample type: 873 subsample type:
@@ -876,28 +880,30 @@ static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
876 D1 | 720x576 | 720x480 880 D1 | 720x576 | 720x480
877 */ 881 */
878 882
879 dist_352 = abs(f->fmt.pix.width - 352); 883 dist_352 = abs(f->width - 352);
880 dist_480 = abs(f->fmt.pix.width - 480); 884 dist_480 = abs(f->width - 480);
881 dist_720 = abs(f->fmt.pix.width - 720); 885 dist_720 = abs(f->width - 720);
882 if (dist_720 < dist_480) { 886 if (dist_720 < dist_480) {
883 f->fmt.pix.width = 720; 887 f->width = 720;
884 f->fmt.pix.height = 576; 888 f->height = 576;
885 h->video_format = SAA6752HS_VF_D1; 889 h->video_format = SAA6752HS_VF_D1;
886 } else if (dist_480 < dist_352) { 890 } else if (dist_480 < dist_352) {
887 f->fmt.pix.width = 480; 891 f->width = 480;
888 f->fmt.pix.height = 576; 892 f->height = 576;
889 h->video_format = SAA6752HS_VF_2_3_D1; 893 h->video_format = SAA6752HS_VF_2_3_D1;
890 } else { 894 } else {
891 f->fmt.pix.width = 352; 895 f->width = 352;
892 if (abs(f->fmt.pix.height - 576) < 896 if (abs(f->height - 576) <
893 abs(f->fmt.pix.height - 288)) { 897 abs(f->height - 288)) {
894 f->fmt.pix.height = 576; 898 f->height = 576;
895 h->video_format = SAA6752HS_VF_1_2_D1; 899 h->video_format = SAA6752HS_VF_1_2_D1;
896 } else { 900 } else {
897 f->fmt.pix.height = 288; 901 f->height = 288;
898 h->video_format = SAA6752HS_VF_SIF; 902 h->video_format = SAA6752HS_VF_SIF;
899 } 903 }
900 } 904 }
905 f->field = V4L2_FIELD_INTERLACED;
906 f->colorspace = V4L2_COLORSPACE_SMPTE170M;
901 return 0; 907 return 0;
902} 908}
903 909
@@ -932,8 +938,8 @@ static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
932}; 938};
933 939
934static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { 940static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
935 .s_fmt = saa6752hs_s_fmt, 941 .s_mbus_fmt = saa6752hs_s_mbus_fmt,
936 .g_fmt = saa6752hs_g_fmt, 942 .g_mbus_fmt = saa6752hs_g_mbus_fmt,
937}; 943};
938 944
939static const struct v4l2_subdev_ops saa6752hs_ops = { 945static const struct v4l2_subdev_ops saa6752hs_ops = {
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 72700d4e3941..07f6bb8ef9d9 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -3897,6 +3897,40 @@ struct saa7134_board saa7134_boards[] = {
3897 .gpio = 0x01, 3897 .gpio = 0x01,
3898 }, 3898 },
3899 }, 3899 },
3900 [SAA7134_BOARD_AVERMEDIA_M733A] = {
3901 .name = "Avermedia PCI M733A",
3902 .audio_clock = 0x00187de7,
3903 .tuner_type = TUNER_PHILIPS_TDA8290,
3904 .radio_type = UNSET,
3905 .tuner_addr = ADDR_UNSET,
3906 .radio_addr = ADDR_UNSET,
3907 .tuner_config = 0,
3908 .gpiomask = 0x020200000,
3909 .inputs = {{
3910 .name = name_tv,
3911 .vmux = 1,
3912 .amux = TV,
3913 .tv = 1,
3914 }, {
3915 .name = name_comp1,
3916 .vmux = 3,
3917 .amux = LINE1,
3918 }, {
3919 .name = name_svideo,
3920 .vmux = 8,
3921 .amux = LINE1,
3922 } },
3923 .radio = {
3924 .name = name_radio,
3925 .amux = TV,
3926 .gpio = 0x00200000,
3927 },
3928 .mute = {
3929 .name = name_mute,
3930 .amux = TV,
3931 .gpio = 0x01,
3932 },
3933 },
3900 [SAA7134_BOARD_BEHOLD_401] = { 3934 [SAA7134_BOARD_BEHOLD_401] = {
3901 /* Beholder Intl. Ltd. 2008 */ 3935 /* Beholder Intl. Ltd. 2008 */
3902 /*Dmitry Belimov <d.belimov@gmail.com> */ 3936 /*Dmitry Belimov <d.belimov@gmail.com> */
@@ -5822,6 +5856,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
5822 .driver_data = SAA7134_BOARD_AVERMEDIA_M135A, 5856 .driver_data = SAA7134_BOARD_AVERMEDIA_M135A,
5823 }, { 5857 }, {
5824 .vendor = PCI_VENDOR_ID_PHILIPS, 5858 .vendor = PCI_VENDOR_ID_PHILIPS,
5859 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5860 .subvendor = 0x1461, /* Avermedia Technologies Inc */
5861 .subdevice = 0x4155,
5862 .driver_data = SAA7134_BOARD_AVERMEDIA_M733A,
5863 }, {
5864 .vendor = PCI_VENDOR_ID_PHILIPS,
5865 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5866 .subvendor = 0x1461, /* Avermedia Technologies Inc */
5867 .subdevice = 0x4255,
5868 .driver_data = SAA7134_BOARD_AVERMEDIA_M733A,
5869 }, {
5870 .vendor = PCI_VENDOR_ID_PHILIPS,
5825 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 5871 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
5826 .subvendor = PCI_VENDOR_ID_PHILIPS, 5872 .subvendor = PCI_VENDOR_ID_PHILIPS,
5827 .subdevice = 0x2004, 5873 .subdevice = 0x2004,
@@ -6786,6 +6832,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
6786 switch (dev->board) { 6832 switch (dev->board) {
6787 case SAA7134_BOARD_HAUPPAUGE_HVR1150: 6833 case SAA7134_BOARD_HAUPPAUGE_HVR1150:
6788 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 6834 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
6835 case SAA7134_BOARD_AVERMEDIA_M733A:
6789 /* tda8290 + tda18271 */ 6836 /* tda8290 + tda18271 */
6790 ret = saa7134_tda8290_18271_callback(dev, command, arg); 6837 ret = saa7134_tda8290_18271_callback(dev, command, arg);
6791 break; 6838 break;
@@ -7087,6 +7134,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7087 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0000C000, 0x0000C000); 7134 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0000C000, 0x0000C000);
7088 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000C000, 0x0000C000); 7135 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000C000, 0x0000C000);
7089 break; 7136 break;
7137 case SAA7134_BOARD_AVERMEDIA_M733A:
7138 saa7134_set_gpio(dev, 1, 1);
7139 msleep(10);
7140 saa7134_set_gpio(dev, 1, 0);
7141 msleep(10);
7142 saa7134_set_gpio(dev, 1, 1);
7143 dev->has_remote = SAA7134_REMOTE_GPIO;
7144 break;
7090 } 7145 }
7091 return 0; 7146 return 0;
7092} 7147}
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index ea877a50f52d..e763f9fd0133 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -223,9 +223,11 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv,
223 struct v4l2_format *f) 223 struct v4l2_format *f)
224{ 224{
225 struct saa7134_dev *dev = file->private_data; 225 struct saa7134_dev *dev = file->private_data;
226 struct v4l2_mbus_framefmt mbus_fmt;
226 227
227 saa_call_all(dev, video, g_fmt, f); 228 saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt);
228 229
230 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
229 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 231 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
230 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; 232 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
231 233
@@ -236,8 +238,11 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
236 struct v4l2_format *f) 238 struct v4l2_format *f)
237{ 239{
238 struct saa7134_dev *dev = file->private_data; 240 struct saa7134_dev *dev = file->private_data;
241 struct v4l2_mbus_framefmt mbus_fmt;
239 242
240 saa_call_all(dev, video, s_fmt, f); 243 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
244 saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
245 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
241 246
242 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 247 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
243 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; 248 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index e5565e2fd426..0b336ca6d55b 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -141,8 +141,8 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
141 struct saa7134_dev *dev = ir->c->adapter->algo_data; 141 struct saa7134_dev *dev = ir->c->adapter->algo_data;
142 142
143 if (dev == NULL) { 143 if (dev == NULL) {
144 dprintk("get_key_flydvb_trio: " 144 i2cdprintk("get_key_flydvb_trio: "
145 "gir->c->adapter->algo_data is NULL!\n"); 145 "ir->c->adapter->algo_data is NULL!\n");
146 return -EIO; 146 return -EIO;
147 } 147 }
148 148
@@ -195,8 +195,8 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
195 /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ 195 /* <dev> is needed to access GPIO. Used by the saa_readl macro. */
196 struct saa7134_dev *dev = ir->c->adapter->algo_data; 196 struct saa7134_dev *dev = ir->c->adapter->algo_data;
197 if (dev == NULL) { 197 if (dev == NULL) {
198 dprintk("get_key_msi_tvanywhere_plus: " 198 i2cdprintk("get_key_msi_tvanywhere_plus: "
199 "gir->c->adapter->algo_data is NULL!\n"); 199 "ir->c->adapter->algo_data is NULL!\n");
200 return -EIO; 200 return -EIO;
201 } 201 }
202 202
@@ -657,12 +657,19 @@ int saa7134_input_init1(struct saa7134_dev *dev)
657 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); 657 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
658 break; 658 break;
659 case SAA7134_BOARD_AVERMEDIA_M135A: 659 case SAA7134_BOARD_AVERMEDIA_M135A:
660 ir_codes = RC_MAP_AVERMEDIA_M135A_RM_JX; 660 ir_codes = RC_MAP_AVERMEDIA_M135A;
661 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ 661 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
662 mask_keyup = 0x0040000; 662 mask_keyup = 0x0040000;
663 mask_keycode = 0xffff; 663 mask_keycode = 0xffff;
664 raw_decode = 1; 664 raw_decode = 1;
665 break; 665 break;
666 case SAA7134_BOARD_AVERMEDIA_M733A:
667 ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6;
668 mask_keydown = 0x0040000;
669 mask_keyup = 0x0040000;
670 mask_keycode = 0xffff;
671 raw_decode = 1;
672 break;
666 case SAA7134_BOARD_AVERMEDIA_777: 673 case SAA7134_BOARD_AVERMEDIA_777:
667 case SAA7134_BOARD_AVERMEDIA_A16AR: 674 case SAA7134_BOARD_AVERMEDIA_A16AR:
668 ir_codes = RC_MAP_AVERMEDIA; 675 ir_codes = RC_MAP_AVERMEDIA;
@@ -815,7 +822,6 @@ int saa7134_input_init1(struct saa7134_dev *dev)
815 mask_keyup = 0x020000; 822 mask_keyup = 0x020000;
816 polling = 50; /* ms */ 823 polling = 50; /* ms */
817 break; 824 break;
818 break;
819 } 825 }
820 if (NULL == ir_codes) { 826 if (NULL == ir_codes) {
821 printk("%s: Oops: IR config error [card=%d]\n", 827 printk("%s: Oops: IR config error [card=%d]\n",
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 3962534267be..756a1ca8833d 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -303,6 +303,7 @@ struct saa7134_format {
303#define SAA7134_BOARD_HAWELL_HW_404M7 177 303#define SAA7134_BOARD_HAWELL_HW_404M7 177
304#define SAA7134_BOARD_BEHOLD_H7 178 304#define SAA7134_BOARD_BEHOLD_H7 178
305#define SAA7134_BOARD_BEHOLD_A7 179 305#define SAA7134_BOARD_BEHOLD_A7 179
306#define SAA7134_BOARD_AVERMEDIA_M733A 180
306 307
307#define SAA7134_MAXBOARDS 32 308#define SAA7134_MAXBOARDS 32
308#define SAA7134_INPUT_MAX 8 309#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index d521c648e157..78d69950c00a 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -1199,28 +1199,32 @@ static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
1199} 1199}
1200#endif 1200#endif
1201 1201
1202static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 1202static int saa717x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
1203{ 1203{
1204 struct v4l2_pix_format *pix;
1205 int prescale, h_scale, v_scale; 1204 int prescale, h_scale, v_scale;
1206 1205
1207 pix = &fmt->fmt.pix;
1208 v4l2_dbg(1, debug, sd, "decoder set size\n"); 1206 v4l2_dbg(1, debug, sd, "decoder set size\n");
1209 1207
1208 if (fmt->code != V4L2_MBUS_FMT_FIXED)
1209 return -EINVAL;
1210
1210 /* FIXME need better bounds checking here */ 1211 /* FIXME need better bounds checking here */
1211 if (pix->width < 1 || pix->width > 1440) 1212 if (fmt->width < 1 || fmt->width > 1440)
1212 return -EINVAL; 1213 return -EINVAL;
1213 if (pix->height < 1 || pix->height > 960) 1214 if (fmt->height < 1 || fmt->height > 960)
1214 return -EINVAL; 1215 return -EINVAL;
1215 1216
1217 fmt->field = V4L2_FIELD_INTERLACED;
1218 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1219
1216 /* scaling setting */ 1220 /* scaling setting */
1217 /* NTSC and interlace only */ 1221 /* NTSC and interlace only */
1218 prescale = SAA717X_NTSC_WIDTH / pix->width; 1222 prescale = SAA717X_NTSC_WIDTH / fmt->width;
1219 if (prescale == 0) 1223 if (prescale == 0)
1220 prescale = 1; 1224 prescale = 1;
1221 h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width; 1225 h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width;
1222 /* interlace */ 1226 /* interlace */
1223 v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height; 1227 v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height;
1224 1228
1225 /* Horizontal prescaling etc */ 1229 /* Horizontal prescaling etc */
1226 set_h_prescale(sd, 0, prescale); 1230 set_h_prescale(sd, 0, prescale);
@@ -1241,19 +1245,19 @@ static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1241 /* set video output size */ 1245 /* set video output size */
1242 /* video number of pixels at output */ 1246 /* video number of pixels at output */
1243 /* TASK A */ 1247 /* TASK A */
1244 saa717x_write(sd, 0x5C, (u8)(pix->width & 0xFF)); 1248 saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF));
1245 saa717x_write(sd, 0x5D, (u8)((pix->width >> 8) & 0xFF)); 1249 saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF));
1246 /* TASK B */ 1250 /* TASK B */
1247 saa717x_write(sd, 0x9C, (u8)(pix->width & 0xFF)); 1251 saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF));
1248 saa717x_write(sd, 0x9D, (u8)((pix->width >> 8) & 0xFF)); 1252 saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF));
1249 1253
1250 /* video number of lines at output */ 1254 /* video number of lines at output */
1251 /* TASK A */ 1255 /* TASK A */
1252 saa717x_write(sd, 0x5E, (u8)(pix->height & 0xFF)); 1256 saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF));
1253 saa717x_write(sd, 0x5F, (u8)((pix->height >> 8) & 0xFF)); 1257 saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF));
1254 /* TASK B */ 1258 /* TASK B */
1255 saa717x_write(sd, 0x9E, (u8)(pix->height & 0xFF)); 1259 saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF));
1256 saa717x_write(sd, 0x9F, (u8)((pix->height >> 8) & 0xFF)); 1260 saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF));
1257 return 0; 1261 return 0;
1258} 1262}
1259 1263
@@ -1403,7 +1407,7 @@ static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
1403 1407
1404static const struct v4l2_subdev_video_ops saa717x_video_ops = { 1408static const struct v4l2_subdev_video_ops saa717x_video_ops = {
1405 .s_routing = saa717x_s_video_routing, 1409 .s_routing = saa717x_s_video_routing,
1406 .s_fmt = saa717x_s_fmt, 1410 .s_mbus_fmt = saa717x_s_mbus_fmt,
1407 .s_stream = saa717x_s_stream, 1411 .s_stream = saa717x_s_stream,
1408}; 1412};
1409 1413
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 4ac3b482fbb4..961bfa2fea97 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -878,7 +878,7 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
878 878
879static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); 879static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
880 880
881static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, 881static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx,
882 struct soc_camera_format_xlate *xlate) 882 struct soc_camera_format_xlate *xlate)
883{ 883{
884 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 884 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -897,7 +897,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
897 fmt = soc_mbus_get_fmtdesc(code); 897 fmt = soc_mbus_get_fmtdesc(code);
898 if (!fmt) { 898 if (!fmt) {
899 dev_err(icd->dev.parent, 899 dev_err(icd->dev.parent,
900 "Invalid format code #%d: %d\n", idx, code); 900 "Invalid format code #%u: %d\n", idx, code);
901 return -EINVAL; 901 return -EINVAL;
902 } 902 }
903 903
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 522ba3f4c285..b6643ca7656a 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -62,8 +62,8 @@ static const struct usb_device_id sn9c102_id_table[] = {
62#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE 62#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
63 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, 63 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
64/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */ 64/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
65#endif
66 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, 65 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
66#endif
67 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, 67 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
68 /* SN9C103 */ 68 /* SN9C103 */
69 { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, 69 { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), },
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index db1ca0e90d76..475757bfd7ba 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -200,7 +200,8 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
200{ 200{
201 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 201 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
202 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 202 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
203 int i, fmts = 0, raw_fmts = 0, ret; 203 unsigned int i, fmts = 0, raw_fmts = 0;
204 int ret;
204 enum v4l2_mbus_pixelcode code; 205 enum v4l2_mbus_pixelcode code;
205 206
206 while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) 207 while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code))
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index 10b003a8be83..248c986f0989 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -71,7 +71,7 @@ static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd,
71 71
72static struct v4l2_subdev_core_ops platform_subdev_core_ops; 72static struct v4l2_subdev_core_ops platform_subdev_core_ops;
73 73
74static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, int index, 74static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
75 enum v4l2_mbus_pixelcode *code) 75 enum v4l2_mbus_pixelcode *code)
76{ 76{
77 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); 77 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index b90e9da3167d..54681a535822 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -850,7 +850,6 @@ static int tcm825x_probe(struct i2c_client *client,
850 const struct i2c_device_id *did) 850 const struct i2c_device_id *did)
851{ 851{
852 struct tcm825x_sensor *sensor = &tcm825x; 852 struct tcm825x_sensor *sensor = &tcm825x;
853 int rval;
854 853
855 if (i2c_get_clientdata(client)) 854 if (i2c_get_clientdata(client))
856 return -EBUSY; 855 return -EBUSY;
@@ -871,11 +870,7 @@ static int tcm825x_probe(struct i2c_client *client,
871 sensor->pix.height = tcm825x_sizes[QVGA].height; 870 sensor->pix.height = tcm825x_sizes[QVGA].height;
872 sensor->pix.pixelformat = V4L2_PIX_FMT_RGB565; 871 sensor->pix.pixelformat = V4L2_PIX_FMT_RGB565;
873 872
874 rval = v4l2_int_device_register(sensor->v4l2_int_device); 873 return v4l2_int_device_register(sensor->v4l2_int_device);
875 if (rval)
876 i2c_set_clientdata(client, NULL);
877
878 return rval;
879} 874}
880 875
881static int tcm825x_remove(struct i2c_client *client) 876static int tcm825x_remove(struct i2c_client *client)
@@ -886,7 +881,6 @@ static int tcm825x_remove(struct i2c_client *client)
886 return -ENODEV; /* our client isn't attached */ 881 return -ENODEV; /* our client isn't attached */
887 882
888 v4l2_int_device_unregister(sensor->v4l2_int_device); 883 v4l2_int_device_unregister(sensor->v4l2_int_device);
889 i2c_set_clientdata(client, NULL);
890 884
891 return 0; 885 return 0;
892} 886}
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index e826114b7fb8..71c73fa0d68c 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -88,9 +88,6 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
88 * @pdata: Board specific 88 * @pdata: Board specific
89 * @ver: Chip version 89 * @ver: Chip version
90 * @streaming: TVP5146/47 decoder streaming - enabled or disabled. 90 * @streaming: TVP5146/47 decoder streaming - enabled or disabled.
91 * @pix: Current pixel format
92 * @num_fmts: Number of formats
93 * @fmt_list: Format list
94 * @current_std: Current standard 91 * @current_std: Current standard
95 * @num_stds: Number of standards 92 * @num_stds: Number of standards
96 * @std_list: Standards list 93 * @std_list: Standards list
@@ -105,13 +102,9 @@ struct tvp514x_decoder {
105 int ver; 102 int ver;
106 int streaming; 103 int streaming;
107 104
108 struct v4l2_pix_format pix;
109 int num_fmts;
110 const struct v4l2_fmtdesc *fmt_list;
111
112 enum tvp514x_std current_std; 105 enum tvp514x_std current_std;
113 int num_stds; 106 int num_stds;
114 struct tvp514x_std_info *std_list; 107 const struct tvp514x_std_info *std_list;
115 /* Input and Output Routing parameters */ 108 /* Input and Output Routing parameters */
116 u32 input; 109 u32 input;
117 u32 output; 110 u32 output;
@@ -203,27 +196,12 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = {
203}; 196};
204 197
205/** 198/**
206 * List of image formats supported by TVP5146/47 decoder
207 * Currently we are using 8 bit mode only, but can be
208 * extended to 10/20 bit mode.
209 */
210static const struct v4l2_fmtdesc tvp514x_fmt_list[] = {
211 {
212 .index = 0,
213 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
214 .flags = 0,
215 .description = "8-bit UYVY 4:2:2 Format",
216 .pixelformat = V4L2_PIX_FMT_UYVY,
217 },
218};
219
220/**
221 * Supported standards - 199 * Supported standards -
222 * 200 *
223 * Currently supports two standards only, need to add support for rest of the 201 * Currently supports two standards only, need to add support for rest of the
224 * modes, like SECAM, etc... 202 * modes, like SECAM, etc...
225 */ 203 */
226static struct tvp514x_std_info tvp514x_std_list[] = { 204static const struct tvp514x_std_info tvp514x_std_list[] = {
227 /* Standard: STD_NTSC_MJ */ 205 /* Standard: STD_NTSC_MJ */
228 [STD_NTSC_MJ] = { 206 [STD_NTSC_MJ] = {
229 .width = NTSC_NUM_ACTIVE_PIXELS, 207 .width = NTSC_NUM_ACTIVE_PIXELS,
@@ -366,13 +344,13 @@ static int tvp514x_write_regs(struct v4l2_subdev *sd,
366} 344}
367 345
368/** 346/**
369 * tvp514x_get_current_std() : Get the current standard detected by TVP5146/47 347 * tvp514x_query_current_std() : Query the current standard detected by TVP5146/47
370 * @sd: ptr to v4l2_subdev struct 348 * @sd: ptr to v4l2_subdev struct
371 * 349 *
372 * Get current standard detected by TVP5146/47, STD_INVALID if there is no 350 * Returns the current standard detected by TVP5146/47, STD_INVALID if there is no
373 * standard detected. 351 * standard detected.
374 */ 352 */
375static enum tvp514x_std tvp514x_get_current_std(struct v4l2_subdev *sd) 353static enum tvp514x_std tvp514x_query_current_std(struct v4l2_subdev *sd)
376{ 354{
377 u8 std, std_status; 355 u8 std, std_status;
378 356
@@ -518,7 +496,7 @@ static int tvp514x_detect(struct v4l2_subdev *sd,
518 * @std_id: standard V4L2 std_id ioctl enum 496 * @std_id: standard V4L2 std_id ioctl enum
519 * 497 *
520 * Returns the current standard detected by TVP5146/47. If no active input is 498 * Returns the current standard detected by TVP5146/47. If no active input is
521 * detected, returns -EINVAL 499 * detected then *std_id is set to 0 and the function returns 0.
522 */ 500 */
523static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) 501static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
524{ 502{
@@ -530,10 +508,12 @@ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
530 if (std_id == NULL) 508 if (std_id == NULL)
531 return -EINVAL; 509 return -EINVAL;
532 510
533 /* get the current standard */ 511 *std_id = V4L2_STD_UNKNOWN;
534 current_std = tvp514x_get_current_std(sd); 512
513 /* query the current standard */
514 current_std = tvp514x_query_current_std(sd);
535 if (current_std == STD_INVALID) 515 if (current_std == STD_INVALID)
536 return -EINVAL; 516 return 0;
537 517
538 input_sel = decoder->input; 518 input_sel = decoder->input;
539 519
@@ -575,12 +555,11 @@ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
575 /* check whether signal is locked */ 555 /* check whether signal is locked */
576 sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1); 556 sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
577 if (lock_mask != (sync_lock_status & lock_mask)) 557 if (lock_mask != (sync_lock_status & lock_mask))
578 return -EINVAL; /* No input detected */ 558 return 0; /* No input detected */
579 559
580 decoder->current_std = current_std;
581 *std_id = decoder->std_list[current_std].standard.id; 560 *std_id = decoder->std_list[current_std].standard.id;
582 561
583 v4l2_dbg(1, debug, sd, "Current STD: %s", 562 v4l2_dbg(1, debug, sd, "Current STD: %s\n",
584 decoder->std_list[current_std].standard.name); 563 decoder->std_list[current_std].standard.name);
585 return 0; 564 return 0;
586} 565}
@@ -614,7 +593,7 @@ static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id)
614 decoder->tvp514x_regs[REG_VIDEO_STD].val = 593 decoder->tvp514x_regs[REG_VIDEO_STD].val =
615 decoder->std_list[i].video_std; 594 decoder->std_list[i].video_std;
616 595
617 v4l2_dbg(1, debug, sd, "Standard set to: %s", 596 v4l2_dbg(1, debug, sd, "Standard set to: %s\n",
618 decoder->std_list[i].standard.name); 597 decoder->std_list[i].standard.name);
619 return 0; 598 return 0;
620} 599}
@@ -637,7 +616,6 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
637 int err; 616 int err;
638 enum tvp514x_input input_sel; 617 enum tvp514x_input input_sel;
639 enum tvp514x_output output_sel; 618 enum tvp514x_output output_sel;
640 enum tvp514x_std current_std = STD_INVALID;
641 u8 sync_lock_status, lock_mask; 619 u8 sync_lock_status, lock_mask;
642 int try_count = LOCK_RETRY_COUNT; 620 int try_count = LOCK_RETRY_COUNT;
643 621
@@ -721,11 +699,6 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
721 /* Allow decoder to sync up with new input */ 699 /* Allow decoder to sync up with new input */
722 msleep(LOCK_RETRY_DELAY); 700 msleep(LOCK_RETRY_DELAY);
723 701
724 /* get the current standard for future reference */
725 current_std = tvp514x_get_current_std(sd);
726 if (current_std == STD_INVALID)
727 continue;
728
729 sync_lock_status = tvp514x_read_reg(sd, 702 sync_lock_status = tvp514x_read_reg(sd,
730 REG_STATUS1); 703 REG_STATUS1);
731 if (lock_mask == (sync_lock_status & lock_mask)) 704 if (lock_mask == (sync_lock_status & lock_mask))
@@ -733,15 +706,13 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
733 break; 706 break;
734 } 707 }
735 708
736 if ((current_std == STD_INVALID) || (try_count < 0)) 709 if (try_count < 0)
737 return -EINVAL; 710 return -EINVAL;
738 711
739 decoder->current_std = current_std;
740 decoder->input = input; 712 decoder->input = input;
741 decoder->output = output; 713 decoder->output = output;
742 714
743 v4l2_dbg(1, debug, sd, "Input set to: %d, std : %d", 715 v4l2_dbg(1, debug, sd, "Input set to: %d\n", input_sel);
744 input_sel, current_std);
745 716
746 return 0; 717 return 0;
747} 718}
@@ -794,7 +765,7 @@ tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
794 return err; 765 return err;
795 } 766 }
796 767
797 v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d", 768 v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d\n",
798 qctrl->name, qctrl->minimum, qctrl->maximum, 769 qctrl->name, qctrl->minimum, qctrl->maximum,
799 qctrl->default_value); 770 qctrl->default_value);
800 771
@@ -851,7 +822,7 @@ tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
851 return -EINVAL; 822 return -EINVAL;
852 } 823 }
853 824
854 v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d", 825 v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d\n",
855 ctrl->id, ctrl->value); 826 ctrl->id, ctrl->value);
856 return 0; 827 return 0;
857} 828}
@@ -951,7 +922,7 @@ tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
951 return err; 922 return err;
952 } 923 }
953 924
954 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d", 925 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n",
955 ctrl->id, ctrl->value); 926 ctrl->id, ctrl->value);
956 927
957 return err; 928 return err;
@@ -967,44 +938,33 @@ tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
967static int 938static int
968tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) 939tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
969{ 940{
970 struct tvp514x_decoder *decoder = to_decoder(sd); 941 if (fmt == NULL || fmt->index)
971 int index;
972
973 if (fmt == NULL)
974 return -EINVAL;
975
976 index = fmt->index;
977 if ((index >= decoder->num_fmts) || (index < 0))
978 /* Index out of bound */
979 return -EINVAL; 942 return -EINVAL;
980 943
981 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 944 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
982 /* only capture is supported */ 945 /* only capture is supported */
983 return -EINVAL; 946 return -EINVAL;
984 947
985 memcpy(fmt, &decoder->fmt_list[index], 948 /* only one format */
986 sizeof(struct v4l2_fmtdesc)); 949 fmt->flags = 0;
987 950 strlcpy(fmt->description, "8-bit UYVY 4:2:2 Format",
988 v4l2_dbg(1, debug, sd, "Current FMT: index - %d (%s)", 951 sizeof(fmt->description));
989 decoder->fmt_list[index].index, 952 fmt->pixelformat = V4L2_PIX_FMT_UYVY;
990 decoder->fmt_list[index].description);
991 return 0; 953 return 0;
992} 954}
993 955
994/** 956/**
995 * tvp514x_try_fmt_cap() - V4L2 decoder interface handler for try_fmt 957 * tvp514x_fmt_cap() - V4L2 decoder interface handler for try/s/g_fmt
996 * @sd: pointer to standard V4L2 sub-device structure 958 * @sd: pointer to standard V4L2 sub-device structure
997 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure 959 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
998 * 960 *
999 * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This 961 * Implement the VIDIOC_TRY/S/G_FMT ioctl for the CAPTURE buffer type. This
1000 * ioctl is used to negotiate the image capture size and pixel format 962 * ioctl is used to negotiate the image capture size and pixel format.
1001 * without actually making it take effect.
1002 */ 963 */
1003static int 964static int
1004tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) 965tvp514x_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
1005{ 966{
1006 struct tvp514x_decoder *decoder = to_decoder(sd); 967 struct tvp514x_decoder *decoder = to_decoder(sd);
1007 int ifmt;
1008 struct v4l2_pix_format *pix; 968 struct v4l2_pix_format *pix;
1009 enum tvp514x_std current_std; 969 enum tvp514x_std current_std;
1010 970
@@ -1012,106 +972,30 @@ tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
1012 return -EINVAL; 972 return -EINVAL;
1013 973
1014 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 974 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1015 /* only capture is supported */ 975 return -EINVAL;
1016 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1017 976
1018 pix = &f->fmt.pix; 977 pix = &f->fmt.pix;
1019 978
1020 /* Calculate height and width based on current standard */ 979 /* Calculate height and width based on current standard */
1021 current_std = tvp514x_get_current_std(sd); 980 current_std = decoder->current_std;
1022 if (current_std == STD_INVALID)
1023 return -EINVAL;
1024 981
1025 decoder->current_std = current_std; 982 pix->pixelformat = V4L2_PIX_FMT_UYVY;
1026 pix->width = decoder->std_list[current_std].width; 983 pix->width = decoder->std_list[current_std].width;
1027 pix->height = decoder->std_list[current_std].height; 984 pix->height = decoder->std_list[current_std].height;
1028
1029 for (ifmt = 0; ifmt < decoder->num_fmts; ifmt++) {
1030 if (pix->pixelformat ==
1031 decoder->fmt_list[ifmt].pixelformat)
1032 break;
1033 }
1034 if (ifmt == decoder->num_fmts)
1035 /* None of the format matched, select default */
1036 ifmt = 0;
1037 pix->pixelformat = decoder->fmt_list[ifmt].pixelformat;
1038
1039 pix->field = V4L2_FIELD_INTERLACED; 985 pix->field = V4L2_FIELD_INTERLACED;
1040 pix->bytesperline = pix->width * 2; 986 pix->bytesperline = pix->width * 2;
1041 pix->sizeimage = pix->bytesperline * pix->height; 987 pix->sizeimage = pix->bytesperline * pix->height;
1042 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 988 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1043 pix->priv = 0; 989 pix->priv = 0;
1044 990
1045 v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d" 991 v4l2_dbg(1, debug, sd, "FMT: bytesperline - %d"
1046 "Width - %d, Height - %d", 992 "Width - %d, Height - %d\n",
1047 decoder->fmt_list[ifmt].description, pix->bytesperline, 993 pix->bytesperline,
1048 pix->width, pix->height); 994 pix->width, pix->height);
1049 return 0; 995 return 0;
1050} 996}
1051 997
1052/** 998/**
1053 * tvp514x_s_fmt_cap() - V4L2 decoder interface handler for s_fmt
1054 * @sd: pointer to standard V4L2 sub-device structure
1055 * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
1056 *
1057 * If the requested format is supported, configures the HW to use that
1058 * format, returns error code if format not supported or HW can't be
1059 * correctly configured.
1060 */
1061static int
1062tvp514x_s_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
1063{
1064 struct tvp514x_decoder *decoder = to_decoder(sd);
1065 struct v4l2_pix_format *pix;
1066 int rval;
1067
1068 if (f == NULL)
1069 return -EINVAL;
1070
1071 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1072 /* only capture is supported */
1073 return -EINVAL;
1074
1075 pix = &f->fmt.pix;
1076 rval = tvp514x_try_fmt_cap(sd, f);
1077 if (rval)
1078 return rval;
1079
1080 decoder->pix = *pix;
1081
1082 return rval;
1083}
1084
1085/**
1086 * tvp514x_g_fmt_cap() - V4L2 decoder interface handler for tvp514x_g_fmt_cap
1087 * @sd: pointer to standard V4L2 sub-device structure
1088 * @f: pointer to standard V4L2 v4l2_format structure
1089 *
1090 * Returns the decoder's current pixel format in the v4l2_format
1091 * parameter.
1092 */
1093static int
1094tvp514x_g_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
1095{
1096 struct tvp514x_decoder *decoder = to_decoder(sd);
1097
1098 if (f == NULL)
1099 return -EINVAL;
1100
1101 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1102 /* only capture is supported */
1103 return -EINVAL;
1104
1105 f->fmt.pix = decoder->pix;
1106
1107 v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d"
1108 "Width - %d, Height - %d",
1109 decoder->pix.bytesperline,
1110 decoder->pix.width, decoder->pix.height);
1111 return 0;
1112}
1113
1114/**
1115 * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm 999 * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm
1116 * @sd: pointer to standard V4L2 sub-device structure 1000 * @sd: pointer to standard V4L2 sub-device structure
1117 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure 1001 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
@@ -1132,15 +1016,8 @@ tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
1132 /* only capture is supported */ 1016 /* only capture is supported */
1133 return -EINVAL; 1017 return -EINVAL;
1134 1018
1135 memset(a, 0, sizeof(*a));
1136 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1137
1138 /* get the current standard */ 1019 /* get the current standard */
1139 current_std = tvp514x_get_current_std(sd); 1020 current_std = decoder->current_std;
1140 if (current_std == STD_INVALID)
1141 return -EINVAL;
1142
1143 decoder->current_std = current_std;
1144 1021
1145 cparm = &a->parm.capture; 1022 cparm = &a->parm.capture;
1146 cparm->capability = V4L2_CAP_TIMEPERFRAME; 1023 cparm->capability = V4L2_CAP_TIMEPERFRAME;
@@ -1175,11 +1052,7 @@ tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
1175 timeperframe = &a->parm.capture.timeperframe; 1052 timeperframe = &a->parm.capture.timeperframe;
1176 1053
1177 /* get the current standard */ 1054 /* get the current standard */
1178 current_std = tvp514x_get_current_std(sd); 1055 current_std = decoder->current_std;
1179 if (current_std == STD_INVALID)
1180 return -EINVAL;
1181
1182 decoder->current_std = current_std;
1183 1056
1184 *timeperframe = 1057 *timeperframe =
1185 decoder->std_list[current_std].standard.frameperiod; 1058 decoder->std_list[current_std].standard.frameperiod;
@@ -1259,9 +1132,9 @@ static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
1259 .s_routing = tvp514x_s_routing, 1132 .s_routing = tvp514x_s_routing,
1260 .querystd = tvp514x_querystd, 1133 .querystd = tvp514x_querystd,
1261 .enum_fmt = tvp514x_enum_fmt_cap, 1134 .enum_fmt = tvp514x_enum_fmt_cap,
1262 .g_fmt = tvp514x_g_fmt_cap, 1135 .g_fmt = tvp514x_fmt_cap,
1263 .try_fmt = tvp514x_try_fmt_cap, 1136 .try_fmt = tvp514x_fmt_cap,
1264 .s_fmt = tvp514x_s_fmt_cap, 1137 .s_fmt = tvp514x_fmt_cap,
1265 .g_parm = tvp514x_g_parm, 1138 .g_parm = tvp514x_g_parm,
1266 .s_parm = tvp514x_s_parm, 1139 .s_parm = tvp514x_s_parm,
1267 .s_stream = tvp514x_s_stream, 1140 .s_stream = tvp514x_s_stream,
@@ -1274,22 +1147,6 @@ static const struct v4l2_subdev_ops tvp514x_ops = {
1274 1147
1275static struct tvp514x_decoder tvp514x_dev = { 1148static struct tvp514x_decoder tvp514x_dev = {
1276 .streaming = 0, 1149 .streaming = 0,
1277
1278 .fmt_list = tvp514x_fmt_list,
1279 .num_fmts = ARRAY_SIZE(tvp514x_fmt_list),
1280
1281 .pix = {
1282 /* Default to NTSC 8-bit YUV 422 */
1283 .width = NTSC_NUM_ACTIVE_PIXELS,
1284 .height = NTSC_NUM_ACTIVE_LINES,
1285 .pixelformat = V4L2_PIX_FMT_UYVY,
1286 .field = V4L2_FIELD_INTERLACED,
1287 .bytesperline = NTSC_NUM_ACTIVE_PIXELS * 2,
1288 .sizeimage =
1289 NTSC_NUM_ACTIVE_PIXELS * 2 * NTSC_NUM_ACTIVE_LINES,
1290 .colorspace = V4L2_COLORSPACE_SMPTE170M,
1291 },
1292
1293 .current_std = STD_NTSC_MJ, 1150 .current_std = STD_NTSC_MJ,
1294 .std_list = tvp514x_std_list, 1151 .std_list = tvp514x_std_list,
1295 .num_stds = ARRAY_SIZE(tvp514x_std_list), 1152 .num_stds = ARRAY_SIZE(tvp514x_std_list),
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 47f0582d50a5..1654f65cca7c 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -934,17 +934,6 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
934 return 0; 934 return 0;
935} 935}
936 936
937static int tvp5150_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
938{
939 switch (fmt->type) {
940 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
941 return tvp5150_s_sliced_fmt(sd, &fmt->fmt.sliced);
942
943 default:
944 return -EINVAL;
945 }
946}
947
948static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi) 937static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
949{ 938{
950 int i, mask = 0; 939 int i, mask = 0;
@@ -960,13 +949,6 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
960 return 0; 949 return 0;
961} 950}
962 951
963static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
964{
965 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
966 return -EINVAL;
967 return tvp5150_g_sliced_fmt(sd, &fmt->fmt.sliced);
968}
969
970static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, 952static int tvp5150_g_chip_ident(struct v4l2_subdev *sd,
971 struct v4l2_dbg_chip_ident *chip) 953 struct v4l2_dbg_chip_ident *chip)
972{ 954{
@@ -1054,8 +1036,6 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
1054 1036
1055static const struct v4l2_subdev_video_ops tvp5150_video_ops = { 1037static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
1056 .s_routing = tvp5150_s_routing, 1038 .s_routing = tvp5150_s_routing,
1057 .g_fmt = tvp5150_g_fmt,
1058 .s_fmt = tvp5150_s_fmt,
1059}; 1039};
1060 1040
1061static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { 1041static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 76be733eabfd..445dc93413e3 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -903,7 +903,7 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
903#endif 903#endif
904}; 904};
905 905
906static int tw9910_enum_fmt(struct v4l2_subdev *sd, int index, 906static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
907 enum v4l2_mbus_pixelcode *code) 907 enum v4l2_mbus_pixelcode *code)
908{ 908{
909 if (index) 909 if (index)
@@ -977,7 +977,6 @@ static int tw9910_probe(struct i2c_client *client,
977 ret = tw9910_video_probe(icd, client); 977 ret = tw9910_video_probe(icd, client);
978 if (ret) { 978 if (ret) {
979 icd->ops = NULL; 979 icd->ops = NULL;
980 i2c_set_clientdata(client, NULL);
981 kfree(priv); 980 kfree(priv);
982 } 981 }
983 982
@@ -990,7 +989,6 @@ static int tw9910_remove(struct i2c_client *client)
990 struct soc_camera_device *icd = client->dev.platform_data; 989 struct soc_camera_device *icd = client->dev.platform_data;
991 990
992 icd->ops = NULL; 991 icd->ops = NULL;
993 i2c_set_clientdata(client, NULL);
994 kfree(priv); 992 kfree(priv);
995 return 0; 993 return 0;
996} 994}
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 6248a639ba2d..c2690df33438 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1671,8 +1671,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
1671 PDEBUG(DBG_PROBE, ""); 1671 PDEBUG(DBG_PROBE, "");
1672 1672
1673 if (usbvision == NULL) { 1673 if (usbvision == NULL) {
1674 dev_err(&usbvision->dev->dev, 1674 pr_err("%s: usb_get_intfdata() failed\n", __func__);
1675 "%s: usb_get_intfdata() failed\n", __func__);
1676 return; 1675 return;
1677 } 1676 }
1678 1677
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index c933b64d1283..bc02e6b21608 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -200,8 +200,6 @@ static int __devexit pm860x_remove(struct i2c_client *client)
200 200
201 pm860x_device_exit(chip); 201 pm860x_device_exit(chip);
202 i2c_unregister_device(chip->companion); 202 i2c_unregister_device(chip->companion);
203 i2c_set_clientdata(chip->client, NULL);
204 i2c_set_clientdata(client, NULL);
205 kfree(chip); 203 kfree(chip);
206 return 0; 204 return 0;
207} 205}
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 53ebfee548fa..66379b413906 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -957,7 +957,6 @@ static int __init ab3100_probe(struct i2c_client *client,
957 i2c_unregister_device(ab3100->testreg_client); 957 i2c_unregister_device(ab3100->testreg_client);
958 exit_no_testreg_client: 958 exit_no_testreg_client:
959 exit_no_detect: 959 exit_no_detect:
960 i2c_set_clientdata(client, NULL);
961 kfree(ab3100); 960 kfree(ab3100);
962 return err; 961 return err;
963} 962}
@@ -979,7 +978,6 @@ static int __exit ab3100_remove(struct i2c_client *client)
979 * their notifiers so deactivate IRQ 978 * their notifiers so deactivate IRQ
980 */ 979 */
981 free_irq(client->irq, ab3100); 980 free_irq(client->irq, ab3100);
982 i2c_set_clientdata(client, NULL);
983 kfree(ab3100); 981 kfree(ab3100);
984 return 0; 982 return 0;
985} 983}
diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c
index 1060f8e1c40a..f54ab62e7bc6 100644
--- a/drivers/mfd/ab3550-core.c
+++ b/drivers/mfd/ab3550-core.c
@@ -1362,7 +1362,6 @@ static int __exit ab3550_remove(struct i2c_client *client)
1362 * their notifiers so deactivate IRQ 1362 * their notifiers so deactivate IRQ
1363 */ 1363 */
1364 free_irq(client->irq, ab); 1364 free_irq(client->irq, ab);
1365 i2c_set_clientdata(client, NULL);
1366 kfree(ab); 1365 kfree(ab);
1367 return 0; 1366 return 0;
1368} 1367}
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index 005532865654..3122139b4300 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -302,7 +302,6 @@ out_free_irq:
302 free_irq(chip->irq, chip); 302 free_irq(chip->irq, chip);
303 303
304out_free_chip: 304out_free_chip:
305 i2c_set_clientdata(client, NULL);
306 kfree(chip); 305 kfree(chip);
307 306
308 return ret; 307 return ret;
@@ -317,7 +316,6 @@ static int __devexit adp5520_remove(struct i2c_client *client)
317 316
318 adp5520_remove_subdevs(chip); 317 adp5520_remove_subdevs(chip);
319 adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); 318 adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0);
320 i2c_set_clientdata(client, NULL);
321 kfree(chip); 319 kfree(chip);
322 return 0; 320 return 0;
323} 321}
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 3ad915d0589c..c07aece900fb 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -534,7 +534,6 @@ static int __devinit da903x_probe(struct i2c_client *client,
534out_free_irq: 534out_free_irq:
535 free_irq(client->irq, chip); 535 free_irq(client->irq, chip);
536out_free_chip: 536out_free_chip:
537 i2c_set_clientdata(client, NULL);
538 kfree(chip); 537 kfree(chip);
539 return ret; 538 return ret;
540} 539}
@@ -544,7 +543,6 @@ static int __devexit da903x_remove(struct i2c_client *client)
544 struct da903x_chip *chip = i2c_get_clientdata(client); 543 struct da903x_chip *chip = i2c_get_clientdata(client);
545 544
546 da903x_remove_subdevs(chip); 545 da903x_remove_subdevs(chip);
547 i2c_set_clientdata(client, NULL);
548 kfree(chip); 546 kfree(chip);
549 return 0; 547 return 0;
550} 548}
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
index e73f3f5252a8..0219115e00c7 100644
--- a/drivers/mfd/max8925-i2c.c
+++ b/drivers/mfd/max8925-i2c.c
@@ -173,7 +173,6 @@ static int __devexit max8925_remove(struct i2c_client *client)
173 max8925_device_exit(chip); 173 max8925_device_exit(chip);
174 i2c_unregister_device(chip->adc); 174 i2c_unregister_device(chip->adc);
175 i2c_unregister_device(chip->rtc); 175 i2c_unregister_device(chip->rtc);
176 i2c_set_clientdata(chip->i2c, NULL);
177 kfree(chip); 176 kfree(chip);
178 return 0; 177 return 0;
179} 178}
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 721948be12c7..a3fb4bcb9889 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1228,7 +1228,6 @@ fail2:
1228 free_irq(client->irq, menelaus); 1228 free_irq(client->irq, menelaus);
1229 flush_scheduled_work(); 1229 flush_scheduled_work();
1230fail1: 1230fail1:
1231 i2c_set_clientdata(client, NULL);
1232 kfree(menelaus); 1231 kfree(menelaus);
1233 return err; 1232 return err;
1234} 1233}
@@ -1238,7 +1237,6 @@ static int __exit menelaus_remove(struct i2c_client *client)
1238 struct menelaus_chip *menelaus = i2c_get_clientdata(client); 1237 struct menelaus_chip *menelaus = i2c_get_clientdata(client);
1239 1238
1240 free_irq(client->irq, menelaus); 1239 free_irq(client->irq, menelaus);
1241 i2c_set_clientdata(client, NULL);
1242 kfree(menelaus); 1240 kfree(menelaus);
1243 the_menelaus = NULL; 1241 the_menelaus = NULL;
1244 return 0; 1242 return 0;
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 704736e6e9b9..23e585527285 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -336,7 +336,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
336 return 0; 336 return 0;
337 337
338err_free: 338err_free:
339 i2c_set_clientdata(client, NULL);
340 kfree(pcf); 339 kfree(pcf);
341 340
342 return ret; 341 return ret;
@@ -357,7 +356,6 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
357 for (i = 0; i < PCF50633_NUM_REGULATORS; i++) 356 for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
358 platform_device_unregister(pcf->regulator_pdev[i]); 357 platform_device_unregister(pcf->regulator_pdev[i]);
359 358
360 i2c_set_clientdata(client, NULL);
361 kfree(pcf); 359 kfree(pcf);
362 360
363 return 0; 361 return 0;
diff --git a/drivers/mfd/tc35892.c b/drivers/mfd/tc35892.c
index 715f095dd7a6..e619e2a55997 100644
--- a/drivers/mfd/tc35892.c
+++ b/drivers/mfd/tc35892.c
@@ -296,7 +296,6 @@ out_freeirq:
296out_removeirq: 296out_removeirq:
297 tc35892_irq_remove(tc35892); 297 tc35892_irq_remove(tc35892);
298out_free: 298out_free:
299 i2c_set_clientdata(i2c, NULL);
300 kfree(tc35892); 299 kfree(tc35892);
301 return ret; 300 return ret;
302} 301}
@@ -310,7 +309,6 @@ static int __devexit tc35892_remove(struct i2c_client *client)
310 free_irq(tc35892->i2c->irq, tc35892); 309 free_irq(tc35892->i2c->irq, tc35892);
311 tc35892_irq_remove(tc35892); 310 tc35892_irq_remove(tc35892);
312 311
313 i2c_set_clientdata(client, NULL);
314 kfree(tc35892); 312 kfree(tc35892);
315 313
316 return 0; 314 return 0;
diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c
index 9b22a77f70f5..d0016b67d125 100644
--- a/drivers/mfd/tps65010.c
+++ b/drivers/mfd/tps65010.c
@@ -530,7 +530,6 @@ static int __exit tps65010_remove(struct i2c_client *client)
530 cancel_delayed_work(&tps->work); 530 cancel_delayed_work(&tps->work);
531 flush_scheduled_work(); 531 flush_scheduled_work();
532 debugfs_remove(tps->file); 532 debugfs_remove(tps->file);
533 i2c_set_clientdata(client, NULL);
534 kfree(tps); 533 kfree(tps);
535 the_tps = NULL; 534 the_tps = NULL;
536 return 0; 535 return 0;
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c
index 7795af4b1fe1..5fe5de166adb 100644
--- a/drivers/mfd/wm8350-i2c.c
+++ b/drivers/mfd/wm8350-i2c.c
@@ -80,7 +80,6 @@ static int wm8350_i2c_probe(struct i2c_client *i2c,
80 return ret; 80 return ret;
81 81
82err: 82err:
83 i2c_set_clientdata(i2c, NULL);
84 kfree(wm8350); 83 kfree(wm8350);
85 return ret; 84 return ret;
86} 85}
@@ -90,7 +89,6 @@ static int wm8350_i2c_remove(struct i2c_client *i2c)
90 struct wm8350 *wm8350 = i2c_get_clientdata(i2c); 89 struct wm8350 *wm8350 = i2c_get_clientdata(i2c);
91 90
92 wm8350_device_exit(wm8350); 91 wm8350_device_exit(wm8350);
93 i2c_set_clientdata(i2c, NULL);
94 kfree(wm8350); 92 kfree(wm8350);
95 93
96 return 0; 94 return 0;
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index e08aafa663dc..1bfef4846b07 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -415,7 +415,6 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
415 return 0; 415 return 0;
416 416
417struct_err: 417struct_err:
418 i2c_set_clientdata(i2c, NULL);
419 kfree(wm8400); 418 kfree(wm8400);
420err: 419err:
421 return ret; 420 return ret;
@@ -426,7 +425,6 @@ static int wm8400_i2c_remove(struct i2c_client *i2c)
426 struct wm8400 *wm8400 = i2c_get_clientdata(i2c); 425 struct wm8400 *wm8400 = i2c_get_clientdata(i2c);
427 426
428 wm8400_release(wm8400); 427 wm8400_release(wm8400);
429 i2c_set_clientdata(i2c, NULL);
430 kfree(wm8400); 428 kfree(wm8400);
431 429
432 return 0; 430 return 0;
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index f7ca3a42b490..559b0b3c16c3 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -643,7 +643,6 @@ static int __devexit at24_remove(struct i2c_client *client)
643 643
644 kfree(at24->writebuf); 644 kfree(at24->writebuf);
645 kfree(at24); 645 kfree(at24);
646 i2c_set_clientdata(client, NULL);
647 return 0; 646 return 0;
648} 647}
649 648
diff --git a/drivers/misc/vmware_balloon.c b/drivers/misc/vmware_balloon.c
index db9cd0240c6f..2a1e804a71aa 100644
--- a/drivers/misc/vmware_balloon.c
+++ b/drivers/misc/vmware_balloon.c
@@ -45,7 +45,7 @@
45 45
46MODULE_AUTHOR("VMware, Inc."); 46MODULE_AUTHOR("VMware, Inc.");
47MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver"); 47MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver");
48MODULE_VERSION("1.2.1.0-K"); 48MODULE_VERSION("1.2.1.1-k");
49MODULE_ALIAS("dmi:*:svnVMware*:*"); 49MODULE_ALIAS("dmi:*:svnVMware*:*");
50MODULE_ALIAS("vmware_vmmemctl"); 50MODULE_ALIAS("vmware_vmmemctl");
51MODULE_LICENSE("GPL"); 51MODULE_LICENSE("GPL");
@@ -101,6 +101,8 @@ MODULE_LICENSE("GPL");
101/* Maximum number of page allocations without yielding processor */ 101/* Maximum number of page allocations without yielding processor */
102#define VMW_BALLOON_YIELD_THRESHOLD 1024 102#define VMW_BALLOON_YIELD_THRESHOLD 1024
103 103
104/* Maximum number of refused pages we accumulate during inflation cycle */
105#define VMW_BALLOON_MAX_REFUSED 16
104 106
105/* 107/*
106 * Hypervisor communication port definitions. 108 * Hypervisor communication port definitions.
@@ -183,6 +185,7 @@ struct vmballoon {
183 185
184 /* transient list of non-balloonable pages */ 186 /* transient list of non-balloonable pages */
185 struct list_head refused_pages; 187 struct list_head refused_pages;
188 unsigned int n_refused_pages;
186 189
187 /* balloon size in pages */ 190 /* balloon size in pages */
188 unsigned int size; 191 unsigned int size;
@@ -428,14 +431,21 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
428 /* inform monitor */ 431 /* inform monitor */
429 locked = vmballoon_send_lock_page(b, page_to_pfn(page)); 432 locked = vmballoon_send_lock_page(b, page_to_pfn(page));
430 if (!locked) { 433 if (!locked) {
434 STATS_INC(b->stats.refused_alloc);
435
431 if (b->reset_required) { 436 if (b->reset_required) {
432 __free_page(page); 437 __free_page(page);
433 return -EIO; 438 return -EIO;
434 } 439 }
435 440
436 /* place on list of non-balloonable pages, retry allocation */ 441 /*
442 * Place page on the list of non-balloonable pages
443 * and retry allocation, unless we already accumulated
444 * too many of them, in which case take a breather.
445 */
437 list_add(&page->lru, &b->refused_pages); 446 list_add(&page->lru, &b->refused_pages);
438 STATS_INC(b->stats.refused_alloc); 447 if (++b->n_refused_pages >= VMW_BALLOON_MAX_REFUSED)
448 return -EIO;
439 } 449 }
440 } while (!locked); 450 } while (!locked);
441 451
@@ -483,6 +493,8 @@ static void vmballoon_release_refused_pages(struct vmballoon *b)
483 __free_page(page); 493 __free_page(page);
484 STATS_INC(b->stats.refused_free); 494 STATS_INC(b->stats.refused_free);
485 } 495 }
496
497 b->n_refused_pages = 0;
486} 498}
487 499
488/* 500/*
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 2b281680e320..d98ddcfac5e5 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1157,7 +1157,6 @@ static void mmc_omap_start_request(struct mmc_omap_host *host,
1157 mmc_omap_start_command(host, req->cmd); 1157 mmc_omap_start_command(host, req->cmd);
1158 if (host->dma_in_use) 1158 if (host->dma_in_use)
1159 omap_start_dma(host->dma_ch); 1159 omap_start_dma(host->dma_ch);
1160 BUG_ON(irqs_disabled());
1161} 1160}
1162 1161
1163static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req) 1162static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index eb97830c0344..5d3f824bb5a3 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -30,25 +30,6 @@
30#define DRIVER_NAME "sh_mmcif" 30#define DRIVER_NAME "sh_mmcif"
31#define DRIVER_VERSION "2010-04-28" 31#define DRIVER_VERSION "2010-04-28"
32 32
33#define MMCIF_CE_CMD_SET 0x00000000
34#define MMCIF_CE_ARG 0x00000008
35#define MMCIF_CE_ARG_CMD12 0x0000000C
36#define MMCIF_CE_CMD_CTRL 0x00000010
37#define MMCIF_CE_BLOCK_SET 0x00000014
38#define MMCIF_CE_CLK_CTRL 0x00000018
39#define MMCIF_CE_BUF_ACC 0x0000001C
40#define MMCIF_CE_RESP3 0x00000020
41#define MMCIF_CE_RESP2 0x00000024
42#define MMCIF_CE_RESP1 0x00000028
43#define MMCIF_CE_RESP0 0x0000002C
44#define MMCIF_CE_RESP_CMD12 0x00000030
45#define MMCIF_CE_DATA 0x00000034
46#define MMCIF_CE_INT 0x00000040
47#define MMCIF_CE_INT_MASK 0x00000044
48#define MMCIF_CE_HOST_STS1 0x00000048
49#define MMCIF_CE_HOST_STS2 0x0000004C
50#define MMCIF_CE_VERSION 0x0000007C
51
52/* CE_CMD_SET */ 33/* CE_CMD_SET */
53#define CMD_MASK 0x3f000000 34#define CMD_MASK 0x3f000000
54#define CMD_SET_RTYP_NO ((0 << 23) | (0 << 22)) 35#define CMD_SET_RTYP_NO ((0 << 23) | (0 << 22))
@@ -207,27 +188,17 @@ struct sh_mmcif_host {
207 wait_queue_head_t intr_wait; 188 wait_queue_head_t intr_wait;
208}; 189};
209 190
210static inline u32 sh_mmcif_readl(struct sh_mmcif_host *host, unsigned int reg)
211{
212 return readl(host->addr + reg);
213}
214
215static inline void sh_mmcif_writel(struct sh_mmcif_host *host,
216 unsigned int reg, u32 val)
217{
218 writel(val, host->addr + reg);
219}
220 191
221static inline void sh_mmcif_bitset(struct sh_mmcif_host *host, 192static inline void sh_mmcif_bitset(struct sh_mmcif_host *host,
222 unsigned int reg, u32 val) 193 unsigned int reg, u32 val)
223{ 194{
224 writel(val | sh_mmcif_readl(host, reg), host->addr + reg); 195 writel(val | readl(host->addr + reg), host->addr + reg);
225} 196}
226 197
227static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host, 198static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
228 unsigned int reg, u32 val) 199 unsigned int reg, u32 val)
229{ 200{
230 writel(~val & sh_mmcif_readl(host, reg), host->addr + reg); 201 writel(~val & readl(host->addr + reg), host->addr + reg);
231} 202}
232 203
233 204
@@ -253,10 +224,10 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
253{ 224{
254 u32 tmp; 225 u32 tmp;
255 226
256 tmp = 0x010f0000 & sh_mmcif_readl(host, MMCIF_CE_CLK_CTRL); 227 tmp = 0x010f0000 & sh_mmcif_readl(host->addr, MMCIF_CE_CLK_CTRL);
257 228
258 sh_mmcif_writel(host, MMCIF_CE_VERSION, SOFT_RST_ON); 229 sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_ON);
259 sh_mmcif_writel(host, MMCIF_CE_VERSION, SOFT_RST_OFF); 230 sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_OFF);
260 sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, tmp | 231 sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, tmp |
261 SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29); 232 SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29);
262 /* byte swap on */ 233 /* byte swap on */
@@ -271,12 +242,10 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
271 host->sd_error = 0; 242 host->sd_error = 0;
272 host->wait_int = 0; 243 host->wait_int = 0;
273 244
274 state1 = sh_mmcif_readl(host, MMCIF_CE_HOST_STS1); 245 state1 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1);
275 state2 = sh_mmcif_readl(host, MMCIF_CE_HOST_STS2); 246 state2 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS2);
276 pr_debug("%s: ERR HOST_STS1 = %08x\n", \ 247 pr_debug("%s: ERR HOST_STS1 = %08x\n", DRIVER_NAME, state1);
277 DRIVER_NAME, sh_mmcif_readl(host, MMCIF_CE_HOST_STS1)); 248 pr_debug("%s: ERR HOST_STS2 = %08x\n", DRIVER_NAME, state2);
278 pr_debug("%s: ERR HOST_STS2 = %08x\n", \
279 DRIVER_NAME, sh_mmcif_readl(host, MMCIF_CE_HOST_STS2));
280 249
281 if (state1 & STS1_CMDSEQ) { 250 if (state1 & STS1_CMDSEQ) {
282 sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); 251 sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK);
@@ -288,7 +257,7 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
288 "command sequence timeout err\n"); 257 "command sequence timeout err\n");
289 return -EIO; 258 return -EIO;
290 } 259 }
291 if (!(sh_mmcif_readl(host, MMCIF_CE_HOST_STS1) 260 if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1)
292 & STS1_CMDSEQ)) 261 & STS1_CMDSEQ))
293 break; 262 break;
294 mdelay(1); 263 mdelay(1);
@@ -330,9 +299,9 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host,
330 299
331 host->wait_int = 0; 300 host->wait_int = 0;
332 blocksize = (BLOCK_SIZE_MASK & 301 blocksize = (BLOCK_SIZE_MASK &
333 sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET)) + 3; 302 sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
334 for (i = 0; i < blocksize / 4; i++) 303 for (i = 0; i < blocksize / 4; i++)
335 *p++ = sh_mmcif_readl(host, MMCIF_CE_DATA); 304 *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
336 305
337 /* buffer read end */ 306 /* buffer read end */
338 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); 307 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
@@ -353,7 +322,8 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
353 long time; 322 long time;
354 u32 blocksize, i, j, sec, *p; 323 u32 blocksize, i, j, sec, *p;
355 324
356 blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET); 325 blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
326 MMCIF_CE_BLOCK_SET);
357 for (j = 0; j < data->sg_len; j++) { 327 for (j = 0; j < data->sg_len; j++) {
358 p = sg_virt(data->sg); 328 p = sg_virt(data->sg);
359 host->wait_int = 0; 329 host->wait_int = 0;
@@ -370,7 +340,8 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
370 340
371 host->wait_int = 0; 341 host->wait_int = 0;
372 for (i = 0; i < blocksize / 4; i++) 342 for (i = 0; i < blocksize / 4; i++)
373 *p++ = sh_mmcif_readl(host, MMCIF_CE_DATA); 343 *p++ = sh_mmcif_readl(host->addr,
344 MMCIF_CE_DATA);
374 } 345 }
375 if (j < data->sg_len - 1) 346 if (j < data->sg_len - 1)
376 data->sg++; 347 data->sg++;
@@ -397,9 +368,9 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host,
397 368
398 host->wait_int = 0; 369 host->wait_int = 0;
399 blocksize = (BLOCK_SIZE_MASK & 370 blocksize = (BLOCK_SIZE_MASK &
400 sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET)) + 3; 371 sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
401 for (i = 0; i < blocksize / 4; i++) 372 for (i = 0; i < blocksize / 4; i++)
402 sh_mmcif_writel(host, MMCIF_CE_DATA, *p++); 373 sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
403 374
404 /* buffer write end */ 375 /* buffer write end */
405 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); 376 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
@@ -421,7 +392,8 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
421 long time; 392 long time;
422 u32 i, sec, j, blocksize, *p; 393 u32 i, sec, j, blocksize, *p;
423 394
424 blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET); 395 blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
396 MMCIF_CE_BLOCK_SET);
425 397
426 for (j = 0; j < data->sg_len; j++) { 398 for (j = 0; j < data->sg_len; j++) {
427 p = sg_virt(data->sg); 399 p = sg_virt(data->sg);
@@ -439,7 +411,8 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
439 411
440 host->wait_int = 0; 412 host->wait_int = 0;
441 for (i = 0; i < blocksize / 4; i++) 413 for (i = 0; i < blocksize / 4; i++)
442 sh_mmcif_writel(host, MMCIF_CE_DATA, *p++); 414 sh_mmcif_writel(host->addr,
415 MMCIF_CE_DATA, *p++);
443 } 416 }
444 if (j < data->sg_len - 1) 417 if (j < data->sg_len - 1)
445 data->sg++; 418 data->sg++;
@@ -451,18 +424,18 @@ static void sh_mmcif_get_response(struct sh_mmcif_host *host,
451 struct mmc_command *cmd) 424 struct mmc_command *cmd)
452{ 425{
453 if (cmd->flags & MMC_RSP_136) { 426 if (cmd->flags & MMC_RSP_136) {
454 cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP3); 427 cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP3);
455 cmd->resp[1] = sh_mmcif_readl(host, MMCIF_CE_RESP2); 428 cmd->resp[1] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP2);
456 cmd->resp[2] = sh_mmcif_readl(host, MMCIF_CE_RESP1); 429 cmd->resp[2] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP1);
457 cmd->resp[3] = sh_mmcif_readl(host, MMCIF_CE_RESP0); 430 cmd->resp[3] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP0);
458 } else 431 } else
459 cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP0); 432 cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP0);
460} 433}
461 434
462static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host, 435static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
463 struct mmc_command *cmd) 436 struct mmc_command *cmd)
464{ 437{
465 cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP_CMD12); 438 cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP_CMD12);
466} 439}
467 440
468static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, 441static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
@@ -596,18 +569,19 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
596 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO; 569 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;
597 570
598 if (host->data) { 571 if (host->data) {
599 sh_mmcif_writel(host, MMCIF_CE_BLOCK_SET, 0); 572 sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
600 sh_mmcif_writel(host, MMCIF_CE_BLOCK_SET, mrq->data->blksz); 573 sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET,
574 mrq->data->blksz);
601 } 575 }
602 opc = sh_mmcif_set_cmd(host, mrq, cmd, opc); 576 opc = sh_mmcif_set_cmd(host, mrq, cmd, opc);
603 577
604 sh_mmcif_writel(host, MMCIF_CE_INT, 0xD80430C0); 578 sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0);
605 sh_mmcif_writel(host, MMCIF_CE_INT_MASK, mask); 579 sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask);
606 /* set arg */ 580 /* set arg */
607 sh_mmcif_writel(host, MMCIF_CE_ARG, cmd->arg); 581 sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg);
608 host->wait_int = 0; 582 host->wait_int = 0;
609 /* set cmd */ 583 /* set cmd */
610 sh_mmcif_writel(host, MMCIF_CE_CMD_SET, opc); 584 sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);
611 585
612 time = wait_event_interruptible_timeout(host->intr_wait, 586 time = wait_event_interruptible_timeout(host->intr_wait,
613 host->wait_int == 1 || host->sd_error == 1, host->timeout); 587 host->wait_int == 1 || host->sd_error == 1, host->timeout);
@@ -752,43 +726,44 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
752 u32 state = 0; 726 u32 state = 0;
753 int err = 0; 727 int err = 0;
754 728
755 state = sh_mmcif_readl(host, MMCIF_CE_INT); 729 state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
756 730
757 if (state & INT_RBSYE) { 731 if (state & INT_RBSYE) {
758 sh_mmcif_writel(host, MMCIF_CE_INT, ~(INT_RBSYE | INT_CRSPE)); 732 sh_mmcif_writel(host->addr, MMCIF_CE_INT,
733 ~(INT_RBSYE | INT_CRSPE));
759 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE); 734 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE);
760 } else if (state & INT_CRSPE) { 735 } else if (state & INT_CRSPE) {
761 sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_CRSPE); 736 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_CRSPE);
762 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCRSPE); 737 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCRSPE);
763 } else if (state & INT_BUFREN) { 738 } else if (state & INT_BUFREN) {
764 sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFREN); 739 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFREN);
765 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); 740 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
766 } else if (state & INT_BUFWEN) { 741 } else if (state & INT_BUFWEN) {
767 sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFWEN); 742 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFWEN);
768 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); 743 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
769 } else if (state & INT_CMD12DRE) { 744 } else if (state & INT_CMD12DRE) {
770 sh_mmcif_writel(host, MMCIF_CE_INT, 745 sh_mmcif_writel(host->addr, MMCIF_CE_INT,
771 ~(INT_CMD12DRE | INT_CMD12RBE | 746 ~(INT_CMD12DRE | INT_CMD12RBE |
772 INT_CMD12CRE | INT_BUFRE)); 747 INT_CMD12CRE | INT_BUFRE));
773 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE); 748 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
774 } else if (state & INT_BUFRE) { 749 } else if (state & INT_BUFRE) {
775 sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFRE); 750 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFRE);
776 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); 751 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
777 } else if (state & INT_DTRANE) { 752 } else if (state & INT_DTRANE) {
778 sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_DTRANE); 753 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_DTRANE);
779 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); 754 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
780 } else if (state & INT_CMD12RBE) { 755 } else if (state & INT_CMD12RBE) {
781 sh_mmcif_writel(host, MMCIF_CE_INT, 756 sh_mmcif_writel(host->addr, MMCIF_CE_INT,
782 ~(INT_CMD12RBE | INT_CMD12CRE)); 757 ~(INT_CMD12RBE | INT_CMD12CRE));
783 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); 758 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
784 } else if (state & INT_ERR_STS) { 759 } else if (state & INT_ERR_STS) {
785 /* err interrupts */ 760 /* err interrupts */
786 sh_mmcif_writel(host, MMCIF_CE_INT, ~state); 761 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
787 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); 762 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
788 err = 1; 763 err = 1;
789 } else { 764 } else {
790 pr_debug("%s: Not support int\n", DRIVER_NAME); 765 pr_debug("%s: Not support int\n", DRIVER_NAME);
791 sh_mmcif_writel(host, MMCIF_CE_INT, ~state); 766 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
792 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); 767 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
793 err = 1; 768 err = 1;
794 } 769 }
@@ -894,12 +869,12 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
894 goto clean_up2; 869 goto clean_up2;
895 } 870 }
896 871
897 sh_mmcif_writel(host, MMCIF_CE_INT_MASK, MASK_ALL); 872 sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
898 sh_mmcif_detect(host->mmc); 873 sh_mmcif_detect(host->mmc);
899 874
900 pr_info("%s: driver version %s\n", DRIVER_NAME, DRIVER_VERSION); 875 pr_info("%s: driver version %s\n", DRIVER_NAME, DRIVER_VERSION);
901 pr_debug("%s: chip ver H'%04x\n", DRIVER_NAME, 876 pr_debug("%s: chip ver H'%04x\n", DRIVER_NAME,
902 sh_mmcif_readl(host, MMCIF_CE_VERSION) & 0x0000ffff); 877 sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
903 return ret; 878 return ret;
904 879
905clean_up2: 880clean_up2:
@@ -917,7 +892,7 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
917 struct sh_mmcif_host *host = platform_get_drvdata(pdev); 892 struct sh_mmcif_host *host = platform_get_drvdata(pdev);
918 int irq[2]; 893 int irq[2];
919 894
920 sh_mmcif_writel(host, MMCIF_CE_INT_MASK, MASK_ALL); 895 sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
921 896
922 irq[0] = platform_get_irq(pdev, 0); 897 irq[0] = platform_get_irq(pdev, 0);
923 irq[1] = platform_get_irq(pdev, 1); 898 irq[1] = platform_get_irq(pdev, 1);
diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c
index eb476b7f8d11..f4ce273e93fd 100644
--- a/drivers/mtd/maps/pismo.c
+++ b/drivers/mtd/maps/pismo.c
@@ -234,7 +234,6 @@ static int __devexit pismo_remove(struct i2c_client *client)
234 /* FIXME: set_vpp needs saner arguments */ 234 /* FIXME: set_vpp needs saner arguments */
235 pismo_setvpp_remove_fix(pismo); 235 pismo_setvpp_remove_fix(pismo);
236 236
237 i2c_set_clientdata(client, NULL);
238 kfree(pismo); 237 kfree(pismo);
239 238
240 return 0; 239 return 0;
@@ -286,7 +285,6 @@ static int __devinit pismo_probe(struct i2c_client *client,
286 return 0; 285 return 0;
287 286
288 exit_free: 287 exit_free:
289 i2c_set_clientdata(client, NULL);
290 kfree(pismo); 288 kfree(pismo);
291 return ret; 289 return ret;
292} 290}
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 00aea6f7d1f1..1312eda57ba6 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -232,7 +232,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
232 if (!fun) 232 if (!fun)
233 return -ENOMEM; 233 return -ENOMEM;
234 234
235 ret = of_address_to_resource(ofdev->node, 0, &io_res); 235 ret = of_address_to_resource(ofdev->dev.of_node, 0, &io_res);
236 if (ret) { 236 if (ret) {
237 dev_err(&ofdev->dev, "can't get IO base\n"); 237 dev_err(&ofdev->dev, "can't get IO base\n");
238 goto err1; 238 goto err1;
@@ -244,7 +244,8 @@ static int __devinit fun_probe(struct of_device *ofdev,
244 goto err1; 244 goto err1;
245 } 245 }
246 246
247 prop = of_get_property(ofdev->node, "fsl,upm-addr-offset", &size); 247 prop = of_get_property(ofdev->dev.of_node, "fsl,upm-addr-offset",
248 &size);
248 if (!prop || size != sizeof(uint32_t)) { 249 if (!prop || size != sizeof(uint32_t)) {
249 dev_err(&ofdev->dev, "can't get UPM address offset\n"); 250 dev_err(&ofdev->dev, "can't get UPM address offset\n");
250 ret = -EINVAL; 251 ret = -EINVAL;
@@ -252,7 +253,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
252 } 253 }
253 fun->upm_addr_offset = *prop; 254 fun->upm_addr_offset = *prop;
254 255
255 prop = of_get_property(ofdev->node, "fsl,upm-cmd-offset", &size); 256 prop = of_get_property(ofdev->dev.of_node, "fsl,upm-cmd-offset", &size);
256 if (!prop || size != sizeof(uint32_t)) { 257 if (!prop || size != sizeof(uint32_t)) {
257 dev_err(&ofdev->dev, "can't get UPM command offset\n"); 258 dev_err(&ofdev->dev, "can't get UPM command offset\n");
258 ret = -EINVAL; 259 ret = -EINVAL;
@@ -260,7 +261,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
260 } 261 }
261 fun->upm_cmd_offset = *prop; 262 fun->upm_cmd_offset = *prop;
262 263
263 prop = of_get_property(ofdev->node, 264 prop = of_get_property(ofdev->dev.of_node,
264 "fsl,upm-addr-line-cs-offsets", &size); 265 "fsl,upm-addr-line-cs-offsets", &size);
265 if (prop && (size / sizeof(uint32_t)) > 0) { 266 if (prop && (size / sizeof(uint32_t)) > 0) {
266 fun->mchip_count = size / sizeof(uint32_t); 267 fun->mchip_count = size / sizeof(uint32_t);
@@ -276,7 +277,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
276 277
277 for (i = 0; i < fun->mchip_count; i++) { 278 for (i = 0; i < fun->mchip_count; i++) {
278 fun->rnb_gpio[i] = -1; 279 fun->rnb_gpio[i] = -1;
279 rnb_gpio = of_get_gpio(ofdev->node, i); 280 rnb_gpio = of_get_gpio(ofdev->dev.of_node, i);
280 if (rnb_gpio >= 0) { 281 if (rnb_gpio >= 0) {
281 ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev)); 282 ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev));
282 if (ret) { 283 if (ret) {
@@ -292,13 +293,13 @@ static int __devinit fun_probe(struct of_device *ofdev,
292 } 293 }
293 } 294 }
294 295
295 prop = of_get_property(ofdev->node, "chip-delay", NULL); 296 prop = of_get_property(ofdev->dev.of_node, "chip-delay", NULL);
296 if (prop) 297 if (prop)
297 fun->chip_delay = *prop; 298 fun->chip_delay = *prop;
298 else 299 else
299 fun->chip_delay = 50; 300 fun->chip_delay = 50;
300 301
301 prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size); 302 prop = of_get_property(ofdev->dev.of_node, "fsl,upm-wait-flags", &size);
302 if (prop && size == sizeof(uint32_t)) 303 if (prop && size == sizeof(uint32_t))
303 fun->wait_flags = *prop; 304 fun->wait_flags = *prop;
304 else 305 else
@@ -315,7 +316,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
315 fun->dev = &ofdev->dev; 316 fun->dev = &ofdev->dev;
316 fun->last_ctrl = NAND_CLE; 317 fun->last_ctrl = NAND_CLE;
317 318
318 ret = fun_chip_init(fun, ofdev->node, &io_res); 319 ret = fun_chip_init(fun, ofdev->dev.of_node, &io_res);
319 if (ret) 320 if (ret)
320 goto err2; 321 goto err2;
321 322
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c
index 3d0867d829cb..0a130dcaa129 100644
--- a/drivers/mtd/nand/mpc5121_nfc.c
+++ b/drivers/mtd/nand/mpc5121_nfc.c
@@ -650,7 +650,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd)
650static int __devinit mpc5121_nfc_probe(struct of_device *op, 650static int __devinit mpc5121_nfc_probe(struct of_device *op,
651 const struct of_device_id *match) 651 const struct of_device_id *match)
652{ 652{
653 struct device_node *rootnode, *dn = op->node; 653 struct device_node *rootnode, *dn = op->dev.of_node;
654 struct device *dev = &op->dev; 654 struct device *dev = &op->dev;
655 struct mpc5121_nfc_prv *prv; 655 struct mpc5121_nfc_prv *prv;
656 struct resource res; 656 struct resource res;
@@ -889,12 +889,12 @@ static struct of_device_id mpc5121_nfc_match[] __devinitdata = {
889}; 889};
890 890
891static struct of_platform_driver mpc5121_nfc_driver = { 891static struct of_platform_driver mpc5121_nfc_driver = {
892 .match_table = mpc5121_nfc_match,
893 .probe = mpc5121_nfc_probe, 892 .probe = mpc5121_nfc_probe,
894 .remove = __devexit_p(mpc5121_nfc_remove), 893 .remove = __devexit_p(mpc5121_nfc_remove),
895 .driver = { 894 .driver = {
896 .name = DRV_NAME, 895 .name = DRV_NAME,
897 .owner = THIS_MODULE, 896 .owner = THIS_MODULE,
897 .of_match_table = mpc5121_nfc_match,
898 }, 898 },
899}; 899};
900 900
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
index 884852dc7eb4..cc728b12de82 100644
--- a/drivers/mtd/nand/socrates_nand.c
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -183,7 +183,7 @@ static int __devinit socrates_nand_probe(struct of_device *ofdev,
183 return -ENOMEM; 183 return -ENOMEM;
184 } 184 }
185 185
186 host->io_base = of_iomap(ofdev->node, 0); 186 host->io_base = of_iomap(ofdev->dev.of_node, 0);
187 if (host->io_base == NULL) { 187 if (host->io_base == NULL) {
188 printk(KERN_ERR "socrates_nand: ioremap failed\n"); 188 printk(KERN_ERR "socrates_nand: ioremap failed\n");
189 kfree(host); 189 kfree(host);
@@ -244,7 +244,7 @@ static int __devinit socrates_nand_probe(struct of_device *ofdev,
244#ifdef CONFIG_MTD_OF_PARTS 244#ifdef CONFIG_MTD_OF_PARTS
245 if (num_partitions == 0) { 245 if (num_partitions == 0) {
246 num_partitions = of_mtd_parse_partitions(&ofdev->dev, 246 num_partitions = of_mtd_parse_partitions(&ofdev->dev,
247 ofdev->node, 247 ofdev->dev.of_node,
248 &partitions); 248 &partitions);
249 if (num_partitions < 0) { 249 if (num_partitions < 0) {
250 res = num_partitions; 250 res = num_partitions;
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 9d11dbf5e4da..b9ad799c719f 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1429,7 +1429,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
1429 wrb = wrb_from_mccq(adapter); 1429 wrb = wrb_from_mccq(adapter);
1430 if (!wrb) { 1430 if (!wrb) {
1431 status = -EBUSY; 1431 status = -EBUSY;
1432 goto err; 1432 goto err_unlock;
1433 } 1433 }
1434 req = cmd->va; 1434 req = cmd->va;
1435 sge = nonembedded_sgl(wrb); 1435 sge = nonembedded_sgl(wrb);
@@ -1457,7 +1457,10 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
1457 else 1457 else
1458 status = adapter->flash_status; 1458 status = adapter->flash_status;
1459 1459
1460err: 1460 return status;
1461
1462err_unlock:
1463 spin_unlock_bh(&adapter->mcc_lock);
1461 return status; 1464 return status;
1462} 1465}
1463 1466
@@ -1497,7 +1500,7 @@ err:
1497 return status; 1500 return status;
1498} 1501}
1499 1502
1500extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, 1503int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
1501 struct be_dma_mem *nonemb_cmd) 1504 struct be_dma_mem *nonemb_cmd)
1502{ 1505{
1503 struct be_mcc_wrb *wrb; 1506 struct be_mcc_wrb *wrb;
@@ -1590,7 +1593,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
1590 1593
1591 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, 1594 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
1592 OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); 1595 OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req));
1593 req->hdr.timeout = 4; 1596 req->hdr.timeout = cpu_to_le32(4);
1594 1597
1595 req->pattern = cpu_to_le64(pattern); 1598 req->pattern = cpu_to_le64(pattern);
1596 req->src_port = cpu_to_le32(port_num); 1599 req->src_port = cpu_to_le32(port_num);
@@ -1662,7 +1665,7 @@ err:
1662 return status; 1665 return status;
1663} 1666}
1664 1667
1665extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, 1668int be_cmd_get_seeprom_data(struct be_adapter *adapter,
1666 struct be_dma_mem *nonemb_cmd) 1669 struct be_dma_mem *nonemb_cmd)
1667{ 1670{
1668 struct be_mcc_wrb *wrb; 1671 struct be_mcc_wrb *wrb;
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 39250b2ca886..959add2410bf 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1654,8 +1654,11 @@ MODULE_DEVICE_TABLE (of, bmac_match);
1654 1654
1655static struct macio_driver bmac_driver = 1655static struct macio_driver bmac_driver =
1656{ 1656{
1657 .name = "bmac", 1657 .driver = {
1658 .match_table = bmac_match, 1658 .name = "bmac",
1659 .owner = THIS_MODULE,
1660 .of_match_table = bmac_match,
1661 },
1659 .probe = bmac_probe, 1662 .probe = bmac_probe,
1660 .remove = bmac_remove, 1663 .remove = bmac_remove,
1661#ifdef CONFIG_PM 1664#ifdef CONFIG_PM
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 188e356c30a3..949d7a9dcf92 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -247,6 +247,7 @@ static const struct flash_spec flash_5709 = {
247MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); 247MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
248 248
249static void bnx2_init_napi(struct bnx2 *bp); 249static void bnx2_init_napi(struct bnx2 *bp);
250static void bnx2_del_napi(struct bnx2 *bp);
250 251
251static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) 252static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
252{ 253{
@@ -6270,6 +6271,7 @@ open_err:
6270 bnx2_free_skbs(bp); 6271 bnx2_free_skbs(bp);
6271 bnx2_free_irq(bp); 6272 bnx2_free_irq(bp);
6272 bnx2_free_mem(bp); 6273 bnx2_free_mem(bp);
6274 bnx2_del_napi(bp);
6273 return rc; 6275 return rc;
6274} 6276}
6275 6277
@@ -6537,6 +6539,7 @@ bnx2_close(struct net_device *dev)
6537 bnx2_free_irq(bp); 6539 bnx2_free_irq(bp);
6538 bnx2_free_skbs(bp); 6540 bnx2_free_skbs(bp);
6539 bnx2_free_mem(bp); 6541 bnx2_free_mem(bp);
6542 bnx2_del_napi(bp);
6540 bp->link_up = 0; 6543 bp->link_up = 0;
6541 netif_carrier_off(bp->dev); 6544 netif_carrier_off(bp->dev);
6542 bnx2_set_power_state(bp, PCI_D3hot); 6545 bnx2_set_power_state(bp, PCI_D3hot);
@@ -8227,7 +8230,16 @@ bnx2_bus_string(struct bnx2 *bp, char *str)
8227 return str; 8230 return str;
8228} 8231}
8229 8232
8230static void __devinit 8233static void
8234bnx2_del_napi(struct bnx2 *bp)
8235{
8236 int i;
8237
8238 for (i = 0; i < bp->irq_nvecs; i++)
8239 netif_napi_del(&bp->bnx2_napi[i].napi);
8240}
8241
8242static void
8231bnx2_init_napi(struct bnx2 *bp) 8243bnx2_init_napi(struct bnx2 *bp)
8232{ 8244{
8233 int i; 8245 int i;
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index 8af8442c694a..af753936e835 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -73,7 +73,7 @@ static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev,
73 else 73 else
74 *mscan_clksrc = MSCAN_CLKSRC_XTAL; 74 *mscan_clksrc = MSCAN_CLKSRC_XTAL;
75 75
76 freq = mpc5xxx_get_bus_frequency(ofdev->node); 76 freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
77 if (!freq) 77 if (!freq)
78 return 0; 78 return 0;
79 79
@@ -152,7 +152,7 @@ static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,
152 } 152 }
153 153
154 /* Determine the MSCAN device index from the physical address */ 154 /* Determine the MSCAN device index from the physical address */
155 pval = of_get_property(ofdev->node, "reg", &plen); 155 pval = of_get_property(ofdev->dev.of_node, "reg", &plen);
156 BUG_ON(!pval || plen < sizeof(*pval)); 156 BUG_ON(!pval || plen < sizeof(*pval));
157 clockidx = (*pval & 0x80) ? 1 : 0; 157 clockidx = (*pval & 0x80) ? 1 : 0;
158 if (*pval & 0x2000) 158 if (*pval & 0x2000)
@@ -168,11 +168,11 @@ static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,
168 */ 168 */
169 if (clock_name && !strcmp(clock_name, "ip")) { 169 if (clock_name && !strcmp(clock_name, "ip")) {
170 *mscan_clksrc = MSCAN_CLKSRC_IPS; 170 *mscan_clksrc = MSCAN_CLKSRC_IPS;
171 freq = mpc5xxx_get_bus_frequency(ofdev->node); 171 freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
172 } else { 172 } else {
173 *mscan_clksrc = MSCAN_CLKSRC_BUS; 173 *mscan_clksrc = MSCAN_CLKSRC_BUS;
174 174
175 pval = of_get_property(ofdev->node, 175 pval = of_get_property(ofdev->dev.of_node,
176 "fsl,mscan-clock-divider", &plen); 176 "fsl,mscan-clock-divider", &plen);
177 if (pval && plen == sizeof(*pval)) 177 if (pval && plen == sizeof(*pval))
178 clockdiv = *pval; 178 clockdiv = *pval;
@@ -251,7 +251,7 @@ static int __devinit mpc5xxx_can_probe(struct of_device *ofdev,
251 const struct of_device_id *id) 251 const struct of_device_id *id)
252{ 252{
253 struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data; 253 struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data;
254 struct device_node *np = ofdev->node; 254 struct device_node *np = ofdev->dev.of_node;
255 struct net_device *dev; 255 struct net_device *dev;
256 struct mscan_priv *priv; 256 struct mscan_priv *priv;
257 void __iomem *base; 257 void __iomem *base;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 24507f3b8b17..57a7e41da69e 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2554,7 +2554,7 @@ static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
2554 mdef = er32(MDEF(i)); 2554 mdef = er32(MDEF(i));
2555 2555
2556 /* Ignore filters with anything other than IPMI ports */ 2556 /* Ignore filters with anything other than IPMI ports */
2557 if (mdef & !(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664)) 2557 if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
2558 continue; 2558 continue;
2559 2559
2560 /* Enable this decision filter in MANC2H */ 2560 /* Enable this decision filter in MANC2H */
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 85f2a2e7030a..45e86d1e5b1b 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -74,7 +74,14 @@ struct enic_msix_entry {
74 void *devid; 74 void *devid;
75}; 75};
76 76
77#define ENIC_SET_APPLIED (1 << 0)
78#define ENIC_SET_REQUEST (1 << 1)
79#define ENIC_SET_NAME (1 << 2)
80#define ENIC_SET_INSTANCE (1 << 3)
81#define ENIC_SET_HOST (1 << 4)
82
77struct enic_port_profile { 83struct enic_port_profile {
84 u32 set;
78 u8 request; 85 u8 request;
79 char name[PORT_PROFILE_MAX]; 86 char name[PORT_PROFILE_MAX];
80 u8 instance_uuid[PORT_UUID_MAX]; 87 u8 instance_uuid[PORT_UUID_MAX];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 6586b5c7e4b6..bc7d6b96de3d 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1029,8 +1029,7 @@ static int enic_dev_init_done(struct enic *enic, int *done, int *error)
1029 return err; 1029 return err;
1030} 1030}
1031 1031
1032static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, 1032static int enic_set_port_profile(struct enic *enic, u8 *mac)
1033 char *name, u8 *instance_uuid, u8 *host_uuid)
1034{ 1033{
1035 struct vic_provinfo *vp; 1034 struct vic_provinfo *vp;
1036 u8 oui[3] = VIC_PROVINFO_CISCO_OUI; 1035 u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
@@ -1040,97 +1039,112 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac,
1040 "%02X%02X-%02X%02X%02X%02X%0X%02X"; 1039 "%02X%02X-%02X%02X%02X%02X%0X%02X";
1041 int err; 1040 int err;
1042 1041
1043 if (!name) 1042 err = enic_vnic_dev_deinit(enic);
1044 return -EINVAL; 1043 if (err)
1044 return err;
1045 1045
1046 if (!is_valid_ether_addr(mac)) 1046 switch (enic->pp.request) {
1047 return -EADDRNOTAVAIL;
1048 1047
1049 vp = vic_provinfo_alloc(GFP_KERNEL, oui, VIC_PROVINFO_LINUX_TYPE); 1048 case PORT_REQUEST_ASSOCIATE:
1050 if (!vp)
1051 return -ENOMEM;
1052 1049
1053 vic_provinfo_add_tlv(vp, 1050 if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
1054 VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, 1051 return -EINVAL;
1055 strlen(name) + 1, name);
1056
1057 vic_provinfo_add_tlv(vp,
1058 VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
1059 ETH_ALEN, mac);
1060
1061 if (instance_uuid) {
1062 uuid = instance_uuid;
1063 sprintf(uuid_str, uuid_fmt,
1064 uuid[0], uuid[1], uuid[2], uuid[3],
1065 uuid[4], uuid[5], uuid[6], uuid[7],
1066 uuid[8], uuid[9], uuid[10], uuid[11],
1067 uuid[12], uuid[13], uuid[14], uuid[15]);
1068 vic_provinfo_add_tlv(vp,
1069 VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
1070 sizeof(uuid_str), uuid_str);
1071 }
1072 1052
1073 if (host_uuid) { 1053 if (!is_valid_ether_addr(mac))
1074 uuid = host_uuid; 1054 return -EADDRNOTAVAIL;
1075 sprintf(uuid_str, uuid_fmt,
1076 uuid[0], uuid[1], uuid[2], uuid[3],
1077 uuid[4], uuid[5], uuid[6], uuid[7],
1078 uuid[8], uuid[9], uuid[10], uuid[11],
1079 uuid[12], uuid[13], uuid[14], uuid[15]);
1080 vic_provinfo_add_tlv(vp,
1081 VIC_LINUX_PROV_TLV_HOST_UUID_STR,
1082 sizeof(uuid_str), uuid_str);
1083 }
1084 1055
1085 err = enic_vnic_dev_deinit(enic); 1056 vp = vic_provinfo_alloc(GFP_KERNEL, oui,
1086 if (err) 1057 VIC_PROVINFO_LINUX_TYPE);
1087 goto err_out; 1058 if (!vp)
1059 return -ENOMEM;
1088 1060
1089 memset(&enic->pp, 0, sizeof(enic->pp)); 1061 vic_provinfo_add_tlv(vp,
1062 VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR,
1063 strlen(enic->pp.name) + 1, enic->pp.name);
1090 1064
1091 err = enic_dev_init_prov(enic, vp); 1065 vic_provinfo_add_tlv(vp,
1092 if (err) 1066 VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
1093 goto err_out; 1067 ETH_ALEN, mac);
1068
1069 if (enic->pp.set & ENIC_SET_INSTANCE) {
1070 uuid = enic->pp.instance_uuid;
1071 sprintf(uuid_str, uuid_fmt,
1072 uuid[0], uuid[1], uuid[2], uuid[3],
1073 uuid[4], uuid[5], uuid[6], uuid[7],
1074 uuid[8], uuid[9], uuid[10], uuid[11],
1075 uuid[12], uuid[13], uuid[14], uuid[15]);
1076 vic_provinfo_add_tlv(vp,
1077 VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
1078 sizeof(uuid_str), uuid_str);
1079 }
1094 1080
1095 enic->pp.request = request; 1081 if (enic->pp.set & ENIC_SET_HOST) {
1096 memcpy(enic->pp.name, name, PORT_PROFILE_MAX); 1082 uuid = enic->pp.host_uuid;
1097 if (instance_uuid) 1083 sprintf(uuid_str, uuid_fmt,
1098 memcpy(enic->pp.instance_uuid, 1084 uuid[0], uuid[1], uuid[2], uuid[3],
1099 instance_uuid, PORT_UUID_MAX); 1085 uuid[4], uuid[5], uuid[6], uuid[7],
1100 if (host_uuid) 1086 uuid[8], uuid[9], uuid[10], uuid[11],
1101 memcpy(enic->pp.host_uuid, 1087 uuid[12], uuid[13], uuid[14], uuid[15]);
1102 host_uuid, PORT_UUID_MAX); 1088 vic_provinfo_add_tlv(vp,
1089 VIC_LINUX_PROV_TLV_HOST_UUID_STR,
1090 sizeof(uuid_str), uuid_str);
1091 }
1103 1092
1104err_out: 1093 err = enic_dev_init_prov(enic, vp);
1105 vic_provinfo_free(vp); 1094 vic_provinfo_free(vp);
1095 if (err)
1096 return err;
1097 break;
1106 1098
1107 return err; 1099 case PORT_REQUEST_DISASSOCIATE:
1108} 1100 break;
1109 1101
1110static int enic_unset_port_profile(struct enic *enic) 1102 default:
1111{ 1103 return -EINVAL;
1112 memset(&enic->pp, 0, sizeof(enic->pp)); 1104 }
1113 return enic_vnic_dev_deinit(enic); 1105
1106 enic->pp.set |= ENIC_SET_APPLIED;
1107 return 0;
1114} 1108}
1115 1109
1116static int enic_set_vf_port(struct net_device *netdev, int vf, 1110static int enic_set_vf_port(struct net_device *netdev, int vf,
1117 struct nlattr *port[]) 1111 struct nlattr *port[])
1118{ 1112{
1119 struct enic *enic = netdev_priv(netdev); 1113 struct enic *enic = netdev_priv(netdev);
1120 char *name = NULL; 1114
1121 u8 *instance_uuid = NULL; 1115 memset(&enic->pp, 0, sizeof(enic->pp));
1122 u8 *host_uuid = NULL; 1116
1123 u8 request = PORT_REQUEST_DISASSOCIATE; 1117 if (port[IFLA_PORT_REQUEST]) {
1118 enic->pp.set |= ENIC_SET_REQUEST;
1119 enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
1120 }
1121
1122 if (port[IFLA_PORT_PROFILE]) {
1123 enic->pp.set |= ENIC_SET_NAME;
1124 memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
1125 PORT_PROFILE_MAX);
1126 }
1127
1128 if (port[IFLA_PORT_INSTANCE_UUID]) {
1129 enic->pp.set |= ENIC_SET_INSTANCE;
1130 memcpy(enic->pp.instance_uuid,
1131 nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
1132 }
1133
1134 if (port[IFLA_PORT_HOST_UUID]) {
1135 enic->pp.set |= ENIC_SET_HOST;
1136 memcpy(enic->pp.host_uuid,
1137 nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
1138 }
1124 1139
1125 /* don't support VFs, yet */ 1140 /* don't support VFs, yet */
1126 if (vf != PORT_SELF_VF) 1141 if (vf != PORT_SELF_VF)
1127 return -EOPNOTSUPP; 1142 return -EOPNOTSUPP;
1128 1143
1129 if (port[IFLA_PORT_REQUEST]) 1144 if (!(enic->pp.set & ENIC_SET_REQUEST))
1130 request = nla_get_u8(port[IFLA_PORT_REQUEST]); 1145 return -EOPNOTSUPP;
1131 1146
1132 switch (request) { 1147 if (enic->pp.request == PORT_REQUEST_ASSOCIATE) {
1133 case PORT_REQUEST_ASSOCIATE:
1134 1148
1135 /* If the interface mac addr hasn't been assigned, 1149 /* If the interface mac addr hasn't been assigned,
1136 * assign a random mac addr before setting port- 1150 * assign a random mac addr before setting port-
@@ -1139,30 +1153,9 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
1139 1153
1140 if (is_zero_ether_addr(netdev->dev_addr)) 1154 if (is_zero_ether_addr(netdev->dev_addr))
1141 random_ether_addr(netdev->dev_addr); 1155 random_ether_addr(netdev->dev_addr);
1142
1143 if (port[IFLA_PORT_PROFILE])
1144 name = nla_data(port[IFLA_PORT_PROFILE]);
1145
1146 if (port[IFLA_PORT_INSTANCE_UUID])
1147 instance_uuid =
1148 nla_data(port[IFLA_PORT_INSTANCE_UUID]);
1149
1150 if (port[IFLA_PORT_HOST_UUID])
1151 host_uuid = nla_data(port[IFLA_PORT_HOST_UUID]);
1152
1153 return enic_set_port_profile(enic, request,
1154 netdev->dev_addr, name,
1155 instance_uuid, host_uuid);
1156
1157 case PORT_REQUEST_DISASSOCIATE:
1158
1159 return enic_unset_port_profile(enic);
1160
1161 default:
1162 break;
1163 } 1156 }
1164 1157
1165 return -EOPNOTSUPP; 1158 return enic_set_port_profile(enic, netdev->dev_addr);
1166} 1159}
1167 1160
1168static int enic_get_vf_port(struct net_device *netdev, int vf, 1161static int enic_get_vf_port(struct net_device *netdev, int vf,
@@ -1172,14 +1165,12 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
1172 int err, error, done; 1165 int err, error, done;
1173 u16 response = PORT_PROFILE_RESPONSE_SUCCESS; 1166 u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
1174 1167
1175 /* don't support VFs, yet */ 1168 if (!(enic->pp.set & ENIC_SET_APPLIED))
1176 if (vf != PORT_SELF_VF) 1169 return -ENODATA;
1177 return -EOPNOTSUPP;
1178 1170
1179 err = enic_dev_init_done(enic, &done, &error); 1171 err = enic_dev_init_done(enic, &done, &error);
1180
1181 if (err) 1172 if (err)
1182 return err; 1173 error = err;
1183 1174
1184 switch (error) { 1175 switch (error) {
1185 case ERR_SUCCESS: 1176 case ERR_SUCCESS:
@@ -1202,12 +1193,15 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
1202 1193
1203 NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request); 1194 NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);
1204 NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response); 1195 NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
1205 NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, 1196 if (enic->pp.set & ENIC_SET_NAME)
1206 enic->pp.name); 1197 NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
1207 NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX, 1198 enic->pp.name);
1208 enic->pp.instance_uuid); 1199 if (enic->pp.set & ENIC_SET_INSTANCE)
1209 NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, 1200 NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
1210 enic->pp.host_uuid); 1201 enic->pp.instance_uuid);
1202 if (enic->pp.set & ENIC_SET_HOST)
1203 NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
1204 enic->pp.host_uuid);
1211 1205
1212 return 0; 1206 return 0;
1213 1207
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 6838dfc9ef23..4c274657283c 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -87,6 +87,7 @@ static int rx_copybreak;
87#include <linux/bitops.h> 87#include <linux/bitops.h>
88#include <asm/io.h> 88#include <asm/io.h>
89#include <asm/uaccess.h> 89#include <asm/uaccess.h>
90#include <asm/byteorder.h>
90 91
91/* These identify the driver base version and may not be removed. */ 92/* These identify the driver base version and may not be removed. */
92static char version[] __devinitdata = 93static char version[] __devinitdata =
@@ -230,7 +231,7 @@ static const u16 media2miictl[16] = {
230 * The EPIC100 Rx and Tx buffer descriptors. Note that these 231 * The EPIC100 Rx and Tx buffer descriptors. Note that these
231 * really ARE host-endian; it's not a misannotation. We tell 232 * really ARE host-endian; it's not a misannotation. We tell
232 * the card to byteswap them internally on big-endian hosts - 233 * the card to byteswap them internally on big-endian hosts -
233 * look for #ifdef CONFIG_BIG_ENDIAN in epic_open(). 234 * look for #ifdef __BIG_ENDIAN in epic_open().
234 */ 235 */
235 236
236struct epic_tx_desc { 237struct epic_tx_desc {
@@ -690,7 +691,7 @@ static int epic_open(struct net_device *dev)
690 outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); 691 outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
691 692
692 /* Tell the chip to byteswap descriptors on big-endian hosts */ 693 /* Tell the chip to byteswap descriptors on big-endian hosts */
693#ifdef CONFIG_BIG_ENDIAN 694#ifdef __BIG_ENDIAN
694 outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); 695 outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
695 inl(ioaddr + GENCTL); 696 inl(ioaddr + GENCTL);
696 outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); 697 outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
@@ -806,7 +807,7 @@ static void epic_restart(struct net_device *dev)
806 for (i = 16; i > 0; i--) 807 for (i = 16; i > 0; i--)
807 outl(0x0008, ioaddr + TEST1); 808 outl(0x0008, ioaddr + TEST1);
808 809
809#ifdef CONFIG_BIG_ENDIAN 810#ifdef __BIG_ENDIAN
810 outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); 811 outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
811#else 812#else
812 outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); 813 outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index ddf7a86cd466..edfff92a6d8e 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1373,10 +1373,9 @@ fec_suspend(struct platform_device *dev, pm_message_t state)
1373 1373
1374 if (ndev) { 1374 if (ndev) {
1375 fep = netdev_priv(ndev); 1375 fep = netdev_priv(ndev);
1376 if (netif_running(ndev)) { 1376 if (netif_running(ndev))
1377 netif_device_detach(ndev); 1377 fec_enet_close(ndev);
1378 fec_stop(ndev); 1378 clk_disable(fep->clk);
1379 }
1380 } 1379 }
1381 return 0; 1380 return 0;
1382} 1381}
@@ -1385,12 +1384,13 @@ static int
1385fec_resume(struct platform_device *dev) 1384fec_resume(struct platform_device *dev)
1386{ 1385{
1387 struct net_device *ndev = platform_get_drvdata(dev); 1386 struct net_device *ndev = platform_get_drvdata(dev);
1387 struct fec_enet_private *fep;
1388 1388
1389 if (ndev) { 1389 if (ndev) {
1390 if (netif_running(ndev)) { 1390 fep = netdev_priv(ndev);
1391 fec_enet_init(ndev, 0); 1391 clk_enable(fep->clk);
1392 netif_device_attach(ndev); 1392 if (netif_running(ndev))
1393 } 1393 fec_enet_open(ndev);
1394 } 1394 }
1395 return 0; 1395 return 0;
1396} 1396}
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 5d45084b287d..48e91b6242ce 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -504,17 +504,54 @@ static int get_regs_len(struct net_device *dev)
504} 504}
505 505
506/* Some transmit errors cause the transmitter to shut 506/* Some transmit errors cause the transmitter to shut
507 * down. We now issue a restart transmit. Since the 507 * down. We now issue a restart transmit.
508 * errors close the BD and update the pointers, the restart 508 * Also, to workaround 8260 device erratum CPM37, we must
509 * _should_ pick up without having to reset any of our 509 * disable and then re-enable the transmitterfollowing a
510 * pointers either. Also, To workaround 8260 device erratum 510 * Late Collision, Underrun, or Retry Limit error.
511 * CPM37, we must disable and then re-enable the transmitter 511 * In addition, tbptr may point beyond BDs beyond still marked
512 * following a Late Collision, Underrun, or Retry Limit error. 512 * as ready due to internal pipelining, so we need to look back
513 * through the BDs and adjust tbptr to point to the last BD
514 * marked as ready. This may result in some buffers being
515 * retransmitted.
513 */ 516 */
514static void tx_restart(struct net_device *dev) 517static void tx_restart(struct net_device *dev)
515{ 518{
516 struct fs_enet_private *fep = netdev_priv(dev); 519 struct fs_enet_private *fep = netdev_priv(dev);
517 fcc_t __iomem *fccp = fep->fcc.fccp; 520 fcc_t __iomem *fccp = fep->fcc.fccp;
521 const struct fs_platform_info *fpi = fep->fpi;
522 fcc_enet_t __iomem *ep = fep->fcc.ep;
523 cbd_t __iomem *curr_tbptr;
524 cbd_t __iomem *recheck_bd;
525 cbd_t __iomem *prev_bd;
526 cbd_t __iomem *last_tx_bd;
527
528 last_tx_bd = fep->tx_bd_base + (fpi->tx_ring * sizeof(cbd_t));
529
530 /* get the current bd held in TBPTR and scan back from this point */
531 recheck_bd = curr_tbptr = (cbd_t __iomem *)
532 ((R32(ep, fen_genfcc.fcc_tbptr) - fep->ring_mem_addr) +
533 fep->ring_base);
534
535 prev_bd = (recheck_bd == fep->tx_bd_base) ? last_tx_bd : recheck_bd - 1;
536
537 /* Move through the bds in reverse, look for the earliest buffer
538 * that is not ready. Adjust TBPTR to the following buffer */
539 while ((CBDR_SC(prev_bd) & BD_ENET_TX_READY) != 0) {
540 /* Go back one buffer */
541 recheck_bd = prev_bd;
542
543 /* update the previous buffer */
544 prev_bd = (prev_bd == fep->tx_bd_base) ? last_tx_bd : prev_bd - 1;
545
546 /* We should never see all bds marked as ready, check anyway */
547 if (recheck_bd == curr_tbptr)
548 break;
549 }
550 /* Now update the TBPTR and dirty flag to the current buffer */
551 W32(ep, fen_genfcc.fcc_tbptr,
552 (uint) (((void *)recheck_bd - fep->ring_base) +
553 fep->ring_mem_addr));
554 fep->dirty_tx = recheck_bd;
518 555
519 C32(fccp, fcc_gfmr, FCC_GFMR_ENT); 556 C32(fccp, fcc_gfmr, FCC_GFMR_ENT);
520 udelay(10); 557 udelay(10);
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 0f90685d3d19..3607340f3da7 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -169,7 +169,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
169 169
170 new_bus->name = "CPM2 Bitbanged MII", 170 new_bus->name = "CPM2 Bitbanged MII",
171 171
172 ret = fs_mii_bitbang_init(new_bus, ofdev->node); 172 ret = fs_mii_bitbang_init(new_bus, ofdev->dev.of_node);
173 if (ret) 173 if (ret)
174 goto out_free_bus; 174 goto out_free_bus;
175 175
@@ -181,7 +181,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
181 new_bus->parent = &ofdev->dev; 181 new_bus->parent = &ofdev->dev;
182 dev_set_drvdata(&ofdev->dev, new_bus); 182 dev_set_drvdata(&ofdev->dev, new_bus);
183 183
184 ret = of_mdiobus_register(new_bus, ofdev->node); 184 ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
185 if (ret) 185 if (ret)
186 goto out_free_irqs; 186 goto out_free_irqs;
187 187
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index f37a4c143ddd..3a029d02c2b4 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -1607,14 +1607,13 @@ static struct of_device_id greth_of_match[] = {
1607MODULE_DEVICE_TABLE(of, greth_of_match); 1607MODULE_DEVICE_TABLE(of, greth_of_match);
1608 1608
1609static struct of_platform_driver greth_of_driver = { 1609static struct of_platform_driver greth_of_driver = {
1610 .name = "grlib-greth", 1610 .driver = {
1611 .match_table = greth_of_match, 1611 .name = "grlib-greth",
1612 .owner = THIS_MODULE,
1613 .of_match_table = greth_of_match,
1614 },
1612 .probe = greth_of_probe, 1615 .probe = greth_of_probe,
1613 .remove = __devexit_p(greth_of_remove), 1616 .remove = __devexit_p(greth_of_remove),
1614 .driver = {
1615 .owner = THIS_MODULE,
1616 .name = "grlib-greth",
1617 },
1618}; 1617};
1619 1618
1620static int __init greth_init(void) 1619static int __init greth_init(void)
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 1159d9138f05..9595b1bfb8dd 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1188,6 +1188,7 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
1188 IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 1188 IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
1189 } else { 1189 } else {
1190 hw_dbg(hw, "RAR index %d is out of range.\n", index); 1190 hw_dbg(hw, "RAR index %d is out of range.\n", index);
1191 return IXGBE_ERR_RAR_INDEX;
1191 } 1192 }
1192 1193
1193 return 0; 1194 return 0;
@@ -1219,6 +1220,7 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
1219 IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 1220 IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
1220 } else { 1221 } else {
1221 hw_dbg(hw, "RAR index %d is out of range.\n", index); 1222 hw_dbg(hw, "RAR index %d is out of range.\n", index);
1223 return IXGBE_ERR_RAR_INDEX;
1222 } 1224 }
1223 1225
1224 /* clear VMDq pool/queue selection for this RAR */ 1226 /* clear VMDq pool/queue selection for this RAR */
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index d571d101de08..b2af2f67f604 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -642,7 +642,7 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter,
642 u32 txoff = IXGBE_TFCS_TXOFF; 642 u32 txoff = IXGBE_TFCS_TXOFF;
643 643
644#ifdef CONFIG_IXGBE_DCB 644#ifdef CONFIG_IXGBE_DCB
645 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 645 if (adapter->dcb_cfg.pfc_mode_enable) {
646 int tc; 646 int tc;
647 int reg_idx = tx_ring->reg_idx; 647 int reg_idx = tx_ring->reg_idx;
648 int dcb_i = adapter->ring_feature[RING_F_DCB].indices; 648 int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 2eb6e151016c..cdd1998f18c7 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -2609,6 +2609,7 @@ struct ixgbe_info {
2609#define IXGBE_ERR_EEPROM_VERSION -24 2609#define IXGBE_ERR_EEPROM_VERSION -24
2610#define IXGBE_ERR_NO_SPACE -25 2610#define IXGBE_ERR_NO_SPACE -25
2611#define IXGBE_ERR_OVERTEMP -26 2611#define IXGBE_ERR_OVERTEMP -26
2612#define IXGBE_ERR_RAR_INDEX -27
2612#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF 2613#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
2613 2614
2614#endif /* _IXGBE_TYPE_H_ */ 2615#endif /* _IXGBE_TYPE_H_ */
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 26bf1b76b997..c7a9bef4dfb0 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -135,6 +135,7 @@ struct korina_private {
135 struct napi_struct napi; 135 struct napi_struct napi;
136 struct timer_list media_check_timer; 136 struct timer_list media_check_timer;
137 struct mii_if_info mii_if; 137 struct mii_if_info mii_if;
138 struct work_struct restart_task;
138 struct net_device *dev; 139 struct net_device *dev;
139 int phy_addr; 140 int phy_addr;
140}; 141};
@@ -375,7 +376,7 @@ static int korina_rx(struct net_device *dev, int limit)
375 if (devcs & ETH_RX_LE) 376 if (devcs & ETH_RX_LE)
376 dev->stats.rx_length_errors++; 377 dev->stats.rx_length_errors++;
377 if (devcs & ETH_RX_OVR) 378 if (devcs & ETH_RX_OVR)
378 dev->stats.rx_over_errors++; 379 dev->stats.rx_fifo_errors++;
379 if (devcs & ETH_RX_CV) 380 if (devcs & ETH_RX_CV)
380 dev->stats.rx_frame_errors++; 381 dev->stats.rx_frame_errors++;
381 if (devcs & ETH_RX_CES) 382 if (devcs & ETH_RX_CES)
@@ -764,10 +765,9 @@ static int korina_alloc_ring(struct net_device *dev)
764 765
765 /* Initialize the receive descriptors */ 766 /* Initialize the receive descriptors */
766 for (i = 0; i < KORINA_NUM_RDS; i++) { 767 for (i = 0; i < KORINA_NUM_RDS; i++) {
767 skb = dev_alloc_skb(KORINA_RBSIZE + 2); 768 skb = netdev_alloc_skb_ip_align(dev, KORINA_RBSIZE);
768 if (!skb) 769 if (!skb)
769 return -ENOMEM; 770 return -ENOMEM;
770 skb_reserve(skb, 2);
771 lp->rx_skb[i] = skb; 771 lp->rx_skb[i] = skb;
772 lp->rd_ring[i].control = DMA_DESC_IOD | 772 lp->rd_ring[i].control = DMA_DESC_IOD |
773 DMA_COUNT(KORINA_RBSIZE); 773 DMA_COUNT(KORINA_RBSIZE);
@@ -890,12 +890,12 @@ static int korina_init(struct net_device *dev)
890 890
891/* 891/*
892 * Restart the RC32434 ethernet controller. 892 * Restart the RC32434 ethernet controller.
893 * FIXME: check the return status where we call it
894 */ 893 */
895static int korina_restart(struct net_device *dev) 894static void korina_restart_task(struct work_struct *work)
896{ 895{
897 struct korina_private *lp = netdev_priv(dev); 896 struct korina_private *lp = container_of(work,
898 int ret; 897 struct korina_private, restart_task);
898 struct net_device *dev = lp->dev;
899 899
900 /* 900 /*
901 * Disable interrupts 901 * Disable interrupts
@@ -916,10 +916,9 @@ static int korina_restart(struct net_device *dev)
916 916
917 napi_disable(&lp->napi); 917 napi_disable(&lp->napi);
918 918
919 ret = korina_init(dev); 919 if (korina_init(dev) < 0) {
920 if (ret < 0) {
921 printk(KERN_ERR "%s: cannot restart device\n", dev->name); 920 printk(KERN_ERR "%s: cannot restart device\n", dev->name);
922 return ret; 921 return;
923 } 922 }
924 korina_multicast_list(dev); 923 korina_multicast_list(dev);
925 924
@@ -927,8 +926,6 @@ static int korina_restart(struct net_device *dev)
927 enable_irq(lp->ovr_irq); 926 enable_irq(lp->ovr_irq);
928 enable_irq(lp->tx_irq); 927 enable_irq(lp->tx_irq);
929 enable_irq(lp->rx_irq); 928 enable_irq(lp->rx_irq);
930
931 return ret;
932} 929}
933 930
934static void korina_clear_and_restart(struct net_device *dev, u32 value) 931static void korina_clear_and_restart(struct net_device *dev, u32 value)
@@ -937,7 +934,7 @@ static void korina_clear_and_restart(struct net_device *dev, u32 value)
937 934
938 netif_stop_queue(dev); 935 netif_stop_queue(dev);
939 writel(value, &lp->eth_regs->ethintfc); 936 writel(value, &lp->eth_regs->ethintfc);
940 korina_restart(dev); 937 schedule_work(&lp->restart_task);
941} 938}
942 939
943/* Ethernet Tx Underflow interrupt */ 940/* Ethernet Tx Underflow interrupt */
@@ -962,11 +959,8 @@ static irqreturn_t korina_und_interrupt(int irq, void *dev_id)
962static void korina_tx_timeout(struct net_device *dev) 959static void korina_tx_timeout(struct net_device *dev)
963{ 960{
964 struct korina_private *lp = netdev_priv(dev); 961 struct korina_private *lp = netdev_priv(dev);
965 unsigned long flags;
966 962
967 spin_lock_irqsave(&lp->lock, flags); 963 schedule_work(&lp->restart_task);
968 korina_restart(dev);
969 spin_unlock_irqrestore(&lp->lock, flags);
970} 964}
971 965
972/* Ethernet Rx Overflow interrupt */ 966/* Ethernet Rx Overflow interrupt */
@@ -1086,6 +1080,8 @@ static int korina_close(struct net_device *dev)
1086 1080
1087 napi_disable(&lp->napi); 1081 napi_disable(&lp->napi);
1088 1082
1083 cancel_work_sync(&lp->restart_task);
1084
1089 free_irq(lp->rx_irq, dev); 1085 free_irq(lp->rx_irq, dev);
1090 free_irq(lp->tx_irq, dev); 1086 free_irq(lp->tx_irq, dev);
1091 free_irq(lp->ovr_irq, dev); 1087 free_irq(lp->ovr_irq, dev);
@@ -1198,6 +1194,8 @@ static int korina_probe(struct platform_device *pdev)
1198 } 1194 }
1199 setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev); 1195 setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev);
1200 1196
1197 INIT_WORK(&lp->restart_task, korina_restart_task);
1198
1201 printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n", 1199 printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
1202 dev->name); 1200 dev->name);
1203out: 1201out:
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index c80ca64277b2..7805bbf1d53a 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -4854,7 +4854,7 @@ static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb)
4854 * 4854 *
4855 * Return 0 if successful; otherwise an error code indicating failure. 4855 * Return 0 if successful; otherwise an error code indicating failure.
4856 */ 4856 */
4857static int netdev_tx(struct sk_buff *skb, struct net_device *dev) 4857static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
4858{ 4858{
4859 struct dev_priv *priv = netdev_priv(dev); 4859 struct dev_priv *priv = netdev_priv(dev);
4860 struct dev_info *hw_priv = priv->adapter; 4860 struct dev_info *hw_priv = priv->adapter;
@@ -6863,6 +6863,7 @@ static const struct net_device_ops netdev_ops = {
6863 .ndo_tx_timeout = netdev_tx_timeout, 6863 .ndo_tx_timeout = netdev_tx_timeout,
6864 .ndo_change_mtu = netdev_change_mtu, 6864 .ndo_change_mtu = netdev_change_mtu,
6865 .ndo_set_mac_address = netdev_set_mac_address, 6865 .ndo_set_mac_address = netdev_set_mac_address,
6866 .ndo_validate_addr = eth_validate_addr,
6866 .ndo_do_ioctl = netdev_ioctl, 6867 .ndo_do_ioctl = netdev_ioctl,
6867 .ndo_set_rx_mode = netdev_set_rx_mode, 6868 .ndo_set_rx_mode = netdev_set_rx_mode,
6868#ifdef CONFIG_NET_POLL_CONTROLLER 6869#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index b6855a6476f8..1c5221f79d6f 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -997,8 +997,11 @@ MODULE_DEVICE_TABLE (of, mace_match);
997 997
998static struct macio_driver mace_driver = 998static struct macio_driver mace_driver =
999{ 999{
1000 .name = "mace", 1000 .driver = {
1001 .match_table = mace_match, 1001 .name = "mace",
1002 .owner = THIS_MODULE,
1003 .of_match_table = mace_match,
1004 },
1002 .probe = mace_probe, 1005 .probe = mace_probe,
1003 .remove = mace_remove, 1006 .remove = mace_remove,
1004}; 1007};
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index c5f8eb102bf7..1b2c29150202 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1422,7 +1422,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1422 flen = len; 1422 flen = len;
1423 if (nfree > 0) { 1423 if (nfree > 0) {
1424 if (pch->speed == 0) { 1424 if (pch->speed == 0) {
1425 flen = totlen/nfree; 1425 flen = len/nfree;
1426 if (nbigger > 0) { 1426 if (nbigger > 0) {
1427 flen++; 1427 flen++;
1428 nbigger--; 1428 nbigger--;
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 2e6fd89f2a72..4762c91cb587 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -830,7 +830,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx)
830 830
831static inline unsigned int efx_port_num(struct efx_nic *efx) 831static inline unsigned int efx_port_num(struct efx_nic *efx)
832{ 832{
833 return PCI_FUNC(efx->pci_dev->devfn); 833 return efx->net_dev->dev_id;
834} 834}
835 835
836/** 836/**
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c
index 727b4228e081..f2b1e6180753 100644
--- a/drivers/net/sfc/siena.c
+++ b/drivers/net/sfc/siena.c
@@ -206,6 +206,7 @@ static int siena_probe_nic(struct efx_nic *efx)
206{ 206{
207 struct siena_nic_data *nic_data; 207 struct siena_nic_data *nic_data;
208 bool already_attached = 0; 208 bool already_attached = 0;
209 efx_oword_t reg;
209 int rc; 210 int rc;
210 211
211 /* Allocate storage for hardware specific data */ 212 /* Allocate storage for hardware specific data */
@@ -220,6 +221,9 @@ static int siena_probe_nic(struct efx_nic *efx)
220 goto fail1; 221 goto fail1;
221 } 222 }
222 223
224 efx_reado(efx, &reg, FR_AZ_CS_DEBUG);
225 efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
226
223 efx_mcdi_init(efx); 227 efx_mcdi_init(efx);
224 228
225 /* Recover from a failed assertion before probing */ 229 /* Recover from a failed assertion before probing */
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 20ab16192325..737df6032bbc 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -646,7 +646,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
646 error = copy_from_user(data, ifr->ifr_data, sizeof(data)); 646 error = copy_from_user(data, ifr->ifr_data, sizeof(data));
647 if (error) { 647 if (error) {
648 pr_err("cant copy from user\n"); 648 pr_err("cant copy from user\n");
649 RET(error); 649 RET(-EFAULT);
650 } 650 }
651 DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); 651 DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
652 } 652 }
@@ -665,7 +665,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
665 data[2]); 665 data[2]);
666 error = copy_to_user(ifr->ifr_data, data, sizeof(data)); 666 error = copy_to_user(ifr->ifr_data, data, sizeof(data));
667 if (error) 667 if (error)
668 RET(error); 668 RET(-EFAULT);
669 break; 669 break;
670 670
671 case BDX_OP_WRITE: 671 case BDX_OP_WRITE:
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 78eb3190b9b1..1edb7a61983c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -340,7 +340,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
340 340
341 skb_to_sgvec(skb, vi->rx_sg + 1, 0, skb->len); 341 skb_to_sgvec(skb, vi->rx_sg + 1, 0, skb->len);
342 342
343 err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, 2, skb); 343 err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, 2, skb, gfp);
344 if (err < 0) 344 if (err < 0)
345 dev_kfree_skb(skb); 345 dev_kfree_skb(skb);
346 346
@@ -385,8 +385,8 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
385 385
386 /* chain first in list head */ 386 /* chain first in list head */
387 first->private = (unsigned long)list; 387 first->private = (unsigned long)list;
388 err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2, 388 err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2,
389 first); 389 first, gfp);
390 if (err < 0) 390 if (err < 0)
391 give_pages(vi, first); 391 give_pages(vi, first);
392 392
@@ -404,7 +404,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)
404 404
405 sg_init_one(vi->rx_sg, page_address(page), PAGE_SIZE); 405 sg_init_one(vi->rx_sg, page_address(page), PAGE_SIZE);
406 406
407 err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, 1, page); 407 err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, 1, page, gfp);
408 if (err < 0) 408 if (err < 0)
409 give_pages(vi, page); 409 give_pages(vi, page);
410 410
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 166e77dfffda..e47f5a986b1c 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -37,8 +37,6 @@
37#include <net/x25device.h> 37#include <net/x25device.h>
38#include "x25_asy.h" 38#include "x25_asy.h"
39 39
40#include <net/x25device.h>
41
42static struct net_device **x25_asy_devs; 40static struct net_device **x25_asy_devs;
43static int x25_asy_maxdev = SL_NRUNIT; 41static int x25_asy_maxdev = SL_NRUNIT;
44 42
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index 82ab532a4923..a93dc18a45c3 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -739,17 +739,27 @@ err_out:
739static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) 739static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
740{ 740{
741 struct device *parent = aru->udev->dev.parent; 741 struct device *parent = aru->udev->dev.parent;
742 struct usb_device *udev;
743
744 /*
745 * Store a copy of the usb_device pointer locally.
746 * This is because device_release_driver initiates
747 * ar9170_usb_disconnect, which in turn frees our
748 * driver context (aru).
749 */
750 udev = aru->udev;
742 751
743 complete(&aru->firmware_loading_complete); 752 complete(&aru->firmware_loading_complete);
744 753
745 /* unbind anything failed */ 754 /* unbind anything failed */
746 if (parent) 755 if (parent)
747 device_lock(parent); 756 device_lock(parent);
748 device_release_driver(&aru->udev->dev); 757
758 device_release_driver(&udev->dev);
749 if (parent) 759 if (parent)
750 device_unlock(parent); 760 device_unlock(parent);
751 761
752 usb_put_dev(aru->udev); 762 usb_put_dev(udev);
753} 763}
754 764
755static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) 765static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index cc6d41dec332..2978359c4366 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -222,7 +222,6 @@ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
222static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, 222static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
223 struct ath5k_txq *txq); 223 struct ath5k_txq *txq);
224static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); 224static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
225static int ath5k_reset_wake(struct ath5k_softc *sc);
226static int ath5k_start(struct ieee80211_hw *hw); 225static int ath5k_start(struct ieee80211_hw *hw);
227static void ath5k_stop(struct ieee80211_hw *hw); 226static void ath5k_stop(struct ieee80211_hw *hw);
228static int ath5k_add_interface(struct ieee80211_hw *hw, 227static int ath5k_add_interface(struct ieee80211_hw *hw,
@@ -2770,7 +2769,7 @@ ath5k_tasklet_reset(unsigned long data)
2770{ 2769{
2771 struct ath5k_softc *sc = (void *)data; 2770 struct ath5k_softc *sc = (void *)data;
2772 2771
2773 ath5k_reset_wake(sc); 2772 ath5k_reset(sc, sc->curchan);
2774} 2773}
2775 2774
2776/* 2775/*
@@ -2941,23 +2940,13 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
2941 ath5k_beacon_config(sc); 2940 ath5k_beacon_config(sc);
2942 /* intrs are enabled by ath5k_beacon_config */ 2941 /* intrs are enabled by ath5k_beacon_config */
2943 2942
2943 ieee80211_wake_queues(sc->hw);
2944
2944 return 0; 2945 return 0;
2945err: 2946err:
2946 return ret; 2947 return ret;
2947} 2948}
2948 2949
2949static int
2950ath5k_reset_wake(struct ath5k_softc *sc)
2951{
2952 int ret;
2953
2954 ret = ath5k_reset(sc, sc->curchan);
2955 if (!ret)
2956 ieee80211_wake_queues(sc->hw);
2957
2958 return ret;
2959}
2960
2961static int ath5k_start(struct ieee80211_hw *hw) 2950static int ath5k_start(struct ieee80211_hw *hw)
2962{ 2951{
2963 return ath5k_init(hw->priv); 2952 return ath5k_init(hw->priv);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 3db19172b43b..859aa4ab0769 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1198,7 +1198,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1198 int r; 1198 int r;
1199 1199
1200 ath_print(common, ATH_DBG_FATAL, 1200 ath_print(common, ATH_DBG_FATAL,
1201 "Unable to stop TxDMA. Reset HAL!\n"); 1201 "Failed to stop TX DMA. Resetting hardware!\n");
1202 1202
1203 spin_lock_bh(&sc->sc_resetlock); 1203 spin_lock_bh(&sc->sc_resetlock);
1204 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); 1204 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
@@ -1728,6 +1728,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1728 } else 1728 } else
1729 bf->bf_isnullfunc = false; 1729 bf->bf_isnullfunc = false;
1730 1730
1731 bf->bf_tx_aborted = false;
1732
1731 return 0; 1733 return 0;
1732} 1734}
1733 1735
@@ -1989,7 +1991,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1989 int nbad = 0; 1991 int nbad = 0;
1990 int isaggr = 0; 1992 int isaggr = 0;
1991 1993
1992 if (bf->bf_tx_aborted) 1994 if (bf->bf_lastbf->bf_tx_aborted)
1993 return 0; 1995 return 0;
1994 1996
1995 isaggr = bf_isaggr(bf); 1997 isaggr = bf_isaggr(bf);
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index a115bfa9513a..7a377f5b7662 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -329,9 +329,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
329 /* create the exported radio header */ 329 /* create the exported radio header */
330 330
331 /* radiotap header */ 331 /* radiotap header */
332 radiotap_hdr.hdr.it_version = 0; 332 memset(&radiotap_hdr, 0, sizeof(radiotap_hdr));
333 /* XXX must check this value for pad */ 333 /* XXX must check radiotap_hdr.hdr.it_pad for pad */
334 radiotap_hdr.hdr.it_pad = 0;
335 radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr)); 334 radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
336 radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT); 335 radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
337 radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate); 336 radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 9bcee10c9308..4a0a0e5265c9 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -239,8 +239,11 @@ static struct of_device_id airport_match[] =
239MODULE_DEVICE_TABLE(of, airport_match); 239MODULE_DEVICE_TABLE(of, airport_match);
240 240
241static struct macio_driver airport_driver = { 241static struct macio_driver airport_driver = {
242 .name = DRIVER_NAME, 242 .driver = {
243 .match_table = airport_match, 243 .name = DRIVER_NAME,
244 .owner = THIS_MODULE,
245 .of_match_table = airport_match,
246 },
244 .probe = airport_attach, 247 .probe = airport_attach,
245 .remove = airport_detach, 248 .remove = airport_detach,
246 .suspend = airport_suspend, 249 .suspend = airport_suspend,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 699161327d65..0f8b84b7224c 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -413,7 +413,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
413 */ 413 */
414 rt2x00_desc_read(txi, 0, &word); 414 rt2x00_desc_read(txi, 0, &word);
415 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, 415 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
416 skb->len - TXINFO_DESC_SIZE); 416 skb->len + TXWI_DESC_SIZE);
417 rt2x00_set_field32(&word, TXINFO_W0_WIV, 417 rt2x00_set_field32(&word, TXINFO_W0_WIV,
418 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); 418 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
419 rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); 419 rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 1a648b90b634..25e5e30a18af 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -1157,7 +1157,7 @@ static int __init m8xx_probe(struct of_device *ofdev,
1157 unsigned int i, m, hwirq; 1157 unsigned int i, m, hwirq;
1158 pcmconf8xx_t *pcmcia; 1158 pcmconf8xx_t *pcmcia;
1159 int status; 1159 int status;
1160 struct device_node *np = ofdev->node; 1160 struct device_node *np = ofdev->dev.of_node;
1161 1161
1162 pcmcia_info("%s\n", version); 1162 pcmcia_info("%s\n", version);
1163 1163
@@ -1301,7 +1301,7 @@ static struct of_platform_driver m8xx_pcmcia_driver = {
1301 .driver = { 1301 .driver = {
1302 .name = driver_name, 1302 .name = driver_name,
1303 .owner = THIS_MODULE, 1303 .owner = THIS_MODULE,
1304 .match_table = m8xx_pcmcia_match, 1304 .of_match_table = m8xx_pcmcia_match,
1305 }, 1305 },
1306 .probe = m8xx_probe, 1306 .probe = m8xx_probe,
1307 .remove = m8xx_remove, 1307 .remove = m8xx_remove,
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 576c3ed92435..40658e3385b4 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -524,7 +524,7 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
524 for (i = 0; i < inlen; i++) 524 for (i = 0; i < inlen; i++)
525 ipc_data_writel(*in++, 4 * i); 525 ipc_data_writel(*in++, 4 * i);
526 526
527 ipc_command(cmd << 12 | sub); 527 ipc_command((cmd << 12) | sub | (inlen << 18));
528 err = busy_loop(); 528 err = busy_loop();
529 529
530 for (i = 0; i < outlen; i++) 530 for (i = 0; i < outlen; i++)
diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c
index f3e22c9fe20a..2f2f9a6f54fa 100644
--- a/drivers/power/max17040_battery.c
+++ b/drivers/power/max17040_battery.c
@@ -225,7 +225,6 @@ static int __devinit max17040_probe(struct i2c_client *client,
225 ret = power_supply_register(&client->dev, &chip->battery); 225 ret = power_supply_register(&client->dev, &chip->battery);
226 if (ret) { 226 if (ret) {
227 dev_err(&client->dev, "failed: power supply register\n"); 227 dev_err(&client->dev, "failed: power supply register\n");
228 i2c_set_clientdata(client, NULL);
229 kfree(chip); 228 kfree(chip);
230 return ret; 229 return ret;
231 } 230 }
@@ -245,7 +244,6 @@ static int __devexit max17040_remove(struct i2c_client *client)
245 244
246 power_supply_unregister(&chip->battery); 245 power_supply_unregister(&chip->battery);
247 cancel_delayed_work(&chip->work); 246 cancel_delayed_work(&chip->work);
248 i2c_set_clientdata(client, NULL);
249 kfree(chip); 247 kfree(chip);
250 return 0; 248 return 0;
251} 249}
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
index 671a7d1f1f0e..8ae3732eb24b 100644
--- a/drivers/regulator/lp3971.c
+++ b/drivers/regulator/lp3971.c
@@ -519,8 +519,6 @@ static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
519 struct lp3971 *lp3971 = i2c_get_clientdata(i2c); 519 struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
520 int i; 520 int i;
521 521
522 i2c_set_clientdata(i2c, NULL);
523
524 for (i = 0; i < lp3971->num_regulators; i++) 522 for (i = 0; i < lp3971->num_regulators; i++)
525 regulator_unregister(lp3971->rdev[i]); 523 regulator_unregister(lp3971->rdev[i]);
526 524
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index b3c1afc16889..2b54d9d75f11 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -244,7 +244,6 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client)
244 for (i = 0; i <= MAX1586_V6; i++) 244 for (i = 0; i <= MAX1586_V6; i++)
245 if (rdev[i]) 245 if (rdev[i])
246 regulator_unregister(rdev[i]); 246 regulator_unregister(rdev[i]);
247 i2c_set_clientdata(client, NULL);
248 kfree(rdev); 247 kfree(rdev);
249 248
250 return 0; 249 return 0;
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index bfc4c5ffdc96..4520ace3f7e7 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -357,7 +357,6 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
357 dev_info(info->dev, "Max8649 regulator device is detected.\n"); 357 dev_info(info->dev, "Max8649 regulator device is detected.\n");
358 return 0; 358 return 0;
359out: 359out:
360 i2c_set_clientdata(client, NULL);
361 kfree(info); 360 kfree(info);
362 return ret; 361 return ret;
363} 362}
@@ -369,7 +368,6 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
369 if (info) { 368 if (info) {
370 if (info->regulator) 369 if (info->regulator)
371 regulator_unregister(info->regulator); 370 regulator_unregister(info->regulator);
372 i2c_set_clientdata(client, NULL);
373 kfree(info); 371 kfree(info);
374 } 372 }
375 373
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c
index 3790b21879ff..d97220efae5a 100644
--- a/drivers/regulator/max8660.c
+++ b/drivers/regulator/max8660.c
@@ -471,7 +471,6 @@ static int __devexit max8660_remove(struct i2c_client *client)
471 for (i = 0; i < MAX8660_V_END; i++) 471 for (i = 0; i < MAX8660_V_END; i++)
472 if (rdev[i]) 472 if (rdev[i])
473 regulator_unregister(rdev[i]); 473 regulator_unregister(rdev[i]);
474 i2c_set_clientdata(client, NULL);
475 kfree(rdev); 474 kfree(rdev);
476 475
477 return 0; 476 return 0;
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 8e2f2098b005..f50afc9f287a 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -538,9 +538,6 @@ static int __devexit tps_65023_remove(struct i2c_client *client)
538 struct tps_pmic *tps = i2c_get_clientdata(client); 538 struct tps_pmic *tps = i2c_get_clientdata(client);
539 int i; 539 int i;
540 540
541 /* clear the client data in i2c */
542 i2c_set_clientdata(client, NULL);
543
544 for (i = 0; i < TPS65023_NUM_REGULATOR; i++) 541 for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
545 regulator_unregister(tps->rdev[i]); 542 regulator_unregister(tps->rdev[i]);
546 543
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 61945734ad00..1f0007fd4431 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -403,7 +403,6 @@ out_irq:
403 free_irq(client->irq, client); 403 free_irq(client->irq, client);
404 404
405out_free: 405out_free:
406 i2c_set_clientdata(client, NULL);
407 kfree(ds1374); 406 kfree(ds1374);
408 return ret; 407 return ret;
409} 408}
@@ -422,7 +421,6 @@ static int __devexit ds1374_remove(struct i2c_client *client)
422 } 421 }
423 422
424 rtc_device_unregister(ds1374->rtc); 423 rtc_device_unregister(ds1374->rtc);
425 i2c_set_clientdata(client, NULL);
426 kfree(ds1374); 424 kfree(ds1374);
427 return 0; 425 return 0;
428} 426}
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
index f0dbf9cb8f9c..db5d8c416d26 100644
--- a/drivers/rtc/rtc-mpc5121.c
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -279,7 +279,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op,
279 if (!rtc) 279 if (!rtc)
280 return -ENOMEM; 280 return -ENOMEM;
281 281
282 rtc->regs = of_iomap(op->node, 0); 282 rtc->regs = of_iomap(op->dev.of_node, 0);
283 if (!rtc->regs) { 283 if (!rtc->regs) {
284 dev_err(&op->dev, "%s: couldn't map io space\n", __func__); 284 dev_err(&op->dev, "%s: couldn't map io space\n", __func__);
285 err = -ENOSYS; 285 err = -ENOSYS;
@@ -290,7 +290,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op,
290 290
291 dev_set_drvdata(&op->dev, rtc); 291 dev_set_drvdata(&op->dev, rtc);
292 292
293 rtc->irq = irq_of_parse_and_map(op->node, 1); 293 rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1);
294 err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED, 294 err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED,
295 "mpc5121-rtc", &op->dev); 295 "mpc5121-rtc", &op->dev);
296 if (err) { 296 if (err) {
@@ -299,7 +299,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op,
299 goto out_dispose; 299 goto out_dispose;
300 } 300 }
301 301
302 rtc->irq_periodic = irq_of_parse_and_map(op->node, 0); 302 rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0);
303 err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd, 303 err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd,
304 IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev); 304 IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev);
305 if (err) { 305 if (err) {
@@ -365,9 +365,11 @@ static struct of_device_id mpc5121_rtc_match[] __devinitdata = {
365}; 365};
366 366
367static struct of_platform_driver mpc5121_rtc_driver = { 367static struct of_platform_driver mpc5121_rtc_driver = {
368 .owner = THIS_MODULE, 368 .driver = {
369 .name = "mpc5121-rtc", 369 .name = "mpc5121-rtc",
370 .match_table = mpc5121_rtc_match, 370 .owner = THIS_MODULE,
371 .of_match_table = mpc5121_rtc_match,
372 },
371 .probe = mpc5121_rtc_probe, 373 .probe = mpc5121_rtc_probe,
372 .remove = __devexit_p(mpc5121_rtc_remove), 374 .remove = __devexit_p(mpc5121_rtc_remove),
373}; 375};
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index b65c82f792d9..789f62f9b47d 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -632,7 +632,6 @@ errout_reg:
632 rtc_device_unregister(rx8025->rtc); 632 rtc_device_unregister(rx8025->rtc);
633 633
634errout_free: 634errout_free:
635 i2c_set_clientdata(client, NULL);
636 kfree(rx8025); 635 kfree(rx8025);
637 636
638errout: 637errout:
@@ -656,7 +655,6 @@ static int __devexit rx8025_remove(struct i2c_client *client)
656 655
657 rx8025_sysfs_unregister(&client->dev); 656 rx8025_sysfs_unregister(&client->dev);
658 rtc_device_unregister(rx8025->rtc); 657 rtc_device_unregister(rx8025->rtc);
659 i2c_set_clientdata(client, NULL);
660 kfree(rx8025); 658 kfree(rx8025);
661 return 0; 659 return 0;
662} 660}
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index def4d396d0b0..f789e002c9b0 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -275,7 +275,6 @@ exit_dummy:
275 if (s35390a->client[i]) 275 if (s35390a->client[i])
276 i2c_unregister_device(s35390a->client[i]); 276 i2c_unregister_device(s35390a->client[i]);
277 kfree(s35390a); 277 kfree(s35390a);
278 i2c_set_clientdata(client, NULL);
279 278
280exit: 279exit:
281 return err; 280 return err;
@@ -292,7 +291,6 @@ static int s35390a_remove(struct i2c_client *client)
292 291
293 rtc_device_unregister(s35390a->rtc); 292 rtc_device_unregister(s35390a->rtc);
294 kfree(s35390a); 293 kfree(s35390a);
295 i2c_set_clientdata(client, NULL);
296 294
297 return 0; 295 return 0;
298} 296}
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index e5972b2c17b7..70b68d35f969 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -495,8 +495,6 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
495 pr_debug("s3c2410_rtc: RTCCON=%02x\n", 495 pr_debug("s3c2410_rtc: RTCCON=%02x\n",
496 readb(s3c_rtc_base + S3C2410_RTCCON)); 496 readb(s3c_rtc_base + S3C2410_RTCCON));
497 497
498 s3c_rtc_setfreq(&pdev->dev, 1);
499
500 device_init_wakeup(&pdev->dev, 1); 498 device_init_wakeup(&pdev->dev, 1);
501 499
502 /* register RTC and exit */ 500 /* register RTC and exit */
@@ -510,14 +508,17 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
510 goto err_nortc; 508 goto err_nortc;
511 } 509 }
512 510
511 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
512
513 if (s3c_rtc_cpu_type == TYPE_S3C64XX) 513 if (s3c_rtc_cpu_type == TYPE_S3C64XX)
514 rtc->max_user_freq = 32768; 514 rtc->max_user_freq = 32768;
515 else 515 else
516 rtc->max_user_freq = 128; 516 rtc->max_user_freq = 128;
517 517
518 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
519
520 platform_set_drvdata(pdev, rtc); 518 platform_set_drvdata(pdev, rtc);
519
520 s3c_rtc_setfreq(&pdev->dev, 1);
521
521 return 0; 522 return 0;
522 523
523 err_nortc: 524 err_nortc:
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 18735b39b3d3..3ddb4dc62d5d 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -542,8 +542,11 @@ MODULE_DEVICE_TABLE (of, mac53c94_match);
542 542
543static struct macio_driver mac53c94_driver = 543static struct macio_driver mac53c94_driver =
544{ 544{
545 .name = "mac53c94", 545 .driver = {
546 .match_table = mac53c94_match, 546 .name = "mac53c94",
547 .owner = THIS_MODULE,
548 .of_match_table = mac53c94_match,
549 },
547 .probe = mac53c94_probe, 550 .probe = mac53c94_probe,
548 .remove = mac53c94_remove, 551 .remove = mac53c94_remove,
549}; 552};
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index a1c97e88068a..1f784fde2510 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -2036,8 +2036,11 @@ MODULE_DEVICE_TABLE (of, mesh_match);
2036 2036
2037static struct macio_driver mesh_driver = 2037static struct macio_driver mesh_driver =
2038{ 2038{
2039 .name = "mesh", 2039 .driver = {
2040 .match_table = mesh_match, 2040 .name = "mesh",
2041 .owner = THIS_MODULE,
2042 .of_match_table = mesh_match,
2043 },
2041 .probe = mesh_probe, 2044 .probe = mesh_probe,
2042 .remove = mesh_remove, 2045 .remove = mesh_remove,
2043 .shutdown = mesh_shutdown, 2046 .shutdown = mesh_shutdown,
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 829cc37abc41..8802e48bc063 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -97,6 +97,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
97#endif 97#endif
98 98
99static int sd_revalidate_disk(struct gendisk *); 99static int sd_revalidate_disk(struct gendisk *);
100static void sd_unlock_native_capacity(struct gendisk *disk);
100static int sd_probe(struct device *); 101static int sd_probe(struct device *);
101static int sd_remove(struct device *); 102static int sd_remove(struct device *);
102static void sd_shutdown(struct device *); 103static void sd_shutdown(struct device *);
@@ -1101,6 +1102,7 @@ static const struct block_device_operations sd_fops = {
1101#endif 1102#endif
1102 .media_changed = sd_media_changed, 1103 .media_changed = sd_media_changed,
1103 .revalidate_disk = sd_revalidate_disk, 1104 .revalidate_disk = sd_revalidate_disk,
1105 .unlock_native_capacity = sd_unlock_native_capacity,
1104}; 1106};
1105 1107
1106static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) 1108static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
@@ -2121,6 +2123,26 @@ static int sd_revalidate_disk(struct gendisk *disk)
2121} 2123}
2122 2124
2123/** 2125/**
2126 * sd_unlock_native_capacity - unlock native capacity
2127 * @disk: struct gendisk to set capacity for
2128 *
2129 * Block layer calls this function if it detects that partitions
2130 * on @disk reach beyond the end of the device. If the SCSI host
2131 * implements ->unlock_native_capacity() method, it's invoked to
2132 * give it a chance to adjust the device capacity.
2133 *
2134 * CONTEXT:
2135 * Defined by block layer. Might sleep.
2136 */
2137static void sd_unlock_native_capacity(struct gendisk *disk)
2138{
2139 struct scsi_device *sdev = scsi_disk(disk)->device;
2140
2141 if (sdev->host->hostt->unlock_native_capacity)
2142 sdev->host->hostt->unlock_native_capacity(sdev);
2143}
2144
2145/**
2124 * sd_format_disk_name - format disk name 2146 * sd_format_disk_name - format disk name
2125 * @prefix: name prefix - ie. "sd" for SCSI disks 2147 * @prefix: name prefix - ie. "sd" for SCSI disks
2126 * @index: index of the disk to format name for 2148 * @index: index of the disk to format name for
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 01c012da4e26..746a44621d91 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -982,6 +982,18 @@ static int skip_tx_en_setup(struct serial_private *priv,
982#define PCI_SUBDEVICE_ID_POCTAL422 0x0408 982#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
983#define PCI_VENDOR_ID_ADVANTECH 0x13fe 983#define PCI_VENDOR_ID_ADVANTECH 0x13fe
984#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 984#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620
985#define PCI_DEVICE_ID_TITAN_200I 0x8028
986#define PCI_DEVICE_ID_TITAN_400I 0x8048
987#define PCI_DEVICE_ID_TITAN_800I 0x8088
988#define PCI_DEVICE_ID_TITAN_800EH 0xA007
989#define PCI_DEVICE_ID_TITAN_800EHB 0xA008
990#define PCI_DEVICE_ID_TITAN_400EH 0xA009
991#define PCI_DEVICE_ID_TITAN_100E 0xA010
992#define PCI_DEVICE_ID_TITAN_200E 0xA012
993#define PCI_DEVICE_ID_TITAN_400E 0xA013
994#define PCI_DEVICE_ID_TITAN_800E 0xA014
995#define PCI_DEVICE_ID_TITAN_200EI 0xA016
996#define PCI_DEVICE_ID_TITAN_200EISI 0xA017
985 997
986/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ 998/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
987#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 999#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@@ -1541,6 +1553,10 @@ enum pci_board_num_t {
1541 pbn_b3_4_115200, 1553 pbn_b3_4_115200,
1542 pbn_b3_8_115200, 1554 pbn_b3_8_115200,
1543 1555
1556 pbn_b4_bt_2_921600,
1557 pbn_b4_bt_4_921600,
1558 pbn_b4_bt_8_921600,
1559
1544 /* 1560 /*
1545 * Board-specific versions. 1561 * Board-specific versions.
1546 */ 1562 */
@@ -1995,6 +2011,25 @@ static struct pciserial_board pci_boards[] __devinitdata = {
1995 .uart_offset = 8, 2011 .uart_offset = 8,
1996 }, 2012 },
1997 2013
2014 [pbn_b4_bt_2_921600] = {
2015 .flags = FL_BASE4,
2016 .num_ports = 2,
2017 .base_baud = 921600,
2018 .uart_offset = 8,
2019 },
2020 [pbn_b4_bt_4_921600] = {
2021 .flags = FL_BASE4,
2022 .num_ports = 4,
2023 .base_baud = 921600,
2024 .uart_offset = 8,
2025 },
2026 [pbn_b4_bt_8_921600] = {
2027 .flags = FL_BASE4,
2028 .num_ports = 8,
2029 .base_baud = 921600,
2030 .uart_offset = 8,
2031 },
2032
1998 /* 2033 /*
1999 * Entries following this are board-specific. 2034 * Entries following this are board-specific.
2000 */ 2035 */
@@ -3043,6 +3078,42 @@ static struct pci_device_id serial_pci_tbl[] = {
3043 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L, 3078 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
3044 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3079 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3045 pbn_b0_bt_8_921600 }, 3080 pbn_b0_bt_8_921600 },
3081 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I,
3082 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3083 pbn_b4_bt_2_921600 },
3084 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400I,
3085 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3086 pbn_b4_bt_4_921600 },
3087 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800I,
3088 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3089 pbn_b4_bt_8_921600 },
3090 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400EH,
3091 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3092 pbn_b0_4_921600 },
3093 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EH,
3094 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3095 pbn_b0_4_921600 },
3096 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EHB,
3097 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3098 pbn_b0_4_921600 },
3099 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E,
3100 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3101 pbn_oxsemi_1_4000000 },
3102 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E,
3103 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3104 pbn_oxsemi_2_4000000 },
3105 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E,
3106 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3107 pbn_oxsemi_4_4000000 },
3108 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E,
3109 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3110 pbn_oxsemi_8_4000000 },
3111 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI,
3112 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3113 pbn_oxsemi_2_4000000 },
3114 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI,
3115 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
3116 pbn_oxsemi_2_4000000 },
3046 3117
3047 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, 3118 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
3048 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3119 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c
index bcee156d2f2e..0f1189605d21 100644
--- a/drivers/serial/altera_uart.c
+++ b/drivers/serial/altera_uart.c
@@ -89,15 +89,12 @@ static unsigned int altera_uart_tx_empty(struct uart_port *port)
89static unsigned int altera_uart_get_mctrl(struct uart_port *port) 89static unsigned int altera_uart_get_mctrl(struct uart_port *port)
90{ 90{
91 struct altera_uart *pp = container_of(port, struct altera_uart, port); 91 struct altera_uart *pp = container_of(port, struct altera_uart, port);
92 unsigned long flags;
93 unsigned int sigs; 92 unsigned int sigs;
94 93
95 spin_lock_irqsave(&port->lock, flags);
96 sigs = 94 sigs =
97 (readl(port->membase + ALTERA_UART_STATUS_REG) & 95 (readl(port->membase + ALTERA_UART_STATUS_REG) &
98 ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; 96 ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0;
99 sigs |= (pp->sigs & TIOCM_RTS); 97 sigs |= (pp->sigs & TIOCM_RTS);
100 spin_unlock_irqrestore(&port->lock, flags);
101 98
102 return sigs; 99 return sigs;
103} 100}
@@ -105,49 +102,37 @@ static unsigned int altera_uart_get_mctrl(struct uart_port *port)
105static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs) 102static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs)
106{ 103{
107 struct altera_uart *pp = container_of(port, struct altera_uart, port); 104 struct altera_uart *pp = container_of(port, struct altera_uart, port);
108 unsigned long flags;
109 105
110 spin_lock_irqsave(&port->lock, flags);
111 pp->sigs = sigs; 106 pp->sigs = sigs;
112 if (sigs & TIOCM_RTS) 107 if (sigs & TIOCM_RTS)
113 pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; 108 pp->imr |= ALTERA_UART_CONTROL_RTS_MSK;
114 else 109 else
115 pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; 110 pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK;
116 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 111 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
117 spin_unlock_irqrestore(&port->lock, flags);
118} 112}
119 113
120static void altera_uart_start_tx(struct uart_port *port) 114static void altera_uart_start_tx(struct uart_port *port)
121{ 115{
122 struct altera_uart *pp = container_of(port, struct altera_uart, port); 116 struct altera_uart *pp = container_of(port, struct altera_uart, port);
123 unsigned long flags;
124 117
125 spin_lock_irqsave(&port->lock, flags);
126 pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; 118 pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK;
127 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 119 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
128 spin_unlock_irqrestore(&port->lock, flags);
129} 120}
130 121
131static void altera_uart_stop_tx(struct uart_port *port) 122static void altera_uart_stop_tx(struct uart_port *port)
132{ 123{
133 struct altera_uart *pp = container_of(port, struct altera_uart, port); 124 struct altera_uart *pp = container_of(port, struct altera_uart, port);
134 unsigned long flags;
135 125
136 spin_lock_irqsave(&port->lock, flags);
137 pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; 126 pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
138 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 127 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
139 spin_unlock_irqrestore(&port->lock, flags);
140} 128}
141 129
142static void altera_uart_stop_rx(struct uart_port *port) 130static void altera_uart_stop_rx(struct uart_port *port)
143{ 131{
144 struct altera_uart *pp = container_of(port, struct altera_uart, port); 132 struct altera_uart *pp = container_of(port, struct altera_uart, port);
145 unsigned long flags;
146 133
147 spin_lock_irqsave(&port->lock, flags);
148 pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; 134 pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK;
149 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 135 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
150 spin_unlock_irqrestore(&port->lock, flags);
151} 136}
152 137
153static void altera_uart_break_ctl(struct uart_port *port, int break_state) 138static void altera_uart_break_ctl(struct uart_port *port, int break_state)
@@ -272,10 +257,14 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data)
272 unsigned int isr; 257 unsigned int isr;
273 258
274 isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr; 259 isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr;
260
261 spin_lock(&port->lock);
275 if (isr & ALTERA_UART_STATUS_RRDY_MSK) 262 if (isr & ALTERA_UART_STATUS_RRDY_MSK)
276 altera_uart_rx_chars(pp); 263 altera_uart_rx_chars(pp);
277 if (isr & ALTERA_UART_STATUS_TRDY_MSK) 264 if (isr & ALTERA_UART_STATUS_TRDY_MSK)
278 altera_uart_tx_chars(pp); 265 altera_uart_tx_chars(pp);
266 spin_unlock(&port->lock);
267
279 return IRQ_RETVAL(isr); 268 return IRQ_RETVAL(isr);
280} 269}
281 270
@@ -402,31 +391,24 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
402 return 0; 391 return 0;
403} 392}
404 393
405static void altera_uart_console_putc(struct console *co, const char c) 394static void altera_uart_console_putc(struct uart_port *port, const char c)
406{ 395{
407 struct uart_port *port = &(altera_uart_ports + co->index)->port; 396 while (!(readl(port->membase + ALTERA_UART_STATUS_REG) &
408 int i; 397 ALTERA_UART_STATUS_TRDY_MSK))
398 cpu_relax();
409 399
410 for (i = 0; i < 0x10000; i++) {
411 if (readl(port->membase + ALTERA_UART_STATUS_REG) &
412 ALTERA_UART_STATUS_TRDY_MSK)
413 break;
414 }
415 writel(c, port->membase + ALTERA_UART_TXDATA_REG); 400 writel(c, port->membase + ALTERA_UART_TXDATA_REG);
416 for (i = 0; i < 0x10000; i++) {
417 if (readl(port->membase + ALTERA_UART_STATUS_REG) &
418 ALTERA_UART_STATUS_TRDY_MSK)
419 break;
420 }
421} 401}
422 402
423static void altera_uart_console_write(struct console *co, const char *s, 403static void altera_uart_console_write(struct console *co, const char *s,
424 unsigned int count) 404 unsigned int count)
425{ 405{
406 struct uart_port *port = &(altera_uart_ports + co->index)->port;
407
426 for (; count; count--, s++) { 408 for (; count; count--, s++) {
427 altera_uart_console_putc(co, *s); 409 altera_uart_console_putc(port, *s);
428 if (*s == '\n') 410 if (*s == '\n')
429 altera_uart_console_putc(co, '\r'); 411 altera_uart_console_putc(port, '\r');
430 } 412 }
431} 413}
432 414
@@ -516,7 +498,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
516 return 0; 498 return 0;
517} 499}
518 500
519static int altera_uart_remove(struct platform_device *pdev) 501static int __devexit altera_uart_remove(struct platform_device *pdev)
520{ 502{
521 struct uart_port *port; 503 struct uart_port *port;
522 int i; 504 int i;
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 96f7e7484fee..511cbf687877 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -797,7 +797,7 @@ static void bfin_serial_shutdown(struct uart_port *port)
797 gpio_free(uart->rts_pin); 797 gpio_free(uart->rts_pin);
798#endif 798#endif
799#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS 799#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
800 if (UART_GET_IER(uart) && EDSSI) 800 if (UART_GET_IER(uart) & EDSSI)
801 free_irq(uart->status_irq, uart); 801 free_irq(uart->status_irq, uart);
802#endif 802#endif
803} 803}
@@ -869,7 +869,12 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
869 } 869 }
870 870
871 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 871 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
872 quot = uart_get_divisor(port, baud) - ANOMALY_05000230; 872 quot = uart_get_divisor(port, baud);
873
874 /* If discipline is not IRDA, apply ANOMALY_05000230 */
875 if (termios->c_line != N_IRDA)
876 quot -= ANOMALY_05000230;
877
873 spin_lock_irqsave(&uart->port.lock, flags); 878 spin_lock_irqsave(&uart->port.lock, flags);
874 879
875 UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); 880 UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c
index ecdc0facf7ee..f8c816e7725d 100644
--- a/drivers/serial/msm_serial.c
+++ b/drivers/serial/msm_serial.c
@@ -41,19 +41,6 @@ struct msm_port {
41 unsigned int imr; 41 unsigned int imr;
42}; 42};
43 43
44#define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port)
45
46static inline void msm_write(struct uart_port *port, unsigned int val,
47 unsigned int off)
48{
49 __raw_writel(val, port->membase + off);
50}
51
52static inline unsigned int msm_read(struct uart_port *port, unsigned int off)
53{
54 return __raw_readl(port->membase + off);
55}
56
57static void msm_stop_tx(struct uart_port *port) 44static void msm_stop_tx(struct uart_port *port)
58{ 45{
59 struct msm_port *msm_port = UART_TO_MSM(port); 46 struct msm_port *msm_port = UART_TO_MSM(port);
@@ -320,11 +307,7 @@ static void msm_init_clock(struct uart_port *port)
320 struct msm_port *msm_port = UART_TO_MSM(port); 307 struct msm_port *msm_port = UART_TO_MSM(port);
321 308
322 clk_enable(msm_port->clk); 309 clk_enable(msm_port->clk);
323 310 msm_serial_set_mnd_regs(port);
324 msm_write(port, 0xC0, UART_MREG);
325 msm_write(port, 0xB2, UART_NREG);
326 msm_write(port, 0x7D, UART_DREG);
327 msm_write(port, 0x1C, UART_MNDREG);
328} 311}
329 312
330static int msm_startup(struct uart_port *port) 313static int msm_startup(struct uart_port *port)
@@ -706,6 +689,8 @@ static int __init msm_serial_probe(struct platform_device *pdev)
706 if (unlikely(IS_ERR(msm_port->clk))) 689 if (unlikely(IS_ERR(msm_port->clk)))
707 return PTR_ERR(msm_port->clk); 690 return PTR_ERR(msm_port->clk);
708 port->uartclk = clk_get_rate(msm_port->clk); 691 port->uartclk = clk_get_rate(msm_port->clk);
692 printk(KERN_INFO "uartclk = %d\n", port->uartclk);
693
709 694
710 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); 695 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
711 if (unlikely(!resource)) 696 if (unlikely(!resource))
diff --git a/drivers/serial/msm_serial.h b/drivers/serial/msm_serial.h
index 689f1fa0e84e..f6ca9ca79e98 100644
--- a/drivers/serial/msm_serial.h
+++ b/drivers/serial/msm_serial.h
@@ -114,4 +114,60 @@
114#define UART_MISR 0x0010 114#define UART_MISR 0x0010
115#define UART_ISR 0x0014 115#define UART_ISR 0x0014
116 116
117#define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port)
118
119static inline
120void msm_write(struct uart_port *port, unsigned int val, unsigned int off)
121{
122 __raw_writel(val, port->membase + off);
123}
124
125static inline
126unsigned int msm_read(struct uart_port *port, unsigned int off)
127{
128 return __raw_readl(port->membase + off);
129}
130
131/*
132 * Setup the MND registers to use the TCXO clock.
133 */
134static inline void msm_serial_set_mnd_regs_tcxo(struct uart_port *port)
135{
136 msm_write(port, 0x06, UART_MREG);
137 msm_write(port, 0xF1, UART_NREG);
138 msm_write(port, 0x0F, UART_DREG);
139 msm_write(port, 0x1A, UART_MNDREG);
140}
141
142/*
143 * Setup the MND registers to use the TCXO clock divided by 4.
144 */
145static inline void msm_serial_set_mnd_regs_tcxoby4(struct uart_port *port)
146{
147 msm_write(port, 0x18, UART_MREG);
148 msm_write(port, 0xF6, UART_NREG);
149 msm_write(port, 0x0F, UART_DREG);
150 msm_write(port, 0x0A, UART_MNDREG);
151}
152
153static inline
154void msm_serial_set_mnd_regs_from_uartclk(struct uart_port *port)
155{
156 if (port->uartclk == 19200000)
157 msm_serial_set_mnd_regs_tcxo(port);
158 else
159 msm_serial_set_mnd_regs_tcxoby4(port);
160}
161
162/*
163 * TROUT has a specific defect that makes it report it's uartclk
164 * as 19.2Mhz (TCXO) when it's actually 4.8Mhz (TCXO/4). This special
165 * cases TROUT to use the right clock.
166 */
167#ifdef CONFIG_MACH_TROUT
168#define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_tcxoby4
169#else
170#define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_from_uartclk
171#endif
172
117#endif /* __DRIVERS_SERIAL_MSM_SERIAL_H */ 173#endif /* __DRIVERS_SERIAL_MSM_SERIAL_H */
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index cabbdc7ba583..5b9cde79e4ea 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -2005,8 +2005,11 @@ static struct of_device_id pmz_match[] =
2005MODULE_DEVICE_TABLE (of, pmz_match); 2005MODULE_DEVICE_TABLE (of, pmz_match);
2006 2006
2007static struct macio_driver pmz_driver = { 2007static struct macio_driver pmz_driver = {
2008 .name = "pmac_zilog", 2008 .driver = {
2009 .match_table = pmz_match, 2009 .name = "pmac_zilog",
2010 .owner = THIS_MODULE,
2011 .of_match_table = pmz_match,
2012 },
2010 .probe = pmz_attach, 2013 .probe = pmz_attach,
2011 .remove = pmz_detach, 2014 .remove = pmz_detach,
2012 .suspend = pmz_suspend, 2015 .suspend = pmz_suspend,
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index dadd686c9801..526307368f8b 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -715,6 +715,8 @@ static struct pcmcia_device_id serial_ids[] = {
715 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), 715 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
716 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), 716 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
717 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a), 717 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
718 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
719 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
718 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15), 720 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
719 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501), 721 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
720 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a), 722 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
@@ -724,8 +726,6 @@ static struct pcmcia_device_id serial_ids[] = {
724 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081), 726 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
725 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101), 727 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
726 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab), 728 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
727 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
728 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
729 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63), 729 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
730 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63), 730 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
731 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef), 731 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
@@ -768,17 +768,26 @@ static struct pcmcia_device_id serial_ids[] = {
768 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276), 768 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276),
769 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), 769 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
770 PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), 770 PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
771 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0101), /* TDK DF2814 */
772 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x100a), /* Xircom CM-56G */
773 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x3e0a), /* TDK DF5660 */
771 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), 774 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
775 PCMCIA_DEVICE_MANF_CARD(0x0107, 0x0002), /* USRobotics 14,400 */
772 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50), 776 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
773 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51), 777 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
774 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52), 778 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
775 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53), 779 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
776 PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180), 780 PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
781 PCMCIA_DEVICE_MANF_CARD(0x0115, 0x3330), /* USRobotics/SUN 14,400 */
782 PCMCIA_DEVICE_MANF_CARD(0x0124, 0x0100), /* Nokia DTP-2 ver II */
783 PCMCIA_DEVICE_MANF_CARD(0x0134, 0x5600), /* LASAT COMMUNICATIONS A/S */
777 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e), 784 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
778 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b), 785 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
779 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025), 786 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
780 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045), 787 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
781 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052), 788 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
789 PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0006), /* Psion 56K+Fax */
790 PCMCIA_DEVICE_MANF_CARD(0x0200, 0x0001), /* MultiMobile */
782 PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae), 791 PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
783 PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef), 792 PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
784 PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), 793 PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
@@ -792,16 +801,21 @@ static struct pcmcia_device_id serial_ids[] = {
792 PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95), 801 PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
793 PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), 802 PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
794 PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), 803 PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
804 PCMCIA_DEVICE_PROD_ID12("IBM", "ISDN/56K/GSM", 0xb569a6e5, 0xfee5297b),
795 PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), 805 PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
796 PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb), 806 PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb),
807 PCMCIA_DEVICE_PROD_ID12("Intertex", "IX34-PCMCIA", 0xf8a097e3, 0x97880447),
797 PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), 808 PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
798 PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), 809 PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
799 PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), 810 PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
800 PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), 811 PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
801 PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), 812 PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a),
813 PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41),
802 PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), 814 PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab),
803 PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), 815 PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
804 PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d), 816 PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
817 PCMCIA_DEVICE_PROD_ID12("Telia", "SurfinBird 560P/A+", 0xe2cdd5e, 0xc9314b38),
818 PCMCIA_DEVICE_PROD_ID1("Smart Serial Port", 0x2d8ce292),
805 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"), 819 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
806 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"), 820 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
807 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), 821 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c
index 005195958647..ceba593dc84f 100644
--- a/drivers/sfi/sfi_core.c
+++ b/drivers/sfi/sfi_core.c
@@ -441,8 +441,10 @@ struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa)
441 441
442 ret = sysfs_create_bin_file(tables_kobj, 442 ret = sysfs_create_bin_file(tables_kobj,
443 &tbl_attr->attr); 443 &tbl_attr->attr);
444 if (ret) 444 if (ret) {
445 kfree(tbl_attr); 445 kfree(tbl_attr);
446 tbl_attr = NULL;
447 }
446 448
447 sfi_unmap_table(th); 449 sfi_unmap_table(th);
448 return tbl_attr; 450 return tbl_attr;
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index c585574b9aed..e91a23e5ffd8 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -16,6 +16,8 @@
16 * License. See the file "COPYING" in the main directory of this archive 16 * License. See the file "COPYING" in the main directory of this archive
17 * for more details. 17 * for more details.
18 */ 18 */
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
19#include <linux/init.h> 21#include <linux/init.h>
20#include <linux/irq.h> 22#include <linux/irq.h>
21#include <linux/module.h> 23#include <linux/module.h>
@@ -855,8 +857,8 @@ static void __init intc_register_irq(struct intc_desc *desc,
855 primary = 1; 857 primary = 1;
856 858
857 if (!data[0] && !data[1]) 859 if (!data[0] && !data[1])
858 pr_warning("intc: missing unique irq mask for " 860 pr_warning("missing unique irq mask for irq %d (vect 0x%04x)\n",
859 "irq %d (vect 0x%04x)\n", irq, irq2evt(irq)); 861 irq, irq2evt(irq));
860 862
861 data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); 863 data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1);
862 data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); 864 data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1);
@@ -952,7 +954,7 @@ int __init register_intc_controller(struct intc_desc *desc)
952 struct intc_desc_int *d; 954 struct intc_desc_int *d;
953 struct resource *res; 955 struct resource *res;
954 956
955 pr_info("intc: Registered controller '%s' with %u IRQs\n", 957 pr_info("Registered controller '%s' with %u IRQs\n",
956 desc->name, hw->nr_vectors); 958 desc->name, hw->nr_vectors);
957 959
958 d = kzalloc(sizeof(*d), GFP_NOWAIT); 960 d = kzalloc(sizeof(*d), GFP_NOWAIT);
@@ -1148,7 +1150,7 @@ int register_intc_userimask(unsigned long addr)
1148 if (unlikely(!uimask)) 1150 if (unlikely(!uimask))
1149 return -ENOMEM; 1151 return -ENOMEM;
1150 1152
1151 pr_info("intc: userimask support registered for levels 0 -> %d\n", 1153 pr_info("userimask support registered for levels 0 -> %d\n",
1152 default_prio_level - 1); 1154 default_prio_level - 1);
1153 1155
1154 return 0; 1156 return 0;
@@ -1286,7 +1288,7 @@ static int __init register_intc_sysdevs(void)
1286 } 1288 }
1287 1289
1288 if (error) 1290 if (error)
1289 pr_err("intc: sysdev registration error\n"); 1291 pr_err("sysdev registration error\n");
1290 1292
1291 return error; 1293 return error;
1292} 1294}
diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c
index 28a126d2742b..2534b1ec3edd 100644
--- a/drivers/spi/mpc512x_psc_spi.c
+++ b/drivers/spi/mpc512x_psc_spi.c
@@ -512,29 +512,29 @@ static int __init mpc512x_psc_spi_of_probe(struct of_device *op,
512 u64 regaddr64, size64; 512 u64 regaddr64, size64;
513 s16 id = -1; 513 s16 id = -1;
514 514
515 regaddr_p = of_get_address(op->node, 0, &size64, NULL); 515 regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);
516 if (!regaddr_p) { 516 if (!regaddr_p) {
517 dev_err(&op->dev, "Invalid PSC address\n"); 517 dev_err(&op->dev, "Invalid PSC address\n");
518 return -EINVAL; 518 return -EINVAL;
519 } 519 }
520 regaddr64 = of_translate_address(op->node, regaddr_p); 520 regaddr64 = of_translate_address(op->dev.of_node, regaddr_p);
521 521
522 /* get PSC id (0..11, used by port_config) */ 522 /* get PSC id (0..11, used by port_config) */
523 if (op->dev.platform_data == NULL) { 523 if (op->dev.platform_data == NULL) {
524 const u32 *psc_nump; 524 const u32 *psc_nump;
525 525
526 psc_nump = of_get_property(op->node, "cell-index", NULL); 526 psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL);
527 if (!psc_nump || *psc_nump > 11) { 527 if (!psc_nump || *psc_nump > 11) {
528 dev_err(&op->dev, "mpc512x_psc_spi: Device node %s " 528 dev_err(&op->dev, "mpc512x_psc_spi: Device node %s "
529 "has invalid cell-index property\n", 529 "has invalid cell-index property\n",
530 op->node->full_name); 530 op->dev.of_node->full_name);
531 return -EINVAL; 531 return -EINVAL;
532 } 532 }
533 id = *psc_nump; 533 id = *psc_nump;
534 } 534 }
535 535
536 return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, 536 return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64,
537 irq_of_parse_and_map(op->node, 0), id); 537 irq_of_parse_and_map(op->dev.of_node, 0), id);
538} 538}
539 539
540static int __exit mpc512x_psc_spi_of_remove(struct of_device *op) 540static int __exit mpc512x_psc_spi_of_remove(struct of_device *op)
@@ -550,12 +550,12 @@ static struct of_device_id mpc512x_psc_spi_of_match[] = {
550MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match); 550MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match);
551 551
552static struct of_platform_driver mpc512x_psc_spi_of_driver = { 552static struct of_platform_driver mpc512x_psc_spi_of_driver = {
553 .match_table = mpc512x_psc_spi_of_match,
554 .probe = mpc512x_psc_spi_of_probe, 553 .probe = mpc512x_psc_spi_of_probe,
555 .remove = __exit_p(mpc512x_psc_spi_of_remove), 554 .remove = __exit_p(mpc512x_psc_spi_of_remove),
556 .driver = { 555 .driver = {
557 .name = "mpc512x-psc-spi", 556 .name = "mpc512x-psc-spi",
558 .owner = THIS_MODULE, 557 .owner = THIS_MODULE,
558 .of_match_table = mpc512x_psc_spi_of_match,
559 }, 559 },
560}; 560};
561 561
diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c
index 19c0b3b34fce..d53466a249d9 100644
--- a/drivers/spi/spi_ppc4xx.c
+++ b/drivers/spi/spi_ppc4xx.c
@@ -397,7 +397,7 @@ static int __init spi_ppc4xx_of_probe(struct of_device *op,
397 struct spi_master *master; 397 struct spi_master *master;
398 struct spi_bitbang *bbp; 398 struct spi_bitbang *bbp;
399 struct resource resource; 399 struct resource resource;
400 struct device_node *np = op->node; 400 struct device_node *np = op->dev.of_node;
401 struct device *dev = &op->dev; 401 struct device *dev = &op->dev;
402 struct device_node *opbnp; 402 struct device_node *opbnp;
403 int ret; 403 int ret;
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 989e2752cc36..6dcda86be6eb 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -625,9 +625,12 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
625 ssb_printk(KERN_ERR PFX "No SPROM available!\n"); 625 ssb_printk(KERN_ERR PFX "No SPROM available!\n");
626 return -ENODEV; 626 return -ENODEV;
627 } 627 }
628 628 if (bus->chipco.dev) { /* can be unavailible! */
629 bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? 629 bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ?
630 SSB_SPROM_BASE1 : SSB_SPROM_BASE31; 630 SSB_SPROM_BASE1 : SSB_SPROM_BASE31;
631 } else {
632 bus->sprom_offset = SSB_SPROM_BASE1;
633 }
631 634
632 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); 635 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
633 if (!buf) 636 if (!buf)
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
index 007bc3a03486..4f7cc8d13277 100644
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -185,6 +185,7 @@ bool ssb_is_sprom_available(struct ssb_bus *bus)
185 /* this routine differs from specs as we do not access SPROM directly 185 /* this routine differs from specs as we do not access SPROM directly
186 on PCMCIA */ 186 on PCMCIA */
187 if (bus->bustype == SSB_BUSTYPE_PCI && 187 if (bus->bustype == SSB_BUSTYPE_PCI &&
188 bus->chipco.dev && /* can be unavailible! */
188 bus->chipco.dev->id.revision >= 31) 189 bus->chipco.dev->id.revision >= 31)
189 return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; 190 return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
190 191
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index b5c3b3013037..984a75440710 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -141,5 +141,11 @@ source "drivers/staging/ti-st/Kconfig"
141 141
142source "drivers/staging/adis16255/Kconfig" 142source "drivers/staging/adis16255/Kconfig"
143 143
144source "drivers/staging/xgifb/Kconfig"
145
146source "drivers/staging/mrst-touchscreen/Kconfig"
147
148source "drivers/staging/msm/Kconfig"
149
144endif # !STAGING_EXCLUDE_BUILD 150endif # !STAGING_EXCLUDE_BUILD
145endif # STAGING 151endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index e330dd5e843d..9fa25133874a 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -51,3 +51,6 @@ obj-$(CONFIG_CRYSTALHD) += crystalhd/
51obj-$(CONFIG_CXT1E1) += cxt1e1/ 51obj-$(CONFIG_CXT1E1) += cxt1e1/
52obj-$(CONFIG_TI_ST) += ti-st/ 52obj-$(CONFIG_TI_ST) += ti-st/
53obj-$(CONFIG_ADIS16255) += adis16255/ 53obj-$(CONFIG_ADIS16255) += adis16255/
54obj-$(CONFIG_FB_XGI) += xgifb/
55obj-$(CONFIG_TOUCHSCREEN_MRSTOUCH) += mrst-touchscreen/
56obj-$(CONFIG_MSM_STAGING) += msm/
diff --git a/drivers/staging/adis16255/Kconfig b/drivers/staging/adis16255/Kconfig
index a642be66adea..a883c1f4478b 100644
--- a/drivers/staging/adis16255/Kconfig
+++ b/drivers/staging/adis16255/Kconfig
@@ -1,5 +1,5 @@
1config ADIS16255 1config ADIS16255
2 tristate "Ananlog Devices ADIS16250/16255" 2 tristate "Analog Devices ADIS16250/16255"
3 depends on SPI && SYSFS 3 depends on SPI && SYSFS
4 ---help--- 4 ---help---
5 If you say yes here you get support for the Analog Devices 5 If you say yes here you get support for the Analog Devices
diff --git a/drivers/staging/adis16255/adis16255.c b/drivers/staging/adis16255/adis16255.c
index 1ba11f00b2e7..55d66e290f7d 100644
--- a/drivers/staging/adis16255/adis16255.c
+++ b/drivers/staging/adis16255/adis16255.c
@@ -361,7 +361,7 @@ err:
361 361
362/*-------------------------------------------------------------------------*/ 362/*-------------------------------------------------------------------------*/
363 363
364static int spi_adis16255_probe(struct spi_device *spi) 364static int __devinit spi_adis16255_probe(struct spi_device *spi)
365{ 365{
366 366
367 struct adis16255_init_data *init_data = spi->dev.platform_data; 367 struct adis16255_init_data *init_data = spi->dev.platform_data;
@@ -421,7 +421,7 @@ err:
421 return status; 421 return status;
422} 422}
423 423
424static int spi_adis16255_remove(struct spi_device *spi) 424static int __devexit spi_adis16255_remove(struct spi_device *spi)
425{ 425{
426 struct spi_adis16255_data *spiadis = dev_get_drvdata(&spi->dev); 426 struct spi_adis16255_data *spiadis = dev_get_drvdata(&spi->dev);
427 427
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c
index ad82ec4a4856..7eb6559e0315 100644
--- a/drivers/staging/batman-adv/device.c
+++ b/drivers/staging/batman-adv/device.c
@@ -309,7 +309,7 @@ void bat_device_add_packet(struct device_client *device_client,
309 struct device_packet *device_packet; 309 struct device_packet *device_packet;
310 unsigned long flags; 310 unsigned long flags;
311 311
312 device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL); 312 device_packet = kmalloc(sizeof(struct device_packet), GFP_ATOMIC);
313 313
314 if (!device_packet) 314 if (!device_packet)
315 return; 315 return;
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c
index 9d13979c2d8e..74c70d589a93 100644
--- a/drivers/staging/batman-adv/main.c
+++ b/drivers/staging/batman-adv/main.c
@@ -127,7 +127,10 @@ int init_module(void)
127 return 0; 127 return 0;
128 128
129unreg_soft_device: 129unreg_soft_device:
130 unregister_netdevice(soft_device); 130 unregister_netdev(soft_device);
131 soft_device = NULL;
132 return -ENOMEM;
133
131free_soft_device: 134free_soft_device:
132 free_netdev(soft_device); 135 free_netdev(soft_device);
133 soft_device = NULL; 136 soft_device = NULL;
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c
index d8536e277a26..ac69ed871a76 100644
--- a/drivers/staging/batman-adv/send.c
+++ b/drivers/staging/batman-adv/send.c
@@ -440,6 +440,9 @@ void send_outstanding_bcast_packet(struct work_struct *work)
440 hlist_del(&forw_packet->list); 440 hlist_del(&forw_packet->list);
441 spin_unlock_irqrestore(&forw_bcast_list_lock, flags); 441 spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
442 442
443 if (atomic_read(&module_state) == MODULE_DEACTIVATING)
444 goto out;
445
443 /* rebroadcast packet */ 446 /* rebroadcast packet */
444 rcu_read_lock(); 447 rcu_read_lock();
445 list_for_each_entry_rcu(batman_if, &if_list, list) { 448 list_for_each_entry_rcu(batman_if, &if_list, list) {
@@ -453,15 +456,15 @@ void send_outstanding_bcast_packet(struct work_struct *work)
453 456
454 forw_packet->num_packets++; 457 forw_packet->num_packets++;
455 458
456 /* if we still have some more bcasts to send and we are not shutting 459 /* if we still have some more bcasts to send */
457 * down */ 460 if (forw_packet->num_packets < 3) {
458 if ((forw_packet->num_packets < 3) &&
459 (atomic_read(&module_state) != MODULE_DEACTIVATING))
460 _add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000)); 461 _add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000));
461 else { 462 return;
462 forw_packet_free(forw_packet);
463 atomic_inc(&bcast_queue_left);
464 } 463 }
464
465out:
466 forw_packet_free(forw_packet);
467 atomic_inc(&bcast_queue_left);
465} 468}
466 469
467void send_outstanding_bat_packet(struct work_struct *work) 470void send_outstanding_bat_packet(struct work_struct *work)
@@ -476,6 +479,9 @@ void send_outstanding_bat_packet(struct work_struct *work)
476 hlist_del(&forw_packet->list); 479 hlist_del(&forw_packet->list);
477 spin_unlock_irqrestore(&forw_bat_list_lock, flags); 480 spin_unlock_irqrestore(&forw_bat_list_lock, flags);
478 481
482 if (atomic_read(&module_state) == MODULE_DEACTIVATING)
483 goto out;
484
479 send_packet(forw_packet); 485 send_packet(forw_packet);
480 486
481 /** 487 /**
@@ -483,10 +489,10 @@ void send_outstanding_bat_packet(struct work_struct *work)
483 * to determine the queues wake up time unless we are 489 * to determine the queues wake up time unless we are
484 * shutting down 490 * shutting down
485 */ 491 */
486 if ((forw_packet->own) && 492 if (forw_packet->own)
487 (atomic_read(&module_state) != MODULE_DEACTIVATING))
488 schedule_own_packet(forw_packet->if_incoming); 493 schedule_own_packet(forw_packet->if_incoming);
489 494
495out:
490 /* don't count own packet */ 496 /* don't count own packet */
491 if (!forw_packet->own) 497 if (!forw_packet->own)
492 atomic_inc(&batman_queue_left); 498 atomic_inc(&batman_queue_left);
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 8ce307e64b58..aad47326d6dc 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -100,15 +100,6 @@ menuconfig COMEDI_ISA_DRIVERS
100 100
101if COMEDI_ISA_DRIVERS && ISA 101if COMEDI_ISA_DRIVERS && ISA
102 102
103config COMEDI_8255
104 tristate "Generic 8255 support"
105 default N
106 ---help---
107 Enable generic 8255 support.
108
109 To compile this driver as a module, choose M here: the module will be
110 called 8255.
111
112config COMEDI_ACL7225B 103config COMEDI_ACL7225B
113 tristate "ADlink NuDAQ ACL-7225b and compatibles support" 104 tristate "ADlink NuDAQ ACL-7225b and compatibles support"
114 default N 105 default N
@@ -130,6 +121,7 @@ config COMEDI_PCL711
130 121
131config COMEDI_PCL724 122config COMEDI_PCL724
132 tristate "Advantech PCL-722/724/731 and ADlink ACL-7122/7124/PET-48DIO" 123 tristate "Advantech PCL-722/724/731 and ADlink ACL-7122/7124/PET-48DIO"
124 select COMEDI_8255
133 default N 125 default N
134 ---help--- 126 ---help---
135 Enable support for Advantech PCL-724, PCL-722, PCL-731 and 127 Enable support for Advantech PCL-724, PCL-722, PCL-731 and
@@ -198,6 +190,7 @@ config COMEDI_PCL818
198 190
199config COMEDI_PCM3724 191config COMEDI_PCM3724
200 tristate "Advantech PCM-3724 PC/104 card support" 192 tristate "Advantech PCM-3724 PC/104 card support"
193 select COMEDI_8255
201 default N 194 default N
202 ---help--- 195 ---help---
203 Enable support for Advantech PCM-3724 PC/104 cards. 196 Enable support for Advantech PCM-3724 PC/104 cards.
@@ -232,18 +225,9 @@ config COMEDI_RTI802
232 To compile this driver as a module, choose M here: the module will be 225 To compile this driver as a module, choose M here: the module will be
233 called rti802. 226 called rti802.
234 227
235config COMEDI_DAS08
236 tristate "DAS-08 compatible ISA, PC/104 and PCMCIA card support"
237 default N
238 ---help---
239 Enable support for Keithley Metrabyte/ComputerBoards DAS08
240 and compatible ISA and PC/104 cards
241
242 To compile this driver as a module, choose M here: the module will be
243 called das08.
244
245config COMEDI_DAS16M1 228config COMEDI_DAS16M1
246 tristate "MeasurementComputing CIO-DAS16/M1DAS-16 ISA card support" 229 tristate "MeasurementComputing CIO-DAS16/M1DAS-16 ISA card support"
230 select COMEDI_8255
247 select COMEDI_FC 231 select COMEDI_FC
248 default N 232 default N
249 ---help--- 233 ---help---
@@ -254,6 +238,7 @@ config COMEDI_DAS16M1
254 238
255config COMEDI_DAS16 239config COMEDI_DAS16
256 tristate "DAS-16 compatible ISA and PC/104 card support" 240 tristate "DAS-16 compatible ISA and PC/104 card support"
241 select COMEDI_8255
257 select COMEDI_FC 242 select COMEDI_FC
258 default N 243 default N
259 ---help--- 244 ---help---
@@ -385,6 +370,7 @@ config COMEDI_FL512
385 370
386config COMEDI_AIO_AIO12_8 371config COMEDI_AIO_AIO12_8
387 tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support" 372 tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support"
373 select COMEDI_8255
388 default N 374 default N
389 ---help--- 375 ---help---
390 Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board 376 Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board
@@ -466,6 +452,7 @@ config COMEDI_NI_ATMIO
466config COMEDI_NI_ATMIO16D 452config COMEDI_NI_ATMIO16D
467 tristate "NI AT-MIO16/AT-MIO16D series ISA-PNP card support" 453 tristate "NI AT-MIO16/AT-MIO16D series ISA-PNP card support"
468 depends on ISAPNP && COMEDI_NI_COMMON 454 depends on ISAPNP && COMEDI_NI_COMMON
455 select COMEDI_8255
469 default N 456 default N
470 ---help--- 457 ---help---
471 Enable support for National Instruments AT-MIO16/AT-MIO16D cards. 458 Enable support for National Instruments AT-MIO16/AT-MIO16D cards.
@@ -667,6 +654,7 @@ config COMEDI_ADDI_APCI_3XXX
667 654
668config COMEDI_ADL_PCI6208 655config COMEDI_ADL_PCI6208
669 tristate "ADLink PCI-6208A support" 656 tristate "ADLink PCI-6208A support"
657 select COMEDI_8255
670 default N 658 default N
671 ---help--- 659 ---help---
672 Enable support for ADLink PCI-6208A cards 660 Enable support for ADLink PCI-6208A cards
@@ -751,6 +739,7 @@ config COMEDI_ADV_PCI1723
751 739
752config COMEDI_ADV_PCI_DIO 740config COMEDI_ADV_PCI_DIO
753 tristate "Advantech PCI DIO card support" 741 tristate "Advantech PCI DIO card support"
742 select COMEDI_8255
754 default N 743 default N
755 ---help--- 744 ---help---
756 Enable support for Advantech PCI DIO cards 745 Enable support for Advantech PCI DIO cards
@@ -762,6 +751,7 @@ config COMEDI_ADV_PCI_DIO
762 751
763config COMEDI_AMPLC_DIO200 752config COMEDI_AMPLC_DIO200
764 tristate "Amplicon PC272E and PCI272 DIO board support" 753 tristate "Amplicon PC272E and PCI272 DIO board support"
754 select COMEDI_8255
765 default N 755 default N
766 ---help--- 756 ---help---
767 Enable support for Amplicon PC272E and PCI272 DIO boards 757 Enable support for Amplicon PC272E and PCI272 DIO boards
@@ -771,6 +761,7 @@ config COMEDI_AMPLC_DIO200
771 761
772config COMEDI_AMPLC_PC236 762config COMEDI_AMPLC_PC236
773 tristate "Amplicon PC36AT and PCI236 DIO board support" 763 tristate "Amplicon PC36AT and PCI236 DIO board support"
764 select COMEDI_8255
774 default N 765 default N
775 ---help--- 766 ---help---
776 Enable support for Amplicon PC36AT and PCI236 DIO boards 767 Enable support for Amplicon PC36AT and PCI236 DIO boards
@@ -799,6 +790,7 @@ config COMEDI_AMPLC_PCI224
799 790
800config COMEDI_AMPLC_PCI230 791config COMEDI_AMPLC_PCI230
801 tristate "Amplicon PCI230 and PCI260 support" 792 tristate "Amplicon PCI230 and PCI260 support"
793 select COMEDI_8255
802 default N 794 default N
803 ---help--- 795 ---help---
804 Enable support for Amplicon PCI230 and PCI260 Multifunction I/O 796 Enable support for Amplicon PCI230 and PCI260 Multifunction I/O
@@ -869,6 +861,7 @@ config COMEDI_II_PCI20KC
869 861
870config COMEDI_DAQBOARD2000 862config COMEDI_DAQBOARD2000
871 tristate "IOtech DAQboard/2000 support" 863 tristate "IOtech DAQboard/2000 support"
864 select COMEDI_8255
872 default N 865 default N
873 ---help--- 866 ---help---
874 Enable support for the IOtech DAQboard/2000 867 Enable support for the IOtech DAQboard/2000
@@ -896,6 +889,7 @@ config COMEDI_KE_COUNTER
896 889
897config COMEDI_CB_PCIDAS64 890config COMEDI_CB_PCIDAS64
898 tristate "MeasurementComputing PCI-DAS 64xx, 60xx, and 4020 support" 891 tristate "MeasurementComputing PCI-DAS 64xx, 60xx, and 4020 support"
892 select COMEDI_8255
899 select COMEDI_FC 893 select COMEDI_FC
900 default N 894 default N
901 ---help--- 895 ---help---
@@ -907,6 +901,7 @@ config COMEDI_CB_PCIDAS64
907 901
908config COMEDI_CB_PCIDAS 902config COMEDI_CB_PCIDAS
909 tristate "MeasurementComputing PCI-DAS support" 903 tristate "MeasurementComputing PCI-DAS support"
904 select COMEDI_8255
910 select COMEDI_FC 905 select COMEDI_FC
911 default N 906 default N
912 ---help--- 907 ---help---
@@ -920,6 +915,7 @@ config COMEDI_CB_PCIDAS
920 915
921config COMEDI_CB_PCIDDA 916config COMEDI_CB_PCIDDA
922 tristate "MeasurementComputing PCI-DDA series support" 917 tristate "MeasurementComputing PCI-DDA series support"
918 select COMEDI_8255
923 default N 919 default N
924 ---help--- 920 ---help---
925 Enable support for ComputerBoards/MeasurementComputing PCI-DDA 921 Enable support for ComputerBoards/MeasurementComputing PCI-DDA
@@ -931,6 +927,7 @@ config COMEDI_CB_PCIDDA
931 927
932config COMEDI_CB_PCIDIO 928config COMEDI_CB_PCIDIO
933 tristate "MeasurementComputing PCI-DIO series support" 929 tristate "MeasurementComputing PCI-DIO series support"
930 select COMEDI_8255
934 default N 931 default N
935 ---help--- 932 ---help---
936 Enable support for ComputerBoards/MeasurementComputing PCI-DIO series 933 Enable support for ComputerBoards/MeasurementComputing PCI-DIO series
@@ -941,6 +938,7 @@ config COMEDI_CB_PCIDIO
941 938
942config COMEDI_CB_PCIMDAS 939config COMEDI_CB_PCIMDAS
943 tristate "MeasurementComputing PCIM-DAS1602/16 support" 940 tristate "MeasurementComputing PCIM-DAS1602/16 support"
941 select COMEDI_8255
944 default N 942 default N
945 ---help--- 943 ---help---
946 Enable support for ComputerBoards/MeasurementComputing PCI Migration 944 Enable support for ComputerBoards/MeasurementComputing PCI Migration
@@ -951,6 +949,7 @@ config COMEDI_CB_PCIMDAS
951 949
952config COMEDI_CB_PCIMDDA 950config COMEDI_CB_PCIMDDA
953 tristate "MeasurementComputing PCIM-DDA06-16 support" 951 tristate "MeasurementComputing PCIM-DDA06-16 support"
952 select COMEDI_8255
954 default N 953 default N
955 ---help--- 954 ---help---
956 Enable support for ComputerBoards/MeasurementComputing PCIM-DDA06-16 955 Enable support for ComputerBoards/MeasurementComputing PCIM-DDA06-16
@@ -1026,6 +1025,7 @@ config COMEDI_NI_670X
1026config COMEDI_NI_PCIDIO 1025config COMEDI_NI_PCIDIO
1027 tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support" 1026 tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support"
1028 depends on COMEDI_MITE 1027 depends on COMEDI_MITE
1028 select COMEDI_8255
1029 default N 1029 default N
1030 ---help--- 1030 ---help---
1031 Enable support for National Instruments PCI-DIO-32HS, PXI-6533, 1031 Enable support for National Instruments PCI-DIO-32HS, PXI-6533,
@@ -1058,6 +1058,7 @@ config COMEDI_NI_PCIMIO
1058 1058
1059config COMEDI_RTD520 1059config COMEDI_RTD520
1060 tristate "Real Time Devices PCI4520/DM7520 support" 1060 tristate "Real Time Devices PCI4520/DM7520 support"
1061 select COMEDI_8255
1061 default N 1062 default N
1062 ---help--- 1063 ---help---
1063 Enable support for Real Time Devices PCI4520/DM7520 1064 Enable support for Real Time Devices PCI4520/DM7520
@@ -1097,7 +1098,7 @@ endif # COMEDI_PCI_DRIVERS
1097 1098
1098menuconfig COMEDI_PCMCIA_DRIVERS 1099menuconfig COMEDI_PCMCIA_DRIVERS
1099 tristate "Comedi PCMCIA drivers" 1100 tristate "Comedi PCMCIA drivers"
1100 depends on COMEDI && PCMCIA && PCCARD 1101 depends on COMEDI && (PCMCIA || PCCARD)
1101 default N 1102 default N
1102 ---help--- 1103 ---help---
1103 Enable comedi PCMCIA and PCCARD drivers to be built 1104 Enable comedi PCMCIA and PCCARD drivers to be built
@@ -1142,6 +1143,7 @@ config COMEDI_NI_DAQ_700_CS
1142config COMEDI_NI_DAQ_DIO24_CS 1143config COMEDI_NI_DAQ_DIO24_CS
1143 tristate "NI DAQ-Card DIO-24 PCMCIA support" 1144 tristate "NI DAQ-Card DIO-24 PCMCIA support"
1144 depends on COMEDI_NI_COMMON 1145 depends on COMEDI_NI_COMMON
1146 select COMEDI_8255
1145 default N 1147 default N
1146 ---help--- 1148 ---help---
1147 Enable support for the National Instruments PCMCIA DAQ-Card DIO-24 1149 Enable support for the National Instruments PCMCIA DAQ-Card DIO-24
@@ -1162,8 +1164,8 @@ config COMEDI_NI_LABPC_CS
1162config COMEDI_NI_MIO_CS 1164config COMEDI_NI_MIO_CS
1163 tristate "NI DAQCard E series PCMCIA support" 1165 tristate "NI DAQCard E series PCMCIA support"
1164 depends on COMEDI_NI_TIO && COMEDI_NI_COMMON 1166 depends on COMEDI_NI_TIO && COMEDI_NI_COMMON
1165 default N
1166 select COMEDI_FC 1167 select COMEDI_FC
1168 default N
1167 ---help--- 1169 ---help---
1168 Enable support for the National Instruments PCMCIA DAQCard E series 1170 Enable support for the National Instruments PCMCIA DAQCard E series
1169 DAQCard-ai-16xe-50, DAQCard-ai-16e-4, DAQCard-6062E, DAQCard-6024E 1171 DAQCard-ai-16xe-50, DAQCard-ai-16e-4, DAQCard-6062E, DAQCard-6024E
@@ -1265,7 +1267,8 @@ config COMEDI_MITE
1265 1267
1266config COMEDI_NI_TIO 1268config COMEDI_NI_TIO
1267 tristate "NI general purpose counter support" 1269 tristate "NI general purpose counter support"
1268 select COMEDI_MITE 1270 depends on COMEDI_MITE
1271 select COMEDI_8255
1269 default N 1272 default N
1270 ---help--- 1273 ---help---
1271 Enable support for National Instruments general purpose counters. 1274 Enable support for National Instruments general purpose counters.
@@ -1278,6 +1281,8 @@ config COMEDI_NI_TIO
1278 1281
1279config COMEDI_NI_LABPC 1282config COMEDI_NI_LABPC
1280 tristate "NI Lab-PC and compatibles ISA and PCI support" 1283 tristate "NI Lab-PC and compatibles ISA and PCI support"
1284 depends on COMEDI_MITE
1285 select COMEDI_8255
1281 select COMEDI_FC 1286 select COMEDI_FC
1282 default N 1287 default N
1283 ---help--- 1288 ---help---
@@ -1291,8 +1296,40 @@ config COMEDI_NI_LABPC
1291 1296
1292endif # COMEDI_NI_COMMON 1297endif # COMEDI_NI_COMMON
1293 1298
1299config COMEDI_8255
1300 tristate "Generic 8255 support"
1301 depends on COMEDI
1302 default N
1303 ---help---
1304 Enable generic 8255 support.
1305
1306 You should enable compilation this driver if you plan to use a board
1307 that has an 8255 chip. For multifunction boards, the main driver will
1308 configure the 8255 subdevice automatically.
1309
1310 Note that most PCI 8255 boards do NOT work with this driver, and
1311 need a separate driver as a wrapper.
1312
1313 To compile this driver as a module, choose M here: the module will be
1314 called 8255.
1315
1316config COMEDI_DAS08
1317 tristate "DAS-08 compatible support"
1318 depends on COMEDI
1319 select COMEDI_8255
1320 default N
1321 ---help---
1322 Enable support for DAS08 and compatible ISA, PC/104 and PCI cards.
1323
1324 Note that PCMCIA DAS08 cards are not directly supported by this
1325 driver, and need a separate driver as a wrapper.
1326
1327 To compile this driver as a module, choose M here: the module will be
1328 called das08.
1329
1294config COMEDI_FC 1330config COMEDI_FC
1295 tristate "Comedi shared functions for low-level driver support" 1331 tristate "Comedi shared functions for low-level driver support"
1332 depends on COMEDI
1296 default N 1333 default N
1297 ---help--- 1334 ---help---
1298 Enable support for shared functions for low-level drivers. 1335 Enable support for shared functions for low-level drivers.
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index aced00e5cd10..aeb2c00875cd 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -83,7 +83,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
83static int do_chaninfo_ioctl(struct comedi_device *dev, 83static int do_chaninfo_ioctl(struct comedi_device *dev,
84 struct comedi_chaninfo __user *arg); 84 struct comedi_chaninfo __user *arg);
85static int do_bufinfo_ioctl(struct comedi_device *dev, 85static int do_bufinfo_ioctl(struct comedi_device *dev,
86 struct comedi_bufinfo __user *arg); 86 struct comedi_bufinfo __user *arg, void *file);
87static int do_cmd_ioctl(struct comedi_device *dev, 87static int do_cmd_ioctl(struct comedi_device *dev,
88 struct comedi_cmd __user *arg, void *file); 88 struct comedi_cmd __user *arg, void *file);
89static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, 89static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg,
@@ -169,7 +169,8 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
169 break; 169 break;
170 case COMEDI_BUFINFO: 170 case COMEDI_BUFINFO:
171 rc = do_bufinfo_ioctl(dev, 171 rc = do_bufinfo_ioctl(dev,
172 (struct comedi_bufinfo __user *)arg); 172 (struct comedi_bufinfo __user *)arg,
173 file);
173 break; 174 break;
174 case COMEDI_LOCK: 175 case COMEDI_LOCK:
175 rc = do_lock_ioctl(dev, arg, file); 176 rc = do_lock_ioctl(dev, arg, file);
@@ -563,7 +564,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
563 564
564 */ 565 */
565static int do_bufinfo_ioctl(struct comedi_device *dev, 566static int do_bufinfo_ioctl(struct comedi_device *dev,
566 struct comedi_bufinfo __user *arg) 567 struct comedi_bufinfo __user *arg, void *file)
567{ 568{
568 struct comedi_bufinfo bi; 569 struct comedi_bufinfo bi;
569 struct comedi_subdevice *s; 570 struct comedi_subdevice *s;
@@ -576,6 +577,10 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
576 return -EINVAL; 577 return -EINVAL;
577 578
578 s = dev->subdevices + bi.subdevice; 579 s = dev->subdevices + bi.subdevice;
580
581 if (s->lock && s->lock != file)
582 return -EACCES;
583
579 async = s->async; 584 async = s->async;
580 585
581 if (!async) { 586 if (!async) {
@@ -584,8 +589,17 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
584 bi.buf_read_ptr = 0; 589 bi.buf_read_ptr = 0;
585 bi.buf_write_count = 0; 590 bi.buf_write_count = 0;
586 bi.buf_read_count = 0; 591 bi.buf_read_count = 0;
592 bi.bytes_read = 0;
593 bi.bytes_written = 0;
587 goto copyback; 594 goto copyback;
588 } 595 }
596 if (!s->busy) {
597 bi.bytes_read = 0;
598 bi.bytes_written = 0;
599 goto copyback_position;
600 }
601 if (s->busy != file)
602 return -EACCES;
589 603
590 if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) { 604 if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) {
591 bi.bytes_read = comedi_buf_read_alloc(async, bi.bytes_read); 605 bi.bytes_read = comedi_buf_read_alloc(async, bi.bytes_read);
@@ -604,6 +618,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
604 comedi_buf_write_free(async, bi.bytes_written); 618 comedi_buf_write_free(async, bi.bytes_written);
605 } 619 }
606 620
621copyback_position:
607 bi.buf_write_count = async->buf_write_count; 622 bi.buf_write_count = async->buf_write_count;
608 bi.buf_write_ptr = async->buf_write_ptr; 623 bi.buf_write_ptr = async->buf_write_ptr;
609 bi.buf_read_count = async->buf_read_count; 624 bi.buf_read_count = async->buf_read_count;
@@ -1576,6 +1591,19 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
1576 while (nbytes > 0 && !retval) { 1591 while (nbytes > 0 && !retval) {
1577 set_current_state(TASK_INTERRUPTIBLE); 1592 set_current_state(TASK_INTERRUPTIBLE);
1578 1593
1594 if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) {
1595 if (count == 0) {
1596 if (comedi_get_subdevice_runflags(s) &
1597 SRF_ERROR) {
1598 retval = -EPIPE;
1599 } else {
1600 retval = 0;
1601 }
1602 do_become_nonbusy(dev, s);
1603 }
1604 break;
1605 }
1606
1579 n = nbytes; 1607 n = nbytes;
1580 1608
1581 m = n; 1609 m = n;
@@ -1588,16 +1616,6 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
1588 n = m; 1616 n = m;
1589 1617
1590 if (n == 0) { 1618 if (n == 0) {
1591 if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) {
1592 if (comedi_get_subdevice_runflags(s) &
1593 SRF_ERROR) {
1594 retval = -EPIPE;
1595 } else {
1596 retval = 0;
1597 }
1598 do_become_nonbusy(dev, s);
1599 break;
1600 }
1601 if (file->f_flags & O_NONBLOCK) { 1619 if (file->f_flags & O_NONBLOCK) {
1602 retval = -EAGAIN; 1620 retval = -EAGAIN;
1603 break; 1621 break;
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index 5ccf246e2526..354fb7d29841 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -12,7 +12,6 @@ obj-$(CONFIG_COMEDI_SERIAL2002) += serial2002.o
12obj-$(CONFIG_COMEDI_SKEL) += skel.o 12obj-$(CONFIG_COMEDI_SKEL) += skel.o
13 13
14# Comedi ISA drivers 14# Comedi ISA drivers
15obj-$(CONFIG_COMEDI_8255) += 8255.o
16obj-$(CONFIG_COMEDI_ACL7225B) += acl7225b.o 15obj-$(CONFIG_COMEDI_ACL7225B) += acl7225b.o
17obj-$(CONFIG_COMEDI_PCL711) += pcl711.o 16obj-$(CONFIG_COMEDI_PCL711) += pcl711.o
18obj-$(CONFIG_COMEDI_PCL724) += pcl724.o 17obj-$(CONFIG_COMEDI_PCL724) += pcl724.o
@@ -26,7 +25,6 @@ obj-$(CONFIG_COMEDI_PCM3724) += pcm3724.o
26obj-$(CONFIG_COMEDI_PCM3730) += pcm3730.o 25obj-$(CONFIG_COMEDI_PCM3730) += pcm3730.o
27obj-$(CONFIG_COMEDI_RTI800) += rti800.o 26obj-$(CONFIG_COMEDI_RTI800) += rti800.o
28obj-$(CONFIG_COMEDI_RTI802) += rti802.o 27obj-$(CONFIG_COMEDI_RTI802) += rti802.o
29obj-$(CONFIG_COMEDI_DAS08) += das08.o
30obj-$(CONFIG_COMEDI_DAS16M1) += das16m1.o 28obj-$(CONFIG_COMEDI_DAS16M1) += das16m1.o
31obj-$(CONFIG_COMEDI_DAS16) += das16.o 29obj-$(CONFIG_COMEDI_DAS16) += das16.o
32obj-$(CONFIG_COMEDI_DAS800) += das800.o 30obj-$(CONFIG_COMEDI_DAS800) += das800.o
@@ -135,4 +133,6 @@ obj-$(CONFIG_COMEDI_NI_TIO) += ni_tio.o
135obj-$(CONFIG_COMEDI_NI_TIO) += ni_tiocmd.o 133obj-$(CONFIG_COMEDI_NI_TIO) += ni_tiocmd.o
136obj-$(CONFIG_COMEDI_NI_LABPC) += ni_labpc.o 134obj-$(CONFIG_COMEDI_NI_LABPC) += ni_labpc.o
137 135
136obj-$(CONFIG_COMEDI_8255) += 8255.o
137obj-$(CONFIG_COMEDI_DAS08) += das08.o
138obj-$(CONFIG_COMEDI_FC) += comedi_fc.o 138obj-$(CONFIG_COMEDI_FC) += comedi_fc.o
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index 2c986413a81a..b18e81d8cf8a 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -68,6 +68,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour
68#include "addi_common.h" 68#include "addi_common.h"
69#include "addi_amcc_s5933.h" 69#include "addi_amcc_s5933.h"
70 70
71#ifndef ADDIDATA_DRIVER_NAME
72#define ADDIDATA_DRIVER_NAME "addi_common"
73#endif
74
71/* Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH <info@addi-data.com>"); */ 75/* Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH <info@addi-data.com>"); */
72/* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */ 76/* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */
73/* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */ 77/* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */
@@ -2528,7 +2532,7 @@ static const struct addi_board boardtypes[] = {
2528#define n_boardtypes (sizeof(boardtypes)/sizeof(struct addi_board)) 2532#define n_boardtypes (sizeof(boardtypes)/sizeof(struct addi_board))
2529 2533
2530static struct comedi_driver driver_addi = { 2534static struct comedi_driver driver_addi = {
2531 .driver_name = "addi_common", 2535 .driver_name = ADDIDATA_DRIVER_NAME,
2532 .module = THIS_MODULE, 2536 .module = THIS_MODULE,
2533 .attach = i_ADDI_Attach, 2537 .attach = i_ADDI_Attach,
2534 .detach = i_ADDI_Detach, 2538 .detach = i_ADDI_Detach,
@@ -2570,10 +2574,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
2570 struct pcilst_struct *card = NULL; 2574 struct pcilst_struct *card = NULL;
2571 unsigned char pci_bus, pci_slot, pci_func; 2575 unsigned char pci_bus, pci_slot, pci_func;
2572 int i_Dma = 0; 2576 int i_Dma = 0;
2573 static char c_Identifier[150];
2574
2575 sprintf(c_Identifier, "Addi-Data GmbH Comedi %s",
2576 this_board->pc_DriverName);
2577 2577
2578 ret = alloc_private(dev, sizeof(struct addi_private)); 2578 ret = alloc_private(dev, sizeof(struct addi_private));
2579 if (ret < 0) 2579 if (ret < 0)
@@ -2583,7 +2583,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
2583 v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */ 2583 v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */
2584 pci_list_builded = 1; 2584 pci_list_builded = 1;
2585 } 2585 }
2586 /* printk("comedi%d: addi_common: board=%s",dev->minor,this_board->pc_DriverName); */ 2586 /* printk("comedi%d: "ADDIDATA_DRIVER_NAME": board=%s",dev->minor,this_board->pc_DriverName); */
2587 2587
2588 if ((this_board->i_Dma) && (it->options[2] == 0)) { 2588 if ((this_board->i_Dma) && (it->options[2] == 0)) {
2589 i_Dma = 1; 2589 i_Dma = 1;
@@ -2648,7 +2648,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
2648 2648
2649 if (irq > 0) { 2649 if (irq > 0) {
2650 if (request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED, 2650 if (request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED,
2651 c_Identifier, dev) < 0) { 2651 this_board->pc_DriverName, dev) < 0) {
2652 printk(", unable to allocate IRQ %u, DISABLING IT", 2652 printk(", unable to allocate IRQ %u, DISABLING IT",
2653 irq); 2653 irq);
2654 irq = 0; /* Can't use IRQ */ 2654 irq = 0; /* Can't use IRQ */
diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c
index da454e854c4c..6dfcbe803f2d 100644
--- a/drivers/staging/comedi/drivers/addi_apci_035.c
+++ b/drivers/staging/comedi/drivers/addi_apci_035.c
@@ -2,4 +2,6 @@
2 2
3#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ 3#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */
4 4
5#define ADDIDATA_DRIVER_NAME "addi_apci_035"
6
5#include "addi-data/addi_common.c" 7#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
index fa2056e8aa0e..4722ec834f7b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1032.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_1032 1 1#define CONFIG_APCI_1032 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_1032"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
index 7a5cae599ef8..db3dafdcf691 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1500.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_1500 1 1#define CONFIG_APCI_1500 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_1500"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c
index 8d414844009f..f591baff6a0b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1516.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1516.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_1516 1 1#define CONFIG_APCI_1516 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_1516"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
index 0351cdde1026..6f5c923ac226 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1564.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_1564 1 1#define CONFIG_APCI_1564 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_1564"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c
index 506799041294..1d926add9e6d 100644
--- a/drivers/staging/comedi/drivers/addi_apci_16xx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_16XX 1 1#define CONFIG_APCI_16XX 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_16xx"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c
index c433445913dd..df6ba8ccf56f 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1710.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1710.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_1710 1 1#define CONFIG_APCI_1710 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_1710"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c
index 271c47c8cad3..7266e412f0a6 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2016.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2016.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_2016 1 1#define CONFIG_APCI_2016 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_2016"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c
index 5108ea2a3924..f67da94119e8 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2032.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_2032 1 1#define CONFIG_APCI_2032 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_2032"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c
index e439f835cf4f..bc7f7d653503 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2200.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_2200 1 1#define CONFIG_APCI_2200 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_2200"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c
index df97c305828b..d86c4209cb90 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3001.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3001.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_3001 1 1#define CONFIG_APCI_3001 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_3001"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
index 9183125ddde4..0b22cf10415d 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3120.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_3120 1 1#define CONFIG_APCI_3120 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_3120"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c
index f25a70b3290b..159313997dcf 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3200.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_3200 1 1#define CONFIG_APCI_3200 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_3200"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c
index 1ee4778ad45b..733c69abc43a 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3300.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3300.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_3300 1 1#define CONFIG_APCI_3300 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_3300"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index 1049e20237e8..d8a01b154e35 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_3501 1 1#define CONFIG_APCI_3501 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_3501"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
index fb9deb7083bd..942bc9e259a8 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -1,3 +1,5 @@
1#define CONFIG_APCI_3XXX 1 1#define CONFIG_APCI_3XXX 1
2 2
3#define ADDIDATA_DRIVER_NAME "addi_apci_3xxx"
4
3#include "addi-data/addi_common.c" 5#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index 40eeecf5347f..e424a0c7d34f 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -7,17 +7,17 @@
7*/ 7*/
8/* 8/*
9Driver: adv_pci_dio 9Driver: adv_pci_dio
10Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1736UP, 10Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
11 PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, 11 PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E,
12 PCI-1756, PCI-1762 12 PCI-1754, PCI-1756, PCI-1762
13Author: Michal Dobes <dobes@tesnet.cz> 13Author: Michal Dobes <dobes@tesnet.cz>
14Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733, 14Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
15 PCI-1734, PCI-1736UP, PCI-1750, 15 PCI-1734, PCI-1735U, PCI-1736UP, PCI-1750,
16 PCI-1751, PCI-1752, PCI-1753, 16 PCI-1751, PCI-1752, PCI-1753,
17 PCI-1753+PCI-1753E, PCI-1754, PCI-1756, 17 PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
18 PCI-1760, PCI-1762 18 PCI-1760, PCI-1762
19Status: untested 19Status: untested
20Updated: Mon, 14 Apr 2008 10:43:08 +0100 20Updated: Tue, 04 May 2010 13:00:00 +0000
21 21
22This driver supports now only insn interface for DI/DO/DIO. 22This driver supports now only insn interface for DI/DO/DIO.
23 23
@@ -35,6 +35,7 @@ Configuration options:
35 35
36#include "comedi_pci.h" 36#include "comedi_pci.h"
37#include "8255.h" 37#include "8255.h"
38#include "8253.h"
38 39
39#undef PCI_DIO_EXTDEBUG /* if defined, enable extensive debug logging */ 40#undef PCI_DIO_EXTDEBUG /* if defined, enable extensive debug logging */
40 41
@@ -49,7 +50,7 @@ Configuration options:
49 50
50/* hardware types of the cards */ 51/* hardware types of the cards */
51enum hw_cards_id { 52enum hw_cards_id {
52 TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1736, 53 TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736,
53 TYPE_PCI1750, 54 TYPE_PCI1750,
54 TYPE_PCI1751, 55 TYPE_PCI1751,
55 TYPE_PCI1752, 56 TYPE_PCI1752,
@@ -67,7 +68,10 @@ enum hw_io_access {
67#define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */ 68#define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */
68#define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */ 69#define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */
69#define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per card */ 70#define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per card */
71#define MAX_8254_SUBDEVS 1 /* max number of 8254 counter subdevs per card */
72 /* (could be more than one 8254 per subdevice) */
70 73
74#define SIZE_8254 4 /* 8254 IO space length */
71#define SIZE_8255 4 /* 8255 IO space length */ 75#define SIZE_8255 4 /* 8255 IO space length */
72 76
73#define PCIDIO_MAINREG 2 /* main I/O region for all Advantech cards? */ 77#define PCIDIO_MAINREG 2 /* main I/O region for all Advantech cards? */
@@ -85,6 +89,12 @@ enum hw_io_access {
85#define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */ 89#define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */
86#define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */ 90#define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */
87 91
92/* Advantech PCI-1735U */
93#define PCI1735_DI 0 /* R: Digital input 0-31 */
94#define PCI1735_DO 0 /* W: Digital output 0-31 */
95#define PCI1735_C8254 4 /* R/W: 8254 counter */
96#define PCI1735_BOARDID 8 /* R: Board I/D switch for 1735U */
97
88/* Advantech PCI-1736UP */ 98/* Advantech PCI-1736UP */
89#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */ 99#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */
90#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */ 100#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */
@@ -192,7 +202,8 @@ static int pci_dio_detach(struct comedi_device *dev);
192struct diosubd_data { 202struct diosubd_data {
193 int chans; /* num of chans */ 203 int chans; /* num of chans */
194 int addr; /* PCI address ofset */ 204 int addr; /* PCI address ofset */
195 int regs; /* number of registers to read or 8255 subdevices */ 205 int regs; /* number of registers to read or 8255
206 subdevices or 8254 chips */
196 unsigned int specflags; /* addon subdevice flags */ 207 unsigned int specflags; /* addon subdevice flags */
197}; 208};
198 209
@@ -206,6 +217,7 @@ struct dio_boardtype {
206 struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */ 217 struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */
207 struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */ 218 struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */
208 struct diosubd_data boardid; /* card supports board ID switch */ 219 struct diosubd_data boardid; /* card supports board ID switch */
220 struct diosubd_data s8254[MAX_8254_SUBDEVS]; /* 8254 subdevices */
209 enum hw_io_access io_access; 221 enum hw_io_access io_access;
210}; 222};
211 223
@@ -214,6 +226,7 @@ static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
214 PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 226 PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
215 PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 227 PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
216 PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 228 PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
229 PCI_VENDOR_ID_ADVANTECH, 0x1735, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
217 PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 230 PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
218 PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 231 PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
219 PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 232 PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
@@ -235,14 +248,15 @@ static const struct dio_boardtype boardtypes[] = {
235 {{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}}, 248 {{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
236 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 249 {{0, 0, 0, 0}, {0, 0, 0, 0}},
237 {4, PCI173x_BOARDID, 1, SDF_INTERNAL}, 250 {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
238 IO_8b, 251 {{0, 0, 0, 0}},
239 }, 252 IO_8b},
240 {"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG, 253 {"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
241 TYPE_PCI1733, 254 TYPE_PCI1733,
242 {{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}}, 255 {{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
243 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 256 {{0, 0, 0, 0}, {0, 0, 0, 0}},
244 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 257 {{0, 0, 0, 0}, {0, 0, 0, 0}},
245 {4, PCI173x_BOARDID, 1, SDF_INTERNAL}, 258 {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
259 {{0, 0, 0, 0}},
246 IO_8b}, 260 IO_8b},
247 {"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG, 261 {"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG,
248 TYPE_PCI1734, 262 TYPE_PCI1734,
@@ -250,6 +264,15 @@ static const struct dio_boardtype boardtypes[] = {
250 {{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}}, 264 {{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
251 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 265 {{0, 0, 0, 0}, {0, 0, 0, 0}},
252 {4, PCI173x_BOARDID, 1, SDF_INTERNAL}, 266 {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
267 {{0, 0, 0, 0}},
268 IO_8b},
269 {"pci1735", PCI_VENDOR_ID_ADVANTECH, 0x1735, PCIDIO_MAINREG,
270 TYPE_PCI1735,
271 {{32, PCI1735_DI, 4, 0}, {0, 0, 0, 0}},
272 {{32, PCI1735_DO, 4, 0}, {0, 0, 0, 0}},
273 {{0, 0, 0, 0}, {0, 0, 0, 0}},
274 { 4, PCI1735_BOARDID, 1, SDF_INTERNAL},
275 {{3, PCI1735_C8254, 1, 0}},
253 IO_8b}, 276 IO_8b},
254 {"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG, 277 {"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG,
255 TYPE_PCI1736, 278 TYPE_PCI1736,
@@ -257,14 +280,15 @@ static const struct dio_boardtype boardtypes[] = {
257 {{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}}, 280 {{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
258 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 281 {{0, 0, 0, 0}, {0, 0, 0, 0}},
259 {4, PCI1736_BOARDID, 1, SDF_INTERNAL}, 282 {4, PCI1736_BOARDID, 1, SDF_INTERNAL},
260 IO_8b, 283 {{0, 0, 0, 0}},
261 }, 284 IO_8b},
262 {"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG, 285 {"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
263 TYPE_PCI1750, 286 TYPE_PCI1750,
264 {{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}}, 287 {{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
265 {{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}}, 288 {{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
266 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 289 {{0, 0, 0, 0}, {0, 0, 0, 0}},
267 {0, 0, 0, 0}, 290 {0, 0, 0, 0},
291 {{0, 0, 0, 0}},
268 IO_8b}, 292 IO_8b},
269 {"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG, 293 {"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG,
270 TYPE_PCI1751, 294 TYPE_PCI1751,
@@ -272,6 +296,7 @@ static const struct dio_boardtype boardtypes[] = {
272 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 296 {{0, 0, 0, 0}, {0, 0, 0, 0}},
273 {{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}}, 297 {{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
274 {0, 0, 0, 0}, 298 {0, 0, 0, 0},
299 {{0, 0, 0, 0}},
275 IO_8b}, 300 IO_8b},
276 {"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG, 301 {"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
277 TYPE_PCI1752, 302 TYPE_PCI1752,
@@ -279,6 +304,7 @@ static const struct dio_boardtype boardtypes[] = {
279 {{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}}, 304 {{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
280 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 305 {{0, 0, 0, 0}, {0, 0, 0, 0}},
281 {4, PCI175x_BOARDID, 1, SDF_INTERNAL}, 306 {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
307 {{0, 0, 0, 0}},
282 IO_16b}, 308 IO_16b},
283 {"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG, 309 {"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
284 TYPE_PCI1753, 310 TYPE_PCI1753,
@@ -286,6 +312,7 @@ static const struct dio_boardtype boardtypes[] = {
286 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 312 {{0, 0, 0, 0}, {0, 0, 0, 0}},
287 {{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}}, 313 {{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
288 {0, 0, 0, 0}, 314 {0, 0, 0, 0},
315 {{0, 0, 0, 0}},
289 IO_8b}, 316 IO_8b},
290 {"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG, 317 {"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
291 TYPE_PCI1753E, 318 TYPE_PCI1753E,
@@ -293,6 +320,7 @@ static const struct dio_boardtype boardtypes[] = {
293 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 320 {{0, 0, 0, 0}, {0, 0, 0, 0}},
294 {{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}}, 321 {{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
295 {0, 0, 0, 0}, 322 {0, 0, 0, 0},
323 {{0, 0, 0, 0}},
296 IO_8b}, 324 IO_8b},
297 {"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG, 325 {"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG,
298 TYPE_PCI1754, 326 TYPE_PCI1754,
@@ -300,6 +328,7 @@ static const struct dio_boardtype boardtypes[] = {
300 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 328 {{0, 0, 0, 0}, {0, 0, 0, 0}},
301 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 329 {{0, 0, 0, 0}, {0, 0, 0, 0}},
302 {4, PCI175x_BOARDID, 1, SDF_INTERNAL}, 330 {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
331 {{0, 0, 0, 0}},
303 IO_16b}, 332 IO_16b},
304 {"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG, 333 {"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG,
305 TYPE_PCI1756, 334 TYPE_PCI1756,
@@ -307,6 +336,7 @@ static const struct dio_boardtype boardtypes[] = {
307 {{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}}, 336 {{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
308 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 337 {{0, 0, 0, 0}, {0, 0, 0, 0}},
309 {4, PCI175x_BOARDID, 1, SDF_INTERNAL}, 338 {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
339 {{0, 0, 0, 0}},
310 IO_16b}, 340 IO_16b},
311 {"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0, 341 {"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0,
312 TYPE_PCI1760, 342 TYPE_PCI1760,
@@ -314,6 +344,7 @@ static const struct dio_boardtype boardtypes[] = {
314 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 344 {{0, 0, 0, 0}, {0, 0, 0, 0}},
315 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 345 {{0, 0, 0, 0}, {0, 0, 0, 0}},
316 {0, 0, 0, 0}, 346 {0, 0, 0, 0},
347 {{0, 0, 0, 0}},
317 IO_8b}, 348 IO_8b},
318 {"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG, 349 {"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG,
319 TYPE_PCI1762, 350 TYPE_PCI1762,
@@ -321,6 +352,7 @@ static const struct dio_boardtype boardtypes[] = {
321 {{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}}, 352 {{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
322 {{0, 0, 0, 0}, {0, 0, 0, 0}}, 353 {{0, 0, 0, 0}, {0, 0, 0, 0}},
323 {4, PCI1762_BOARDID, 1, SDF_INTERNAL}, 354 {4, PCI1762_BOARDID, 1, SDF_INTERNAL},
355 {{0, 0, 0, 0}},
324 IO_16b} 356 IO_16b}
325}; 357};
326 358
@@ -440,6 +472,83 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
440/* 472/*
441============================================================================== 473==============================================================================
442*/ 474*/
475static int pci_8254_insn_read(struct comedi_device *dev,
476 struct comedi_subdevice *s,
477 struct comedi_insn *insn, unsigned int *data)
478{
479 const struct diosubd_data *d = (const struct diosubd_data *)s->private;
480 unsigned int chan, chip, chipchan;
481 unsigned long flags;
482
483 chan = CR_CHAN(insn->chanspec); /* channel on subdevice */
484 chip = chan / 3; /* chip on subdevice */
485 chipchan = chan - (3 * chip); /* channel on chip on subdevice */
486 spin_lock_irqsave(&s->spin_lock, flags);
487 data[0] = i8254_read(dev->iobase + d->addr + (SIZE_8254 * chip),
488 0, chipchan);
489 spin_unlock_irqrestore(&s->spin_lock, flags);
490 return 1;
491}
492
493/*
494==============================================================================
495*/
496static int pci_8254_insn_write(struct comedi_device *dev,
497 struct comedi_subdevice *s,
498 struct comedi_insn *insn, unsigned int *data)
499{
500 const struct diosubd_data *d = (const struct diosubd_data *)s->private;
501 unsigned int chan, chip, chipchan;
502 unsigned long flags;
503
504 chan = CR_CHAN(insn->chanspec); /* channel on subdevice */
505 chip = chan / 3; /* chip on subdevice */
506 chipchan = chan - (3 * chip); /* channel on chip on subdevice */
507 spin_lock_irqsave(&s->spin_lock, flags);
508 i8254_write(dev->iobase + d->addr + (SIZE_8254 * chip),
509 0, chipchan, data[0]);
510 spin_unlock_irqrestore(&s->spin_lock, flags);
511 return 1;
512}
513
514/*
515==============================================================================
516*/
517static int pci_8254_insn_config(struct comedi_device *dev,
518 struct comedi_subdevice *s,
519 struct comedi_insn *insn, unsigned int *data)
520{
521 const struct diosubd_data *d = (const struct diosubd_data *)s->private;
522 unsigned int chan, chip, chipchan;
523 unsigned long iobase;
524 int ret = 0;
525 unsigned long flags;
526
527 chan = CR_CHAN(insn->chanspec); /* channel on subdevice */
528 chip = chan / 3; /* chip on subdevice */
529 chipchan = chan - (3 * chip); /* channel on chip on subdevice */
530 iobase = dev->iobase + d->addr + (SIZE_8254 * chip);
531 spin_lock_irqsave(&s->spin_lock, flags);
532 switch (data[0]) {
533 case INSN_CONFIG_SET_COUNTER_MODE:
534 ret = i8254_set_mode(iobase, 0, chipchan, data[1]);
535 if (ret < 0)
536 ret = -EINVAL;
537 break;
538 case INSN_CONFIG_8254_READ_STATUS:
539 data[1] = i8254_status(iobase, 0, chipchan);
540 break;
541 default:
542 ret = -EINVAL;
543 break;
544 }
545 spin_unlock_irqrestore(&s->spin_lock, flags);
546 return ret < 0 ? ret : insn->n;
547}
548
549/*
550==============================================================================
551*/
443static int pci1760_unchecked_mbxrequest(struct comedi_device *dev, 552static int pci1760_unchecked_mbxrequest(struct comedi_device *dev,
444 unsigned char *omb, unsigned char *imb, 553 unsigned char *omb, unsigned char *imb,
445 int repeats) 554 int repeats)
@@ -708,6 +817,15 @@ static int pci_dio_reset(struct comedi_device *dev)
708 outb(0, dev->iobase + PCI1734_IDO + 2); 817 outb(0, dev->iobase + PCI1734_IDO + 2);
709 outb(0, dev->iobase + PCI1734_IDO + 3); 818 outb(0, dev->iobase + PCI1734_IDO + 3);
710 break; 819 break;
820 case TYPE_PCI1735:
821 outb(0, dev->iobase + PCI1735_DO); /* clear outputs */
822 outb(0, dev->iobase + PCI1735_DO + 1);
823 outb(0, dev->iobase + PCI1735_DO + 2);
824 outb(0, dev->iobase + PCI1735_DO + 3);
825 i8254_set_mode(dev->iobase + PCI1735_C8254, 0, 0, I8254_MODE0);
826 i8254_set_mode(dev->iobase + PCI1735_C8254, 0, 1, I8254_MODE0);
827 i8254_set_mode(dev->iobase + PCI1735_C8254, 0, 2, I8254_MODE0);
828 break;
711 829
712 case TYPE_PCI1736: 830 case TYPE_PCI1736:
713 outb(0, dev->iobase + PCI1736_IDO); 831 outb(0, dev->iobase + PCI1736_IDO);
@@ -877,6 +995,26 @@ static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s,
877/* 995/*
878============================================================================== 996==============================================================================
879*/ 997*/
998static int pci_dio_add_8254(struct comedi_device *dev,
999 struct comedi_subdevice * s,
1000 const struct diosubd_data *d, int subdev)
1001{
1002 s->type = COMEDI_SUBD_COUNTER;
1003 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1004 s->n_chan = d->chans;
1005 s->maxdata = 65535;
1006 s->len_chanlist = d->chans;
1007 s->insn_read = pci_8254_insn_read;
1008 s->insn_write = pci_8254_insn_write;
1009 s->insn_config = pci_8254_insn_config;
1010 s->private = (void *)d;
1011
1012 return 0;
1013}
1014
1015/*
1016==============================================================================
1017*/
880static int CheckAndAllocCard(struct comedi_device *dev, 1018static int CheckAndAllocCard(struct comedi_device *dev,
881 struct comedi_devconfig *it, 1019 struct comedi_devconfig *it,
882 struct pci_dev *pcidev) 1020 struct pci_dev *pcidev)
@@ -979,6 +1117,9 @@ static int pci_dio_attach(struct comedi_device *dev,
979 n_subdevices += this_board->sdio[i].regs; 1117 n_subdevices += this_board->sdio[i].regs;
980 if (this_board->boardid.chans) 1118 if (this_board->boardid.chans)
981 n_subdevices++; 1119 n_subdevices++;
1120 for (i = 0; i < MAX_8254_SUBDEVS; i++)
1121 if (this_board->s8254[i].chans)
1122 n_subdevices++;
982 } 1123 }
983 1124
984 ret = alloc_subdevices(dev, n_subdevices); 1125 ret = alloc_subdevices(dev, n_subdevices);
@@ -1022,6 +1163,13 @@ static int pci_dio_attach(struct comedi_device *dev,
1022 subdev++; 1163 subdev++;
1023 } 1164 }
1024 1165
1166 for (i = 0; i < MAX_8254_SUBDEVS; i++)
1167 if (this_board->s8254[i].chans) {
1168 s = dev->subdevices + subdev;
1169 pci_dio_add_8254(dev, s, &this_board->s8254[i], subdev);
1170 subdev++;
1171 }
1172
1025 if (this_board->cardtype == TYPE_PCI1760) 1173 if (this_board->cardtype == TYPE_PCI1760)
1026 pci1760_attach(dev, it); 1174 pci1760_attach(dev, it);
1027 1175
@@ -1067,6 +1215,16 @@ static int pci_dio_detach(struct comedi_device *dev)
1067 } 1215 }
1068 } 1216 }
1069 1217
1218 if (this_board->boardid.chans) {
1219 subdev++;
1220 }
1221
1222 for (i = 0; i < MAX_8254_SUBDEVS; i++) {
1223 if (this_board->s8254[i].chans) {
1224 subdev++;
1225 }
1226 }
1227
1070 for (i = 0; i < dev->n_subdevices; i++) { 1228 for (i = 0; i < dev->n_subdevices; i++) {
1071 s = dev->subdevices + i; 1229 s = dev->subdevices + i;
1072 s->private = NULL; 1230 s->private = NULL;
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index 8eb67651486a..bf27617aa62d 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -460,6 +460,7 @@ struct dio200_subdev_8254 {
460 int has_clk_gat_sce; 460 int has_clk_gat_sce;
461 unsigned clock_src[3]; /* Current clock sources */ 461 unsigned clock_src[3]; /* Current clock sources */
462 unsigned gate_src[3]; /* Current gate sources */ 462 unsigned gate_src[3]; /* Current gate sources */
463 spinlock_t spinlock;
463}; 464};
464 465
465struct dio200_subdev_intr { 466struct dio200_subdev_intr {
@@ -1042,8 +1043,11 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
1042{ 1043{
1043 struct dio200_subdev_8254 *subpriv = s->private; 1044 struct dio200_subdev_8254 *subpriv = s->private;
1044 int chan = CR_CHAN(insn->chanspec); 1045 int chan = CR_CHAN(insn->chanspec);
1046 unsigned long flags;
1045 1047
1048 spin_lock_irqsave(&subpriv->spinlock, flags);
1046 data[0] = i8254_read(subpriv->iobase, 0, chan); 1049 data[0] = i8254_read(subpriv->iobase, 0, chan);
1050 spin_unlock_irqrestore(&subpriv->spinlock, flags);
1047 1051
1048 return 1; 1052 return 1;
1049} 1053}
@@ -1057,8 +1061,11 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
1057{ 1061{
1058 struct dio200_subdev_8254 *subpriv = s->private; 1062 struct dio200_subdev_8254 *subpriv = s->private;
1059 int chan = CR_CHAN(insn->chanspec); 1063 int chan = CR_CHAN(insn->chanspec);
1064 unsigned long flags;
1060 1065
1066 spin_lock_irqsave(&subpriv->spinlock, flags);
1061 i8254_write(subpriv->iobase, 0, chan, data[0]); 1067 i8254_write(subpriv->iobase, 0, chan, data[0]);
1068 spin_unlock_irqrestore(&subpriv->spinlock, flags);
1062 1069
1063 return 1; 1070 return 1;
1064} 1071}
@@ -1151,14 +1158,16 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
1151 struct comedi_insn *insn, unsigned int *data) 1158 struct comedi_insn *insn, unsigned int *data)
1152{ 1159{
1153 struct dio200_subdev_8254 *subpriv = s->private; 1160 struct dio200_subdev_8254 *subpriv = s->private;
1154 int ret; 1161 int ret = 0;
1155 int chan = CR_CHAN(insn->chanspec); 1162 int chan = CR_CHAN(insn->chanspec);
1163 unsigned long flags;
1156 1164
1165 spin_lock_irqsave(&subpriv->spinlock, flags);
1157 switch (data[0]) { 1166 switch (data[0]) {
1158 case INSN_CONFIG_SET_COUNTER_MODE: 1167 case INSN_CONFIG_SET_COUNTER_MODE:
1159 ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]); 1168 ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
1160 if (ret < 0) 1169 if (ret < 0)
1161 return -EINVAL; 1170 ret = -EINVAL;
1162 break; 1171 break;
1163 case INSN_CONFIG_8254_READ_STATUS: 1172 case INSN_CONFIG_8254_READ_STATUS:
1164 data[1] = i8254_status(subpriv->iobase, 0, chan); 1173 data[1] = i8254_status(subpriv->iobase, 0, chan);
@@ -1166,30 +1175,35 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
1166 case INSN_CONFIG_SET_GATE_SRC: 1175 case INSN_CONFIG_SET_GATE_SRC:
1167 ret = dio200_set_gate_src(subpriv, chan, data[2]); 1176 ret = dio200_set_gate_src(subpriv, chan, data[2]);
1168 if (ret < 0) 1177 if (ret < 0)
1169 return -EINVAL; 1178 ret = -EINVAL;
1170 break; 1179 break;
1171 case INSN_CONFIG_GET_GATE_SRC: 1180 case INSN_CONFIG_GET_GATE_SRC:
1172 ret = dio200_get_gate_src(subpriv, chan); 1181 ret = dio200_get_gate_src(subpriv, chan);
1173 if (ret < 0) 1182 if (ret < 0) {
1174 return -EINVAL; 1183 ret = -EINVAL;
1184 break;
1185 }
1175 data[2] = ret; 1186 data[2] = ret;
1176 break; 1187 break;
1177 case INSN_CONFIG_SET_CLOCK_SRC: 1188 case INSN_CONFIG_SET_CLOCK_SRC:
1178 ret = dio200_set_clock_src(subpriv, chan, data[1]); 1189 ret = dio200_set_clock_src(subpriv, chan, data[1]);
1179 if (ret < 0) 1190 if (ret < 0)
1180 return -EINVAL; 1191 ret = -EINVAL;
1181 break; 1192 break;
1182 case INSN_CONFIG_GET_CLOCK_SRC: 1193 case INSN_CONFIG_GET_CLOCK_SRC:
1183 ret = dio200_get_clock_src(subpriv, chan, &data[2]); 1194 ret = dio200_get_clock_src(subpriv, chan, &data[2]);
1184 if (ret < 0) 1195 if (ret < 0) {
1185 return -EINVAL; 1196 ret = -EINVAL;
1197 break;
1198 }
1186 data[1] = ret; 1199 data[1] = ret;
1187 break; 1200 break;
1188 default: 1201 default:
1189 return -EINVAL; 1202 ret = -EINVAL;
1190 break; 1203 break;
1191 } 1204 }
1192 return insn->n; 1205 spin_unlock_irqrestore(&subpriv->spinlock, flags);
1206 return ret < 0 ? ret : insn->n;
1193} 1207}
1194 1208
1195/* 1209/*
@@ -1222,6 +1236,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
1222 s->insn_write = dio200_subdev_8254_write; 1236 s->insn_write = dio200_subdev_8254_write;
1223 s->insn_config = dio200_subdev_8254_config; 1237 s->insn_config = dio200_subdev_8254_config;
1224 1238
1239 spin_lock_init(&subpriv->spinlock);
1225 subpriv->iobase = offset + iobase; 1240 subpriv->iobase = offset + iobase;
1226 subpriv->has_clk_gat_sce = has_clk_gat_sce; 1241 subpriv->has_clk_gat_sce = has_clk_gat_sce;
1227 if (has_clk_gat_sce) { 1242 if (has_clk_gat_sce) {
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index cedb02d40f95..3a46f0c0bff9 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -123,7 +123,7 @@ static const struct ni_board_struct ni_boards[] = {
123 .adbits = 12, 123 .adbits = 12,
124 .ai_fifo_depth = 1024, 124 .ai_fifo_depth = 1024,
125 .alwaysdither = 0, 125 .alwaysdither = 0,
126 .gainlkup = ai_gain_16, 126 .gainlkup = ai_gain_4,
127 .ai_speed = 5000, 127 .ai_speed = 5000,
128 .n_aochan = 2, 128 .n_aochan = 2,
129 .aobits = 12, 129 .aobits = 12,
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 86f035d00675..27b4cb2e2ec2 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -351,8 +351,7 @@ static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
351 int ret = 0; 351 int ret = 0;
352 352
353 if (!this_usbduxsub) { 353 if (!this_usbduxsub) {
354 dev_err(&this_usbduxsub->interface->dev, 354 pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
355 "comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
356 return -EFAULT; 355 return -EFAULT;
357 } 356 }
358 dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n"); 357 dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c
index 1f020dad6234..3320359408a9 100644
--- a/drivers/staging/dream/synaptics_i2c_rmi.c
+++ b/drivers/staging/dream/synaptics_i2c_rmi.c
@@ -519,7 +519,6 @@ err_input_register_device_failed:
519err_input_dev_alloc_failed: 519err_input_dev_alloc_failed:
520err_detect_failed: 520err_detect_failed:
521err_power_failed: 521err_power_failed:
522 i2c_set_clientdata(client, NULL);
523 kfree(ts); 522 kfree(ts);
524err_alloc_data_failed: 523err_alloc_data_failed:
525err_check_functionality_failed: 524err_check_functionality_failed:
@@ -537,7 +536,6 @@ static int synaptics_ts_remove(struct i2c_client *client)
537 else 536 else
538 hrtimer_cancel(&ts->timer); 537 hrtimer_cancel(&ts->timer);
539 input_unregister_device(ts->input_dev); 538 input_unregister_device(ts->input_dev);
540 i2c_set_clientdata(client, NULL);
541 kfree(ts); 539 kfree(ts);
542 return 0; 540 return 0;
543} 541}
diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c
index bd5adbc2a238..d33947b0378f 100644
--- a/drivers/staging/dt3155/allocator.c
+++ b/drivers/staging/dt3155/allocator.c
@@ -176,9 +176,7 @@ int allocator_free_dma(unsigned long address)
176 prev = ptr; ptr = ptr->next; 176 prev = ptr; ptr = ptr->next;
177 177
178 if (!ptr) { 178 if (!ptr) {
179 printk(KERN_ERR ALL_MSG 179 pr_err(ALL_MSG "free_dma but add. not allocated\n");
180 "free_dma(0x%08lx) but add. not allocated\n",
181 ptr->address);
182 return -EINVAL; 180 return -EINVAL;
183 } 181 }
184 PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size, 182 PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size,
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c
index bd925457f8b7..72f5c1f56d19 100644
--- a/drivers/staging/go7007/wis-saa7113.c
+++ b/drivers/staging/go7007/wis-saa7113.c
@@ -289,7 +289,6 @@ static int wis_saa7113_probe(struct i2c_client *client,
289 if (write_regs(client, initial_registers) < 0) { 289 if (write_regs(client, initial_registers) < 0) {
290 printk(KERN_ERR 290 printk(KERN_ERR
291 "wis-saa7113: error initializing SAA7113\n"); 291 "wis-saa7113: error initializing SAA7113\n");
292 i2c_set_clientdata(client, NULL);
293 kfree(dec); 292 kfree(dec);
294 return -ENODEV; 293 return -ENODEV;
295 } 294 }
@@ -301,7 +300,6 @@ static int wis_saa7113_remove(struct i2c_client *client)
301{ 300{
302 struct wis_saa7113 *dec = i2c_get_clientdata(client); 301 struct wis_saa7113 *dec = i2c_get_clientdata(client);
303 302
304 i2c_set_clientdata(client, NULL);
305 kfree(dec); 303 kfree(dec);
306 return 0; 304 return 0;
307} 305}
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c
index b2eb804c1954..cd950b61cf70 100644
--- a/drivers/staging/go7007/wis-saa7115.c
+++ b/drivers/staging/go7007/wis-saa7115.c
@@ -422,7 +422,6 @@ static int wis_saa7115_probe(struct i2c_client *client,
422 if (write_regs(client, initial_registers) < 0) { 422 if (write_regs(client, initial_registers) < 0) {
423 printk(KERN_ERR 423 printk(KERN_ERR
424 "wis-saa7115: error initializing SAA7115\n"); 424 "wis-saa7115: error initializing SAA7115\n");
425 i2c_set_clientdata(client, NULL);
426 kfree(dec); 425 kfree(dec);
427 return -ENODEV; 426 return -ENODEV;
428 } 427 }
@@ -434,7 +433,6 @@ static int wis_saa7115_remove(struct i2c_client *client)
434{ 433{
435 struct wis_saa7115 *dec = i2c_get_clientdata(client); 434 struct wis_saa7115 *dec = i2c_get_clientdata(client);
436 435
437 i2c_set_clientdata(client, NULL);
438 kfree(dec); 436 kfree(dec);
439 return 0; 437 return 0;
440} 438}
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c
index b1013291190f..981c9b311b8b 100644
--- a/drivers/staging/go7007/wis-sony-tuner.c
+++ b/drivers/staging/go7007/wis-sony-tuner.c
@@ -684,7 +684,6 @@ static int wis_sony_tuner_remove(struct i2c_client *client)
684{ 684{
685 struct wis_sony_tuner *t = i2c_get_clientdata(client); 685 struct wis_sony_tuner *t = i2c_get_clientdata(client);
686 686
687 i2c_set_clientdata(client, NULL);
688 kfree(t); 687 kfree(t);
689 return 0; 688 return 0;
690} 689}
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c
index 315268d130dd..ee28a99dc388 100644
--- a/drivers/staging/go7007/wis-tw2804.c
+++ b/drivers/staging/go7007/wis-tw2804.c
@@ -323,7 +323,6 @@ static int wis_tw2804_remove(struct i2c_client *client)
323{ 323{
324 struct wis_tw2804 *dec = i2c_get_clientdata(client); 324 struct wis_tw2804 *dec = i2c_get_clientdata(client);
325 325
326 i2c_set_clientdata(client, NULL);
327 kfree(dec); 326 kfree(dec);
328 return 0; 327 return 0;
329} 328}
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
index 2afea09091b9..80d47269b1c0 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -294,7 +294,6 @@ static int wis_tw9903_probe(struct i2c_client *client,
294 294
295 if (write_regs(client, initial_registers) < 0) { 295 if (write_regs(client, initial_registers) < 0) {
296 printk(KERN_ERR "wis-tw9903: error initializing TW9903\n"); 296 printk(KERN_ERR "wis-tw9903: error initializing TW9903\n");
297 i2c_set_clientdata(client, NULL);
298 kfree(dec); 297 kfree(dec);
299 return -ENODEV; 298 return -ENODEV;
300 } 299 }
@@ -306,7 +305,6 @@ static int wis_tw9903_remove(struct i2c_client *client)
306{ 305{
307 struct wis_tw9903 *dec = i2c_get_clientdata(client); 306 struct wis_tw9903 *dec = i2c_get_clientdata(client);
308 307
309 i2c_set_clientdata(client, NULL);
310 kfree(dec); 308 kfree(dec);
311 return 0; 309 return 0;
312} 310}
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
index a4555e6f133f..014f6684faba 100644
--- a/drivers/staging/iio/Documentation/iio_utils.h
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -62,9 +62,8 @@ inline int find_type_by_name(const char *name, const char *type)
62 1) != 0) { 62 1) != 0) {
63 filename = malloc(strlen(iio_dir) 63 filename = malloc(strlen(iio_dir)
64 + strlen(type) 64 + strlen(type)
65 + 1
66 + numstrlen 65 + numstrlen
67 + 1); 66 + 6);
68 if (filename == NULL) 67 if (filename == NULL)
69 return -ENOMEM; 68 return -ENOMEM;
70 sprintf(filename, "%s%s%d/name", 69 sprintf(filename, "%s%s%d/name",
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 20e267448d1f..905f8560d31f 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -1011,7 +1011,6 @@ error_put_reg:
1011 if (!IS_ERR(st->reg)) 1011 if (!IS_ERR(st->reg))
1012 regulator_put(st->reg); 1012 regulator_put(st->reg);
1013error_free_st: 1013error_free_st:
1014 i2c_set_clientdata(client, NULL);
1015 kfree(st); 1014 kfree(st);
1016 1015
1017error_ret: 1016error_ret:
@@ -1030,7 +1029,6 @@ static int max1363_remove(struct i2c_client *client)
1030 regulator_disable(st->reg); 1029 regulator_disable(st->reg);
1031 regulator_put(st->reg); 1030 regulator_put(st->reg);
1032 } 1031 }
1033 i2c_set_clientdata(client, NULL);
1034 kfree(st); 1032 kfree(st);
1035 1033
1036 return 0; 1034 return 0;
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 43aaacff4e74..e4b0a5ef1c1f 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -694,7 +694,6 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
694fail2: 694fail2:
695 iio_device_unregister(chip->indio_dev); 695 iio_device_unregister(chip->indio_dev);
696fail1: 696fail1:
697 i2c_set_clientdata(client, NULL);
698 kfree(chip); 697 kfree(chip);
699 return err; 698 return err;
700} 699}
@@ -705,7 +704,6 @@ static int tsl2563_remove(struct i2c_client *client)
705 704
706 iio_device_unregister(chip->indio_dev); 705 iio_device_unregister(chip->indio_dev);
707 706
708 i2c_set_clientdata(client, NULL);
709 kfree(chip); 707 kfree(chip);
710 return 0; 708 return 0;
711} 709}
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 1f14cd4770e7..294272d0619f 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -20,7 +20,7 @@ static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
20 if ((length == 0) || (bytes_per_datum == 0)) 20 if ((length == 0) || (bytes_per_datum == 0))
21 return -EINVAL; 21 return -EINVAL;
22 __iio_update_ring_buffer(&ring->buf, bytes_per_datum, length); 22 __iio_update_ring_buffer(&ring->buf, bytes_per_datum, length);
23 ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL); 23 ring->data = kmalloc(length*ring->buf.bpd, GFP_ATOMIC);
24 ring->read_p = NULL; 24 ring->read_p = NULL;
25 ring->write_p = NULL; 25 ring->write_p = NULL;
26 ring->last_written_p = NULL; 26 ring->last_written_p = NULL;
diff --git a/drivers/staging/mrst-touchscreen/Kconfig b/drivers/staging/mrst-touchscreen/Kconfig
new file mode 100644
index 000000000000..c2af49217084
--- /dev/null
+++ b/drivers/staging/mrst-touchscreen/Kconfig
@@ -0,0 +1,7 @@
1config TOUCHSCREEN_INTEL_MID
2 tristate "Intel MID platform resistive touchscreen"
3 depends on INTEL_SCU_IPC
4 default y
5 help
6 Say Y here if you have a Intel MID based touchscreen
7 If unsure, say N.
diff --git a/drivers/staging/mrst-touchscreen/Makefile b/drivers/staging/mrst-touchscreen/Makefile
new file mode 100644
index 000000000000..2d638b0d70bf
--- /dev/null
+++ b/drivers/staging/mrst-touchscreen/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) := intel_mid_touch.o
2
3
diff --git a/drivers/staging/mrst-touchscreen/TODO b/drivers/staging/mrst-touchscreen/TODO
new file mode 100644
index 000000000000..7157028d634a
--- /dev/null
+++ b/drivers/staging/mrst-touchscreen/TODO
@@ -0,0 +1,2 @@
1- Move the driver to not think it is SPI (requires fixing some of the SFI
2 and firmware side)
diff --git a/drivers/staging/mrst-touchscreen/intel-mid-touch.c b/drivers/staging/mrst-touchscreen/intel-mid-touch.c
new file mode 100644
index 000000000000..1db00975a594
--- /dev/null
+++ b/drivers/staging/mrst-touchscreen/intel-mid-touch.c
@@ -0,0 +1,864 @@
1/*
2 * intel_mid_touch.c - Intel MID Resistive Touch Screen Driver
3 *
4 * Copyright (C) 2008 Intel Corp
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 of the License.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; ifnot, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 *
21 * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com)
22 * Ramesh Agarwal (ramesh.agarwal@intel.com)
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 *
25 * TODO:
26 * kill off mrstouch_debug eventually
27 * review conversion of r/m/w sequences
28 * Replace interrupt mutex abuse
29 * Kill of mrstouchdevp pointer
30 *
31 */
32
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/input.h>
36#include <linux/interrupt.h>
37#include <linux/err.h>
38#include <linux/param.h>
39#include <linux/spi/spi.h>
40#include <linux/irq.h>
41#include <linux/delay.h>
42#include <linux/kthread.h>
43#include <asm/intel_scu_ipc.h>
44
45
46#if defined(MRSTOUCH_DEBUG)
47#define mrstouch_debug(fmt, args...)\
48 do { \
49 printk(KERN_DEBUG "\n[MRSTOUCH(%d)] - ", __LINE__); \
50 printk(KERN_DEBUG fmt, ##args); \
51 } while (0);
52#else
53#define mrstouch_debug(fmt, args...)
54#endif
55
56/* PMIC Interrupt registers */
57#define PMIC_REG_ID1 0x00 /*PMIC ID1 register */
58
59/* PMIC Interrupt registers */
60#define PMIC_REG_INT 0x04 /*PMIC interrupt register */
61#define PMIC_REG_MINT 0x05 /*PMIC interrupt mask register */
62
63/* ADC Interrupt registers */
64#define PMIC_REG_ADCINT 0x5F /*ADC interrupt register */
65#define PMIC_REG_MADCINT 0x60 /*ADC interrupt mask register */
66
67/* ADC Control registers */
68#define PMIC_REG_ADCCNTL1 0x61 /*ADC control register */
69
70/* ADC Channel Selection registers */
71#define PMICADDR0 0xA4
72#define END_OF_CHANNEL 0x1F
73
74/* ADC Result register */
75#define PMIC_REG_ADCSNS0H 0x64
76
77/* ADC channels for touch screen */
78#define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */
79#define MRST_TS_CHAN11 0xB /* Touch screen X- connection */
80#define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */
81#define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */
82
83/* Touch screen coordinate constants */
84#define TOUCH_PRESSURE 50
85#define TOUCH_PRESSURE_FS 100
86
87#define XMOVE_LIMIT 5
88#define YMOVE_LIMIT 5
89#define XYMOVE_CNT 3
90
91#define MAX_10BIT ((1<<10)-1)
92
93/* Touch screen channel BIAS constants */
94#define XBIAS 0x20
95#define YBIAS 0x40
96#define ZBIAS 0x80
97
98/* Touch screen coordinates */
99#define MIN_X 10
100#define MAX_X 1024
101#define MIN_Y 10
102#define MAX_Y 1024
103#define WAIT_ADC_COMPLETION 10
104
105/* PMIC ADC round robin delays */
106#define ADC_LOOP_DELAY0 0x0 /* Continuous loop */
107#define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */
108
109/* PMIC Vendor Identifiers */
110#define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */
111#define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */
112#define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */
113#define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */
114
115/* Touch screen device structure */
116struct mrstouch_dev {
117 struct spi_device *spi; /* SPI device associated with touch screen */
118 struct input_dev *input; /* input device for touchscreen*/
119 char phys[32]; /* Device name */
120 struct task_struct *pendet_thrd; /* PENDET interrupt handler */
121 struct mutex lock; /* Sync between interrupt and PENDET handler */
122 bool busy; /* Busy flag */
123 u16 asr; /* Address selection register */
124 int irq; /* Touch screen IRQ # */
125 uint vendor; /* PMIC vendor */
126 uint rev; /* PMIC revision */
127 bool suspended; /* Device suspended status */
128 bool disabled; /* Device disabled status */
129 u16 x; /* X coordinate */
130 u16 y; /* Y coordinate */
131 bool pendown; /* PEN position */
132} ;
133
134
135/* Global Pointer to Touch screen device */
136static struct mrstouch_dev *mrstouchdevp;
137
138/* Utility to read PMIC ID */
139static int mrstouch_pmic_id(uint *vendor, uint *rev)
140{
141 int err;
142 u8 r;
143
144 err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r);
145 if (err)
146 return err;
147
148 *vendor = r & 0x7;
149 *rev = (r >> 3) & 0x7;
150
151 return 0;
152}
153
154/*
155 * Parse ADC channels to find end of the channel configured by other ADC user
156 * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels
157 */
158static int mrstouch_chan_parse(struct mrstouch_dev *tsdev)
159{
160 int err, i, j, found;
161 u32 r32;
162
163 found = -1;
164
165 for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) {
166 if (found >= 0)
167 break;
168
169 err = intel_scu_ipc_ioread32(PMICADDR0, &r32);
170 if (err)
171 return err;
172
173 for (j = 0; j < 32; j+= 8) {
174 if (((r32 >> j) & 0xFF) == END_OF_CHANNEL) {
175 found = i;
176 break;
177 }
178 }
179 }
180 if (found < 0)
181 return 0;
182
183 if (tsdev->vendor == PMIC_VENDOR_FS) {
184 if (found && found > (MRSTOUCH_MAX_CHANNELS - 18))
185 return -ENOSPC;
186 } else {
187 if (found && found > (MRSTOUCH_MAX_CHANNELS - 4))
188 return -ENOSPC;
189 }
190 return found;
191}
192
193/* Utility to enable/disable pendet.
194 * pendet set to true enables PENDET interrupt
195 * pendet set to false disables PENDET interrupt
196 * Also clears RND mask bit
197*/
198static int pendet_enable(struct mrstouch_dev *tsdev, bool pendet)
199{
200 u16 reg;
201 u8 r;
202 u8 pendet_enabled = 0;
203 int retry = 0;
204 int err;
205
206 err = intel_scu_ipc_ioread16(PMIC_REG_MADCINT, &reg);
207 if (err)
208 return err;
209
210 if (pendet) {
211 reg &= ~0x0005;
212 reg |= 0x2000; /* Enable pendet */
213 } else
214 reg &= 0xDFFF; /* Disable pendet */
215
216 /* Set MADCINT and update ADCCNTL1 (next reg byte) */
217 err = intel_scu_ipc_iowrite16(PMIC_REG_MADCINT, reg);
218 if (!pendet || err)
219 return err;
220
221 /*
222 * Sometimes even after the register write succeeds
223 * the PMIC register value is not updated. Retry few iterations
224 * to enable pendet.
225 */
226
227 err = intel_scu_ipc_ioread8(PMIC_REG_ADCCNTL1, &r);
228 pendet_enabled = (r >> 5) & 0x01;
229
230 retry = 0;
231 while (!err && !pendet_enabled) {
232 retry++;
233 msleep(10);
234 err = intel_scu_ipc_iowrite8(PMIC_REG_ADCCNTL1, reg >> 8);
235 if (err)
236 break;
237 err = intel_scu_ipc_ioread8(PMIC_REG_ADCCNTL1, &r);
238 if (err == 0)
239 pendet_enabled = (r >> 5) & 0x01;
240 if (retry >= 10) {
241 dev_err(&tsdev->spi->dev, "Touch screen disabled.\n");
242 return -EIO;
243 }
244 }
245 return 0;
246}
247
248/* To read PMIC ADC touch screen result
249 * Reads ADC storage registers for higher 7 and lower 3 bits
250 * converts the two readings to single value and turns off gain bit
251 */
252static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm)
253{
254 int err;
255 u16 result;
256 u32 res;
257
258 result = PMIC_REG_ADCSNS0H + offset;
259
260 if (chan == MRST_TS_CHAN12)
261 result += 4;
262
263 err = intel_scu_ipc_ioread32(result, &res);
264 if (err)
265 return err;
266
267 /* Mash the bits up */
268
269 *vp = (res & 0xFF) << 3; /* Highest 7 bits */
270 *vp |= (res >> 8) & 0x07; /* Lower 3 bits */
271 *vp &= 0x3FF;
272
273 res >>= 16;
274
275 *vm = (res & 0xFF) << 3; /* Highest 7 bits */
276 *vm |= (res >> 8) & 0x07; /* Lower 3 bits */
277 *vm &= 0x3FF;
278
279 return 0;
280}
281
282/* To configure touch screen channels
283 * Writes touch screen channels to ADC address selection registers
284 */
285static int mrstouch_ts_chan_set(uint offset)
286{
287 int count;
288 u16 chan;
289 u16 reg[5];
290 u8 data[5];
291
292 chan = PMICADDR0 + offset;
293 for (count = 0; count <= 3; count++) {
294 reg[count] = chan++;
295 data[count] = MRST_TS_CHAN10 + count;
296 }
297 reg[count] = chan;
298 data[count] = END_OF_CHANNEL;
299
300 return intel_scu_ipc_writev(reg, data, 5);
301}
302
303/* Initialize ADC */
304static int mrstouch_adc_init(struct mrstouch_dev *tsdev)
305{
306 int err, start;
307 u8 ra, rm;
308
309 err = mrstouch_pmic_id(&tsdev->vendor, &tsdev->rev);
310 if (err) {
311 dev_err(&tsdev->spi->dev, "Unable to read PMIC id\n");
312 return err;
313 }
314
315 start = mrstouch_chan_parse(tsdev);
316 if (start < 0) {
317 dev_err(&tsdev->spi->dev, "Unable to parse channels\n");
318 return start;
319 }
320
321 tsdev->asr = start;
322
323 mrstouch_debug("Channel offset(%d): 0x%X\n", tsdev->asr, tsdev->vendor);
324
325 /* ADC power on, start, enable PENDET and set loop delay
326 * ADC loop delay is set to 4.5 ms approximately
327 * Loop delay more than this results in jitter in adc readings
328 * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET
329 * interrupt generation sometimes.
330 */
331
332 if (tsdev->vendor == PMIC_VENDOR_FS) {
333 ra = 0xE0 | ADC_LOOP_DELAY0;
334 rm = 0x5;
335 } else {
336 /* NEC and MAXIm not consistent with loop delay 0 */
337 ra = 0xE0 | ADC_LOOP_DELAY1;
338 rm = 0x0;
339
340 /* configure touch screen channels */
341 err = mrstouch_ts_chan_set(tsdev->asr);
342 if (err)
343 return err;
344 }
345 err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7);
346 if (err == 0)
347 err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03);
348 return err;
349}
350
351/* Reports x,y coordinates to event subsystem */
352static void mrstouch_report_xy(struct mrstouch_dev *tsdev, u16 x, u16 y, u16 z)
353{
354 int xdiff, ydiff;
355
356 if (tsdev->pendown && z <= TOUCH_PRESSURE) {
357 /* Pen removed, report button release */
358 mrstouch_debug("BTN REL(%d)", z);
359 input_report_key(tsdev->input, BTN_TOUCH, 0);
360 tsdev->pendown = false;
361 }
362
363 xdiff = abs(x - tsdev->x);
364 ydiff = abs(y - tsdev->y);
365
366 /*
367 if x and y values changes for XYMOVE_CNT readings it is considered
368 as stylus is moving. This is required to differentiate between stylus
369 movement and jitter
370 */
371 if (x < MIN_X || x > MAX_X || y < MIN_Y || y > MAX_Y) {
372 /* Spurious values, release button if touched and return */
373 if (tsdev->pendown) {
374 mrstouch_debug("BTN REL(%d)", z);
375 input_report_key(tsdev->input, BTN_TOUCH, 0);
376 tsdev->pendown = false;
377 }
378 return;
379 } else if (xdiff >= XMOVE_LIMIT || ydiff >= YMOVE_LIMIT) {
380 tsdev->x = x;
381 tsdev->y = y;
382
383 input_report_abs(tsdev->input, ABS_X, x);
384 input_report_abs(tsdev->input, ABS_Y, y);
385 input_sync(tsdev->input);
386 }
387
388
389 if (!tsdev->pendown && z > TOUCH_PRESSURE) {
390 /* Pen touched, report button touch */
391 mrstouch_debug("BTN TCH(%d, %d, %d)", x, y, z);
392 input_report_key(tsdev->input, BTN_TOUCH, 1);
393 tsdev->pendown = true;
394 }
395}
396
397
398/* Utility to start ADC, used by freescale handler */
399static int pendet_mask(void)
400{
401 return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02);
402}
403
404/* Utility to stop ADC, used by freescale handler */
405static int pendet_umask(void)
406{
407 return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02);
408}
409
410/* Utility to read ADC, used by freescale handler */
411static int mrstouch_pmic_fs_adc_read(struct mrstouch_dev *tsdev)
412{
413 int err;
414 u16 x, y, z, result;
415 u16 reg[4];
416 u8 data[4];
417
418 result = PMIC_REG_ADCSNS0H + tsdev->asr;
419
420 reg[0] = result + 4;
421 reg[1] = result + 5;
422 reg[2] = result + 16;
423 reg[3] = result + 17;
424
425 err = intel_scu_ipc_readv(reg, data, 4);
426 if (err)
427 goto ipc_error;
428
429 x = data[0] << 3; /* Higher 7 bits */
430 x |= data[1] & 0x7; /* Lower 3 bits */
431 x &= 0x3FF;
432
433 y = data[2] << 3; /* Higher 7 bits */
434 y |= data[3] & 0x7; /* Lower 3 bits */
435 y &= 0x3FF;
436
437 /* Read Z value */
438 reg[0] = result + 28;
439 reg[1] = result + 29;
440
441 err = intel_scu_ipc_readv(reg, data, 4);
442 if (err)
443 goto ipc_error;
444
445 z = data[0] << 3; /* Higher 7 bits */
446 z |= data[1] & 0x7; /* Lower 3 bits */
447 z &= 0x3FF;
448
449#if defined(MRSTOUCH_PRINT_XYZP)
450 mrstouch_debug("X: %d, Y: %d, Z: %d", x, y, z);
451#endif
452
453 if (z >= TOUCH_PRESSURE_FS) {
454 mrstouch_report_xy(tsdev, x, y, TOUCH_PRESSURE - 1); /* Pen Removed */
455 return TOUCH_PRESSURE - 1;
456 } else {
457 mrstouch_report_xy(tsdev, x, y, TOUCH_PRESSURE + 1); /* Pen Touched */
458 return TOUCH_PRESSURE + 1;
459 }
460
461 return 0;
462
463ipc_error:
464 dev_err(&tsdev->spi->dev, "ipc error during fs_adc read\n");
465 return err;
466}
467
468/* To handle free scale pmic pendet interrupt */
469static int pmic0_pendet(void *dev_id)
470{
471 int err, count;
472 u16 chan;
473 unsigned int touched;
474 struct mrstouch_dev *tsdev = (struct mrstouch_dev *)dev_id;
475 u16 reg[5];
476 u8 data[5];
477
478 chan = PMICADDR0 + tsdev->asr;
479
480 /* Set X BIAS */
481 for (count = 0; count <= 3; count++) {
482 reg[count] = chan++;
483 data[count] = 0x2A;
484 }
485 reg[count] = chan++; /* Dummy */
486 data[count] = 0;
487
488 err = intel_scu_ipc_writev(reg, data, 5);
489 if (err)
490 goto ipc_error;
491
492 msleep(WAIT_ADC_COMPLETION);
493
494 /* Set Y BIAS */
495 for (count = 0; count <= 3; count++) {
496 reg[count] = chan++;
497 data[count] = 0x4A;
498 }
499 reg[count] = chan++; /* Dummy */
500 data[count] = 0;
501
502 err = intel_scu_ipc_writev(reg, data, 5);
503 if (err)
504 goto ipc_error;
505
506 msleep(WAIT_ADC_COMPLETION);
507
508 /* Set Z BIAS */
509 err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A);
510 if (err)
511 goto ipc_error;
512
513 msleep(WAIT_ADC_COMPLETION);
514
515 /*Read touch screen channels till pen removed
516 * Freescale reports constant value of z for all points
517 * z is high when screen is not touched and low when touched
518 * Map high z value to not touched and low z value to pen touched
519 */
520 touched = mrstouch_pmic_fs_adc_read(tsdev);
521 while (touched > TOUCH_PRESSURE) {
522 touched = mrstouch_pmic_fs_adc_read(tsdev);
523 msleep(WAIT_ADC_COMPLETION);
524 }
525
526 /* Clear all TS channels */
527 chan = PMICADDR0 + tsdev->asr;
528 for (count = 0; count <= 4; count++) {
529 reg[count] = chan++;
530 data[count] = 0;
531 }
532 err = intel_scu_ipc_writev(reg, data, 5);
533 if (err)
534 goto ipc_error;
535
536 for (count = 0; count <= 4; count++) {
537 reg[count] = chan++;
538 data[count] = 0;
539 }
540 err = intel_scu_ipc_writev(reg, data, 5);
541 if (err)
542 goto ipc_error;
543
544 err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000);
545 if (err)
546 goto ipc_error;
547
548 return 0;
549
550ipc_error:
551 dev_err(&tsdev->spi->dev, "ipc error during pendet\n");
552 return err;
553}
554
555
556/* To enable X, Y and Z bias values
557 * Enables YPYM for X channels and XPXM for Y channels
558 */
559static int mrstouch_ts_bias_set(uint offset, uint bias)
560{
561 int count;
562 u16 chan, start;
563 u16 reg[4];
564 u8 data[4];
565
566 chan = PMICADDR0 + offset;
567 start = MRST_TS_CHAN10;
568
569 for (count = 0; count <= 3; count++) {
570 reg[count] = chan++;
571 data[count] = bias | (start + count);
572 }
573 return intel_scu_ipc_writev(reg, data, 4);
574}
575
576/* To read touch screen channel values */
577static int mrstouch_adc_read(struct mrstouch_dev *tsdev)
578{
579 int err;
580 u16 xp, xm, yp, ym, zp, zm;
581
582 /* configure Y bias for X channels */
583 err = mrstouch_ts_bias_set(tsdev->asr, YBIAS);
584 if (err)
585 goto ipc_error;
586
587 msleep(WAIT_ADC_COMPLETION);
588
589 /* read x+ and x- channels */
590 err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, &xp, &xm);
591 if (err)
592 goto ipc_error;
593
594 /* configure x bias for y channels */
595 err = mrstouch_ts_bias_set(tsdev->asr, XBIAS);
596 if (err)
597 goto ipc_error;
598
599 msleep(WAIT_ADC_COMPLETION);
600
601 /* read y+ and y- channels */
602 err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, &yp, &ym);
603 if (err)
604 goto ipc_error;
605
606 /* configure z bias for x and y channels */
607 err = mrstouch_ts_bias_set(tsdev->asr, ZBIAS);
608 if (err)
609 goto ipc_error;
610
611 msleep(WAIT_ADC_COMPLETION);
612
613 /* read z+ and z- channels */
614 err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, &zp, &zm);
615 if (err)
616 goto ipc_error;
617
618#if defined(MRSTOUCH_PRINT_XYZP)
619 printk(KERN_INFO "X+: %d, Y+: %d, Z+: %d\n", xp, yp, zp);
620#endif
621
622#if defined(MRSTOUCH_PRINT_XYZM)
623 printk(KERN_INFO "X-: %d, Y-: %d, Z-: %d\n", xm, ym, zm);
624#endif
625
626 mrstouch_report_xy(tsdev, xp, yp, zp); /* report x and y to eventX */
627
628 return zp;
629
630ipc_error:
631 dev_err(&tsdev->spi->dev, "ipc error during adc read\n");
632 return err;
633}
634
635/* PENDET interrupt handler function for NEC and MAXIM */
636static void pmic12_pendet(void *data)
637{
638 unsigned int touched;
639 struct mrstouch_dev *tsdev = (struct mrstouch_dev *)data;
640
641 /* read touch screen channels till pen removed */
642 do {
643 touched = mrstouch_adc_read(tsdev);
644 } while (touched > TOUCH_PRESSURE);
645}
646
647/* Handler to process PENDET interrupt */
648int mrstouch_pendet(void *data)
649{
650 struct mrstouch_dev *tsdev = (struct mrstouch_dev *)data;
651 while (1) {
652 /* Wait for PENDET interrupt */
653 if (mutex_lock_interruptible(&tsdev->lock)) {
654 msleep(WAIT_ADC_COMPLETION);
655 continue;
656 }
657
658 if (tsdev->busy)
659 return 0;
660
661 tsdev->busy = true;
662
663 if (tsdev->vendor == PMIC_VENDOR_NEC ||
664 tsdev->vendor == PMIC_VENDOR_MAXIM) {
665 /* PENDET must be disabled in NEC before reading ADC */
666 pendet_enable(tsdev,false); /* Disbale PENDET */
667 pmic12_pendet(tsdev);
668 pendet_enable(tsdev, true); /*Enable PENDET */
669 } else if (tsdev->vendor == PMIC_VENDOR_FS) {
670 pendet_umask(); /* Stop ADC */
671 pmic0_pendet(tsdev);
672 pendet_mask(); /* Stop ADC */
673 } else
674 dev_err(&tsdev->spi->dev, "Unsupported touchscreen: %d\n",
675 tsdev->vendor);
676
677 tsdev->busy = false;
678
679 }
680 return 0;
681}
682
683/* PENDET interrupt handler */
684static irqreturn_t pendet_intr_handler(int irq, void *handle)
685{
686 struct mrstouch_dev *tsdev = (struct mrstouch_dev *)handle;
687
688 mutex_unlock(&tsdev->lock);
689 return IRQ_HANDLED;
690}
691
692/* Intializes input device and registers with input subsystem */
693static int ts_input_dev_init(struct mrstouch_dev *tsdev, struct spi_device *spi)
694{
695 int err = 0;
696
697 mrstouch_debug("%s", __func__);
698
699 tsdev->input = input_allocate_device();
700 if (!tsdev->input) {
701 dev_err(&tsdev->spi->dev, "Unable to allocate input device.\n");
702 return -EINVAL;
703 }
704
705 tsdev->input->name = "mrst_touchscreen";
706 snprintf(tsdev->phys, sizeof(tsdev->phys),
707 "%s/input0", dev_name(&spi->dev));
708 tsdev->input->phys = tsdev->phys;
709 tsdev->input->dev.parent = &spi->dev;
710
711 tsdev->input->id.vendor = tsdev->vendor;
712 tsdev->input->id.version = tsdev->rev;
713
714 tsdev->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
715 tsdev->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
716
717 input_set_abs_params(tsdev->input, ABS_X, MIN_X, MIN_Y, 0, 0);
718 input_set_abs_params(tsdev->input, ABS_Y, MIN_X, MIN_Y, 0, 0);
719
720 err = input_register_device(tsdev->input);
721 if (err) {
722 dev_err(&tsdev->spi->dev, "unable to register input device\n");
723 input_free_device(tsdev->input);
724 return err;
725 }
726
727 mrstouch_debug("%s", "mrstouch initialized");
728
729 return 0;
730
731}
732
733/* Probe function for touch screen driver */
734static int __devinit mrstouch_probe(struct spi_device *mrstouch_spi)
735{
736 int err;
737 unsigned int myirq;
738 struct mrstouch_dev *tsdev;
739
740 mrstouch_debug("%s(%p)", __func__, mrstouch_spi);
741
742 mrstouchdevp = NULL;
743 myirq = mrstouch_spi->irq;
744
745 if (!mrstouch_spi->irq) {
746 dev_err(&mrstouch_spi->dev, "no interrupt assigned\n");
747 return -EINVAL;
748 }
749
750 tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL);
751 if (!tsdev) {
752 dev_err(&mrstouch_spi->dev, "unable to allocate memory\n");
753 return -ENOMEM;
754 }
755
756 tsdev->irq = myirq;
757 mrstouchdevp = tsdev;
758
759 err = mrstouch_adc_init(tsdev);
760 if (err) {
761 dev_err(&mrstouch_spi->dev, "ADC init failed\n");
762 goto mrstouch_err_free_mem;
763 }
764
765 dev_set_drvdata(&mrstouch_spi->dev, tsdev);
766 tsdev->spi = mrstouch_spi;
767
768 err = ts_input_dev_init(tsdev, mrstouch_spi);
769 if (err) {
770 dev_err(&tsdev->spi->dev, "ts_input_dev_init failed");
771 goto mrstouch_err_free_mem;
772 }
773
774 mutex_init(&tsdev->lock);
775 mutex_lock(&tsdev->lock)
776
777 mrstouch_debug("Requesting IRQ-%d", myirq);
778 err = request_irq(myirq, pendet_intr_handler,
779 0, "mrstouch", tsdev);
780 if (err) {
781 dev_err(&tsdev->spi->dev, "unable to allocate irq\n");
782 goto mrstouch_err_free_mem;
783 }
784
785 tsdev->pendet_thrd = kthread_run(mrstouch_pendet,
786 (void *)tsdev, "pendet handler");
787 if (IS_ERR(tsdev->pendet_thrd)) {
788 dev_err(&tsdev->spi->dev, "kthread_run failed\n");
789 err = PTR_ERR(tsdev->pendet_thrd);
790 goto mrstouch_err_free_mem;
791 }
792 mrstouch_debug("%s", "Driver initialized");
793 return 0;
794
795mrstouch_err_free_mem:
796 kfree(tsdev);
797 return err;
798}
799
800static int mrstouch_suspend(struct spi_device *spi, pm_message_t msg)
801{
802 mrstouch_debug("%s", __func__);
803 mrstouchdevp->suspended = 1;
804 return 0;
805}
806
807static int mrstouch_resume(struct spi_device *spi)
808{
809 mrstouch_debug("%s", __func__);
810 mrstouchdevp->suspended = 0;
811 return 0;
812}
813
814static int mrstouch_remove(struct spi_device *spi)
815{
816 mrstouch_debug("%s", __func__);
817 free_irq(mrstouchdevp->irq, mrstouchdevp);
818 input_unregister_device(mrstouchdevp->input);
819 input_free_device(mrstouchdevp->input);
820 kfree(mrstouchdevp);
821 if (mrstouchdevp->pendet_thrd)
822 kthread_stop(mrstouchdevp->pendet_thrd);
823 return 0;
824}
825
826static struct spi_driver mrstouch_driver = {
827 .driver = {
828 .name = "pmic_touch",
829 .bus = &spi_bus_type,
830 .owner = THIS_MODULE,
831 },
832 .probe = mrstouch_probe,
833 .suspend = mrstouch_suspend,
834 .resume = mrstouch_resume,
835 .remove = mrstouch_remove,
836};
837
838static int __init mrstouch_module_init(void)
839{
840 int err;
841
842 mrstouch_debug("%s", __func__);
843 err = spi_register_driver(&mrstouch_driver);
844 if (err) {
845 mrstouch_debug("%s(%d)", "SPI PENDET failed", err);
846 return -1;
847 }
848
849 return 0;
850}
851
852static void __exit mrstouch_module_exit(void)
853{
854 mrstouch_debug("%s", __func__);
855 spi_unregister_driver(&mrstouch_driver);
856 return;
857}
858
859module_init(mrstouch_module_init);
860module_exit(mrstouch_module_exit);
861
862MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com");
863MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver");
864MODULE_LICENSE("GPL");
diff --git a/drivers/staging/msm/Kconfig b/drivers/staging/msm/Kconfig
new file mode 100644
index 000000000000..c57039f2060b
--- /dev/null
+++ b/drivers/staging/msm/Kconfig
@@ -0,0 +1,134 @@
1config MSM_STAGING
2 tristate "MSM Frame Buffer Support"
3 depends on FB && ARCH_MSM && !FB_MSM
4 select FB_BACKLIGHT if FB_MSM_BACKLIGHT
5 select NEW_LEDS
6 select LEDS_CLASS
7 select FB_CFB_FILLRECT
8 select FB_CFB_COPYAREA
9 select FB_CFB_IMAGEBLIT
10 ---help---
11 Support for MSM Framebuffer.
12
13if MSM_STAGING
14
15config FB_MSM_LCDC_HW
16 bool
17 default n
18
19choice
20 prompt "MDP HW version"
21 default FB_MSM_MDP31
22
23config FB_MSM_MDP31
24 select FB_MSM_LCDC_HW
25 bool "MDP HW ver3.1"
26 ---help---
27 Support for MSM MDP HW revision 3.1
28 Say Y here if this is msm8x50 variant platform.
29endchoice
30
31config FB_MSM_LCDC
32 bool
33 default n
34
35config FB_MSM_TVOUT
36 bool
37 default n
38
39config FB_MSM_LCDC_PANEL
40 bool
41 select FB_MSM_LCDC
42 default n
43
44config FB_MSM_LCDC_PRISM_WVGA
45 bool
46 select FB_MSM_LCDC_PANEL
47 default n
48
49config FB_MSM_LCDC_ST1_WXGA
50 bool
51 select FB_MSM_LCDC_PANEL
52 default n
53
54config FB_MSM_LCDC_ST15_WXGA
55 bool
56 select FB_MSM_LCDC_PANEL
57 default n
58
59config FB_MSM_LCDC_WXGA
60 bool
61 select FB_MSM_LCDC_PANEL
62 default n
63
64choice
65 prompt "LCD Panel"
66 default FB_MSM_LCDC_ST15_PANEL
67
68config FB_MSM_LCDC_PRISM_WVGA_PANEL
69 depends on FB_MSM_LCDC_HW
70 bool "LCDC Prism WVGA Panel"
71 select FB_MSM_LCDC_PRISM_WVGA
72 ---help---
73 Support for LCDC Prism WVGA (800x480) panel
74
75
76config FB_MSM_LCDC_ST15_PANEL
77 depends on FB_MSM_LCDC_HW
78 bool "LCDC ST1.5 Panel"
79 select FB_MSM_LCDC_ST15_WXGA
80 ---help---
81 Support for ST1.5 WXGA (1366x768) panel
82
83config FB_MSM_PANEL_NONE
84 bool "NONE"
85 ---help---
86 This will disable LCD panel
87endchoice
88
89choice
90 prompt "Secondary LCD Panel"
91 depends on FB_MSM_MDP31
92 default FB_MSM_SECONDARY_PANEL_NONE
93
94config FB_MSM_SECONDARY_PANEL_NONE
95 bool "NONE"
96 ---help---
97 No secondary panel
98endchoice
99
100config FB_MSM_TVOUT_NTSC
101 bool
102 select FB_MSM_TVOUT
103 default n
104
105config FB_MSM_TVOUT_PAL
106 bool
107 select FB_MSM_TVOUT
108 default n
109
110choice
111 depends on (FB_MSM_MDP22 || FB_MSM_MDP31)
112 prompt "TVOut Region"
113 default FB_MSM_TVOUT_NTSC_M
114
115config FB_MSM_TVOUT_NTSC_M
116 bool "NTSC M"
117 select FB_MSM_TVOUT_NTSC
118 ---help---
119 Support for NTSC M region (North American and Korea)
120
121config FB_MSM_TVOUT_NONE
122 bool "NONE"
123 ---help---
124 This will disable TV Out functionality.
125endchoice
126
127config PMEM_KERNEL_SIZE
128 int "PMEM for kernel components (in MB)"
129 default 2
130 depends on ARCH_QSD8X50
131 help
132 Configures the amount of PMEM for use by kernel components
133 (in MB; minimum 2MB)
134endif
diff --git a/drivers/staging/msm/Makefile b/drivers/staging/msm/Makefile
new file mode 100644
index 000000000000..98a0ce177cb2
--- /dev/null
+++ b/drivers/staging/msm/Makefile
@@ -0,0 +1,93 @@
1obj-y := msm_fb.o staging-devices.o memory.o
2
3obj-$(CONFIG_FB_MSM_LOGO) += logo.o
4obj-$(CONFIG_FB_BACKLIGHT) += msm_fb_bl.o
5
6# MDP
7obj-y += mdp.o
8
9ifeq ($(CONFIG_FB_MSM_MDP40),y)
10obj-y += mdp4_util.o
11obj-$(CONFIG_DEBUG_FS) += mdp4_debugfs.o
12else
13obj-y += mdp_hw_init.o
14obj-y += mdp_ppp.o
15ifeq ($(CONFIG_FB_MSM_MDP31),y)
16obj-y += mdp_ppp_v31.o
17obj-$(CONFIG_MDP_PPP_ASYNC_OP) += mdp_ppp_dq.o
18else
19obj-y += mdp_ppp_v20.o
20endif
21endif
22
23ifeq ($(CONFIG_FB_MSM_OVERLAY),y)
24obj-y += mdp4_overlay.o
25obj-y += mdp4_overlay_lcdc.o
26obj-y += mdp4_overlay_mddi.o
27else
28obj-y += mdp_dma_lcdc.o
29endif
30
31obj-y += mdp_dma.o
32obj-y += mdp_dma_s.o
33obj-y += mdp_vsync.o
34obj-y += mdp_cursor.o
35obj-y += mdp_dma_tv.o
36
37# EBI2
38obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o
39
40# LCDC
41obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o
42
43# MDDI
44msm_mddi-objs := mddi.o mddihost.o mddihosti.o
45obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o
46
47# External MDDI
48msm_mddi_ext-objs := mddihost_e.o mddi_ext.o
49obj-$(CONFIG_FB_MSM_EXTMDDI) += msm_mddi_ext.o
50
51# TVEnc
52obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o
53
54# MSM FB Panel
55obj-y += msm_fb_panel.o
56obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_tmd20.o
57obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_l2f.o
58
59ifeq ($(CONFIG_FB_MSM_MDDI_AUTO_DETECT),y)
60obj-y += mddi_prism.o
61obj-y += mddi_toshiba.o
62obj-y += mddi_toshiba_vga.o
63obj-y += mddi_toshiba_wvga_pt.o
64obj-y += mddi_toshiba_wvga.o
65obj-y += mddi_sharp.o
66else
67obj-$(CONFIG_FB_MSM_MDDI_PRISM_WVGA) += mddi_prism.o
68obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON) += mddi_toshiba.o
69obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON_VGA) += mddi_toshiba_vga.o
70obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA_PORTRAIT) += mddi_toshiba_wvga_pt.o
71obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA) += mddi_toshiba_wvga.o
72obj-$(CONFIG_FB_MSM_MDDI_SHARP_QVGA_128x128) += mddi_sharp.o
73endif
74
75obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
76obj-$(CONFIG_FB_MSM_LCDC_PRISM_WVGA) += lcdc_prism.o
77obj-$(CONFIG_FB_MSM_LCDC_EXTERNAL_WXGA) += lcdc_external.o
78obj-$(CONFIG_FB_MSM_LCDC_GORDON_VGA) += lcdc_gordon.o
79obj-$(CONFIG_FB_MSM_LCDC_WXGA) += lcdc_wxga.o
80obj-$(CONFIG_FB_MSM_LCDC_TOSHIBA_WVGA_PT) += lcdc_toshiba_wvga_pt.o
81obj-$(CONFIG_FB_MSM_LCDC_SHARP_WVGA_PT) += lcdc_sharp_wvga_pt.o
82obj-$(CONFIG_FB_MSM_LCDC_GRAPEFRUIT_VGA) += lcdc_grapefruit.o
83obj-$(CONFIG_FB_MSM_LCDC_ST1_WXGA) += lcdc_st1_wxga.o
84obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o
85obj-$(CONFIG_FB_MSM_HDMI_SII_EXTERNAL_720P) += hdmi_sii9022.o
86
87obj-$(CONFIG_FB_MSM_TVOUT_NTSC) += tv_ntsc.o
88obj-$(CONFIG_FB_MSM_TVOUT_PAL) += tv_pal.o
89
90obj-$(CONFIG_FB_MSM_EXTMDDI_SVGA) += mddi_ext_lcd.o
91
92clean:
93 rm *.o .*cmd
diff --git a/drivers/staging/msm/TODO b/drivers/staging/msm/TODO
new file mode 100644
index 000000000000..05107a7d516a
--- /dev/null
+++ b/drivers/staging/msm/TODO
@@ -0,0 +1,3 @@
1- Merge this code with the existing MSM framebuffer
2- General style clean ups.
3
diff --git a/drivers/staging/msm/ebi2_l2f.c b/drivers/staging/msm/ebi2_l2f.c
new file mode 100644
index 000000000000..eea891d8f0f8
--- /dev/null
+++ b/drivers/staging/msm/ebi2_l2f.c
@@ -0,0 +1,569 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19
20#include <linux/memory.h>
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/time.h>
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include "linux/proc_fs.h"
27
28#include <linux/delay.h>
29
30#include <mach/hardware.h>
31#include <linux/io.h>
32
33#include <asm/system.h>
34#include <asm/mach-types.h>
35
36/* The following are for MSM5100 on Gator
37*/
38#ifdef FEATURE_PM1000
39#include "pm1000.h"
40#endif /* FEATURE_PM1000 */
41/* The following are for MSM6050 on Bambi
42*/
43#ifdef FEATURE_PMIC_LCDKBD_LED_DRIVER
44#include "pm.h"
45#endif /* FEATURE_PMIC_LCDKBD_LED_DRIVER */
46
47#ifdef DISP_DEVICE_18BPP
48#undef DISP_DEVICE_18BPP
49#define DISP_DEVICE_16BPP
50#endif
51
52#define QCIF_WIDTH 176
53#define QCIF_HEIGHT 220
54
55static void *DISP_CMD_PORT;
56static void *DISP_DATA_PORT;
57
58#define DISP_CMD_DISON 0xaf
59#define DISP_CMD_DISOFF 0xae
60#define DISP_CMD_DISNOR 0xa6
61#define DISP_CMD_DISINV 0xa7
62#define DISP_CMD_DISCTL 0xca
63#define DISP_CMD_GCP64 0xcb
64#define DISP_CMD_GCP16 0xcc
65#define DISP_CMD_GSSET 0xcd
66#define DISP_GS_2 0x02
67#define DISP_GS_16 0x01
68#define DISP_GS_64 0x00
69#define DISP_CMD_SLPIN 0x95
70#define DISP_CMD_SLPOUT 0x94
71#define DISP_CMD_SD_PSET 0x75
72#define DISP_CMD_MD_PSET 0x76
73#define DISP_CMD_SD_CSET 0x15
74#define DISP_CMD_MD_CSET 0x16
75#define DISP_CMD_DATCTL 0xbc
76#define DISP_DATCTL_666 0x08
77#define DISP_DATCTL_565 0x28
78#define DISP_DATCTL_444 0x38
79#define DISP_CMD_RAMWR 0x5c
80#define DISP_CMD_RAMRD 0x5d
81#define DISP_CMD_PTLIN 0xa8
82#define DISP_CMD_PTLOUT 0xa9
83#define DISP_CMD_ASCSET 0xaa
84#define DISP_CMD_SCSTART 0xab
85#define DISP_CMD_VOLCTL 0xc6
86#define DISP_VOLCTL_TONE 0x80
87#define DISP_CMD_NOp 0x25
88#define DISP_CMD_OSSEL 0xd0
89#define DISP_CMD_3500KSET 0xd1
90#define DISP_CMD_3500KEND 0xd2
91#define DISP_CMD_14MSET 0xd3
92#define DISP_CMD_14MEND 0xd4
93
94#define DISP_CMD_OUT(cmd) outpw(DISP_CMD_PORT, cmd);
95
96#define DISP_DATA_OUT(data) outpw(DISP_DATA_PORT, data);
97
98#define DISP_DATA_IN() inpw(DISP_DATA_PORT);
99
100/* Epson device column number starts at 2
101*/
102#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \
103 DISP_CMD_OUT(DISP_CMD_SD_PSET) \
104 DISP_DATA_OUT((ulhc_row) & 0xFF) \
105 DISP_DATA_OUT((ulhc_row) >> 8) \
106 DISP_DATA_OUT((lrhc_row) & 0xFF) \
107 DISP_DATA_OUT((lrhc_row) >> 8) \
108 DISP_CMD_OUT(DISP_CMD_SD_CSET) \
109 DISP_DATA_OUT(((ulhc_col)+2) & 0xFF) \
110 DISP_DATA_OUT(((ulhc_col)+2) >> 8) \
111 DISP_DATA_OUT(((lrhc_col)+2) & 0xFF) \
112 DISP_DATA_OUT(((lrhc_col)+2) >> 8)
113
114#define DISP_MIN_CONTRAST 0
115#define DISP_MAX_CONTRAST 127
116#define DISP_DEFAULT_CONTRAST 80
117
118#define DISP_MIN_BACKLIGHT 0
119#define DISP_MAX_BACKLIGHT 15
120#define DISP_DEFAULT_BACKLIGHT 2
121
122#define WAIT_SEC(sec) mdelay((sec)/1000)
123
124static word disp_area_start_row;
125static word disp_area_end_row;
126static byte disp_contrast = DISP_DEFAULT_CONTRAST;
127static boolean disp_powered_up;
128static boolean disp_initialized = FALSE;
129/* For some reason the contrast set at init time is not good. Need to do
130 * it again
131 */
132static boolean display_on = FALSE;
133static void epsonQcif_disp_init(struct platform_device *pdev);
134static void epsonQcif_disp_set_contrast(word contrast);
135static void epsonQcif_disp_set_display_area(word start_row, word end_row);
136static int epsonQcif_disp_off(struct platform_device *pdev);
137static int epsonQcif_disp_on(struct platform_device *pdev);
138static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres);
139
140volatile word databack;
141static void epsonQcif_disp_init(struct platform_device *pdev)
142{
143 struct msm_fb_data_type *mfd;
144
145 int i;
146
147 if (disp_initialized)
148 return;
149
150 mfd = platform_get_drvdata(pdev);
151
152 DISP_CMD_PORT = mfd->cmd_port;
153 DISP_DATA_PORT = mfd->data_port;
154
155 /* Sleep in */
156 DISP_CMD_OUT(DISP_CMD_SLPIN);
157
158 /* Display off */
159 DISP_CMD_OUT(DISP_CMD_DISOFF);
160
161 /* Display normal */
162 DISP_CMD_OUT(DISP_CMD_DISNOR);
163
164 /* Set data mode */
165 DISP_CMD_OUT(DISP_CMD_DATCTL);
166 DISP_DATA_OUT(DISP_DATCTL_565);
167
168 /* Set display timing */
169 DISP_CMD_OUT(DISP_CMD_DISCTL);
170 DISP_DATA_OUT(0x1c); /* p1 */
171 DISP_DATA_OUT(0x02); /* p1 */
172 DISP_DATA_OUT(0x82); /* p2 */
173 DISP_DATA_OUT(0x00); /* p3 */
174 DISP_DATA_OUT(0x00); /* p4 */
175 DISP_DATA_OUT(0xe0); /* p5 */
176 DISP_DATA_OUT(0x00); /* p5 */
177 DISP_DATA_OUT(0xdc); /* p6 */
178 DISP_DATA_OUT(0x00); /* p6 */
179 DISP_DATA_OUT(0x02); /* p7 */
180 DISP_DATA_OUT(0x00); /* p8 */
181
182 /* Set 64 gray scale level */
183 DISP_CMD_OUT(DISP_CMD_GCP64);
184 DISP_DATA_OUT(0x08); /* p01 */
185 DISP_DATA_OUT(0x00);
186 DISP_DATA_OUT(0x2a); /* p02 */
187 DISP_DATA_OUT(0x00);
188 DISP_DATA_OUT(0x4e); /* p03 */
189 DISP_DATA_OUT(0x00);
190 DISP_DATA_OUT(0x6b); /* p04 */
191 DISP_DATA_OUT(0x00);
192 DISP_DATA_OUT(0x88); /* p05 */
193 DISP_DATA_OUT(0x00);
194 DISP_DATA_OUT(0xa3); /* p06 */
195 DISP_DATA_OUT(0x00);
196 DISP_DATA_OUT(0xba); /* p07 */
197 DISP_DATA_OUT(0x00);
198 DISP_DATA_OUT(0xd1); /* p08 */
199 DISP_DATA_OUT(0x00);
200 DISP_DATA_OUT(0xe5); /* p09 */
201 DISP_DATA_OUT(0x00);
202 DISP_DATA_OUT(0xf3); /* p10 */
203 DISP_DATA_OUT(0x00);
204 DISP_DATA_OUT(0x03); /* p11 */
205 DISP_DATA_OUT(0x01);
206 DISP_DATA_OUT(0x13); /* p12 */
207 DISP_DATA_OUT(0x01);
208 DISP_DATA_OUT(0x22); /* p13 */
209 DISP_DATA_OUT(0x01);
210 DISP_DATA_OUT(0x2f); /* p14 */
211 DISP_DATA_OUT(0x01);
212 DISP_DATA_OUT(0x3b); /* p15 */
213 DISP_DATA_OUT(0x01);
214 DISP_DATA_OUT(0x46); /* p16 */
215 DISP_DATA_OUT(0x01);
216 DISP_DATA_OUT(0x51); /* p17 */
217 DISP_DATA_OUT(0x01);
218 DISP_DATA_OUT(0x5b); /* p18 */
219 DISP_DATA_OUT(0x01);
220 DISP_DATA_OUT(0x64); /* p19 */
221 DISP_DATA_OUT(0x01);
222 DISP_DATA_OUT(0x6c); /* p20 */
223 DISP_DATA_OUT(0x01);
224 DISP_DATA_OUT(0x74); /* p21 */
225 DISP_DATA_OUT(0x01);
226 DISP_DATA_OUT(0x7c); /* p22 */
227 DISP_DATA_OUT(0x01);
228 DISP_DATA_OUT(0x83); /* p23 */
229 DISP_DATA_OUT(0x01);
230 DISP_DATA_OUT(0x8a); /* p24 */
231 DISP_DATA_OUT(0x01);
232 DISP_DATA_OUT(0x91); /* p25 */
233 DISP_DATA_OUT(0x01);
234 DISP_DATA_OUT(0x98); /* p26 */
235 DISP_DATA_OUT(0x01);
236 DISP_DATA_OUT(0x9f); /* p27 */
237 DISP_DATA_OUT(0x01);
238 DISP_DATA_OUT(0xa6); /* p28 */
239 DISP_DATA_OUT(0x01);
240 DISP_DATA_OUT(0xac); /* p29 */
241 DISP_DATA_OUT(0x01);
242 DISP_DATA_OUT(0xb2); /* p30 */
243 DISP_DATA_OUT(0x01);
244 DISP_DATA_OUT(0xb7); /* p31 */
245 DISP_DATA_OUT(0x01);
246 DISP_DATA_OUT(0xbc); /* p32 */
247 DISP_DATA_OUT(0x01);
248 DISP_DATA_OUT(0xc1); /* p33 */
249 DISP_DATA_OUT(0x01);
250 DISP_DATA_OUT(0xc6); /* p34 */
251 DISP_DATA_OUT(0x01);
252 DISP_DATA_OUT(0xcb); /* p35 */
253 DISP_DATA_OUT(0x01);
254 DISP_DATA_OUT(0xd0); /* p36 */
255 DISP_DATA_OUT(0x01);
256 DISP_DATA_OUT(0xd4); /* p37 */
257 DISP_DATA_OUT(0x01);
258 DISP_DATA_OUT(0xd8); /* p38 */
259 DISP_DATA_OUT(0x01);
260 DISP_DATA_OUT(0xdc); /* p39 */
261 DISP_DATA_OUT(0x01);
262 DISP_DATA_OUT(0xe0); /* p40 */
263 DISP_DATA_OUT(0x01);
264 DISP_DATA_OUT(0xe4); /* p41 */
265 DISP_DATA_OUT(0x01);
266 DISP_DATA_OUT(0xe8); /* p42 */
267 DISP_DATA_OUT(0x01);
268 DISP_DATA_OUT(0xec); /* p43 */
269 DISP_DATA_OUT(0x01);
270 DISP_DATA_OUT(0xf0); /* p44 */
271 DISP_DATA_OUT(0x01);
272 DISP_DATA_OUT(0xf4); /* p45 */
273 DISP_DATA_OUT(0x01);
274 DISP_DATA_OUT(0xf8); /* p46 */
275 DISP_DATA_OUT(0x01);
276 DISP_DATA_OUT(0xfb); /* p47 */
277 DISP_DATA_OUT(0x01);
278 DISP_DATA_OUT(0xfe); /* p48 */
279 DISP_DATA_OUT(0x01);
280 DISP_DATA_OUT(0x01); /* p49 */
281 DISP_DATA_OUT(0x02);
282 DISP_DATA_OUT(0x03); /* p50 */
283 DISP_DATA_OUT(0x02);
284 DISP_DATA_OUT(0x05); /* p51 */
285 DISP_DATA_OUT(0x02);
286 DISP_DATA_OUT(0x07); /* p52 */
287 DISP_DATA_OUT(0x02);
288 DISP_DATA_OUT(0x09); /* p53 */
289 DISP_DATA_OUT(0x02);
290 DISP_DATA_OUT(0x0b); /* p54 */
291 DISP_DATA_OUT(0x02);
292 DISP_DATA_OUT(0x0d); /* p55 */
293 DISP_DATA_OUT(0x02);
294 DISP_DATA_OUT(0x0f); /* p56 */
295 DISP_DATA_OUT(0x02);
296 DISP_DATA_OUT(0x11); /* p57 */
297 DISP_DATA_OUT(0x02);
298 DISP_DATA_OUT(0x13); /* p58 */
299 DISP_DATA_OUT(0x02);
300 DISP_DATA_OUT(0x15); /* p59 */
301 DISP_DATA_OUT(0x02);
302 DISP_DATA_OUT(0x17); /* p60 */
303 DISP_DATA_OUT(0x02);
304 DISP_DATA_OUT(0x19); /* p61 */
305 DISP_DATA_OUT(0x02);
306 DISP_DATA_OUT(0x1b); /* p62 */
307 DISP_DATA_OUT(0x02);
308 DISP_DATA_OUT(0x1c); /* p63 */
309 DISP_DATA_OUT(0x02);
310
311 /* Set 16 gray scale level */
312 DISP_CMD_OUT(DISP_CMD_GCP16);
313 DISP_DATA_OUT(0x1a); /* p01 */
314 DISP_DATA_OUT(0x32); /* p02 */
315 DISP_DATA_OUT(0x42); /* p03 */
316 DISP_DATA_OUT(0x4c); /* p04 */
317 DISP_DATA_OUT(0x58); /* p05 */
318 DISP_DATA_OUT(0x5f); /* p06 */
319 DISP_DATA_OUT(0x66); /* p07 */
320 DISP_DATA_OUT(0x6b); /* p08 */
321 DISP_DATA_OUT(0x70); /* p09 */
322 DISP_DATA_OUT(0x74); /* p10 */
323 DISP_DATA_OUT(0x78); /* p11 */
324 DISP_DATA_OUT(0x7b); /* p12 */
325 DISP_DATA_OUT(0x7e); /* p13 */
326 DISP_DATA_OUT(0x80); /* p14 */
327 DISP_DATA_OUT(0x82); /* p15 */
328
329 /* Set DSP column */
330 DISP_CMD_OUT(DISP_CMD_MD_CSET);
331 DISP_DATA_OUT(0xff);
332 DISP_DATA_OUT(0x03);
333 DISP_DATA_OUT(0xff);
334 DISP_DATA_OUT(0x03);
335
336 /* Set DSP page */
337 DISP_CMD_OUT(DISP_CMD_MD_PSET);
338 DISP_DATA_OUT(0xff);
339 DISP_DATA_OUT(0x01);
340 DISP_DATA_OUT(0xff);
341 DISP_DATA_OUT(0x01);
342
343 /* Set ARM column */
344 DISP_CMD_OUT(DISP_CMD_SD_CSET);
345 DISP_DATA_OUT(0x02);
346 DISP_DATA_OUT(0x00);
347 DISP_DATA_OUT((QCIF_WIDTH + 1) & 0xFF);
348 DISP_DATA_OUT((QCIF_WIDTH + 1) >> 8);
349
350 /* Set ARM page */
351 DISP_CMD_OUT(DISP_CMD_SD_PSET);
352 DISP_DATA_OUT(0x00);
353 DISP_DATA_OUT(0x00);
354 DISP_DATA_OUT((QCIF_HEIGHT - 1) & 0xFF);
355 DISP_DATA_OUT((QCIF_HEIGHT - 1) >> 8);
356
357 /* Set 64 gray scales */
358 DISP_CMD_OUT(DISP_CMD_GSSET);
359 DISP_DATA_OUT(DISP_GS_64);
360
361 DISP_CMD_OUT(DISP_CMD_OSSEL);
362 DISP_DATA_OUT(0);
363
364 /* Sleep out */
365 DISP_CMD_OUT(DISP_CMD_SLPOUT);
366
367 WAIT_SEC(40000);
368
369 /* Initialize power IC */
370 DISP_CMD_OUT(DISP_CMD_VOLCTL);
371 DISP_DATA_OUT(DISP_VOLCTL_TONE);
372
373 WAIT_SEC(40000);
374
375 /* Set electronic volume, d'xx */
376 DISP_CMD_OUT(DISP_CMD_VOLCTL);
377 DISP_DATA_OUT(DISP_DEFAULT_CONTRAST); /* value from 0 to 127 */
378
379 /* Initialize display data */
380 DISP_SET_RECT(0, (QCIF_HEIGHT - 1), 0, (QCIF_WIDTH - 1));
381 DISP_CMD_OUT(DISP_CMD_RAMWR);
382 for (i = 0; i < QCIF_HEIGHT * QCIF_WIDTH; i++)
383 DISP_DATA_OUT(0xffff);
384
385 DISP_CMD_OUT(DISP_CMD_RAMRD);
386 databack = DISP_DATA_IN();
387 databack = DISP_DATA_IN();
388 databack = DISP_DATA_IN();
389 databack = DISP_DATA_IN();
390
391 WAIT_SEC(80000);
392
393 DISP_CMD_OUT(DISP_CMD_DISON);
394
395 disp_area_start_row = 0;
396 disp_area_end_row = QCIF_HEIGHT - 1;
397 disp_powered_up = TRUE;
398 disp_initialized = TRUE;
399 epsonQcif_disp_set_display_area(0, QCIF_HEIGHT - 1);
400 display_on = TRUE;
401}
402
403static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres)
404{
405 if (!disp_initialized)
406 return;
407
408 DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1);
409 DISP_CMD_OUT(DISP_CMD_RAMWR);
410}
411
412static void epsonQcif_disp_set_display_area(word start_row, word end_row)
413{
414 if (!disp_initialized)
415 return;
416
417 if ((start_row == disp_area_start_row)
418 && (end_row == disp_area_end_row))
419 return;
420 disp_area_start_row = start_row;
421 disp_area_end_row = end_row;
422
423 /* Range checking
424 */
425 if (end_row >= QCIF_HEIGHT)
426 end_row = QCIF_HEIGHT - 1;
427 if (start_row > end_row)
428 start_row = end_row;
429
430 /* When display is not the full screen, gray scale is set to
431 ** 2; otherwise it is set to 64.
432 */
433 if ((start_row == 0) && (end_row == (QCIF_HEIGHT - 1))) {
434 /* The whole screen */
435 DISP_CMD_OUT(DISP_CMD_PTLOUT);
436 WAIT_SEC(10000);
437 DISP_CMD_OUT(DISP_CMD_DISOFF);
438 WAIT_SEC(100000);
439 DISP_CMD_OUT(DISP_CMD_GSSET);
440 DISP_DATA_OUT(DISP_GS_64);
441 WAIT_SEC(100000);
442 DISP_CMD_OUT(DISP_CMD_DISON);
443 } else {
444 /* partial screen */
445 DISP_CMD_OUT(DISP_CMD_PTLIN);
446 DISP_DATA_OUT(start_row);
447 DISP_DATA_OUT(start_row >> 8);
448 DISP_DATA_OUT(end_row);
449 DISP_DATA_OUT(end_row >> 8);
450 DISP_CMD_OUT(DISP_CMD_GSSET);
451 DISP_DATA_OUT(DISP_GS_2);
452 }
453}
454
455static int epsonQcif_disp_off(struct platform_device *pdev)
456{
457 if (!disp_initialized)
458 epsonQcif_disp_init(pdev);
459
460 if (display_on) {
461 DISP_CMD_OUT(DISP_CMD_DISOFF);
462 DISP_CMD_OUT(DISP_CMD_SLPIN);
463 display_on = FALSE;
464 }
465
466 return 0;
467}
468
469static int epsonQcif_disp_on(struct platform_device *pdev)
470{
471 if (!disp_initialized)
472 epsonQcif_disp_init(pdev);
473
474 if (!display_on) {
475 DISP_CMD_OUT(DISP_CMD_SLPOUT);
476 WAIT_SEC(40000);
477 DISP_CMD_OUT(DISP_CMD_DISON);
478 epsonQcif_disp_set_contrast(disp_contrast);
479 display_on = TRUE;
480 }
481
482 return 0;
483}
484
485static void epsonQcif_disp_set_contrast(word contrast)
486{
487 if (!disp_initialized)
488 return;
489
490 /* Initialize power IC, d'24 */
491 DISP_CMD_OUT(DISP_CMD_VOLCTL);
492 DISP_DATA_OUT(DISP_VOLCTL_TONE);
493
494 WAIT_SEC(40000);
495
496 /* Set electronic volume, d'xx */
497 DISP_CMD_OUT(DISP_CMD_VOLCTL);
498 if (contrast > 127)
499 contrast = 127;
500 DISP_DATA_OUT(contrast); /* value from 0 to 127 */
501 disp_contrast = (byte) contrast;
502} /* End disp_set_contrast */
503
504static void epsonQcif_disp_clear_screen_area(
505 word start_row, word end_row, word start_column, word end_column) {
506 int32 i;
507
508 /* Clear the display screen */
509 DISP_SET_RECT(start_row, end_row, start_column, end_column);
510 DISP_CMD_OUT(DISP_CMD_RAMWR);
511 i = (end_row - start_row + 1) * (end_column - start_column + 1);
512 for (; i > 0; i--)
513 DISP_DATA_OUT(0xffff);
514}
515
516static int __init epsonQcif_probe(struct platform_device *pdev)
517{
518 msm_fb_add_device(pdev);
519
520 return 0;
521}
522
523static struct platform_driver this_driver = {
524 .probe = epsonQcif_probe,
525 .driver = {
526 .name = "ebi2_epson_qcif",
527 },
528};
529
530static struct msm_fb_panel_data epsonQcif_panel_data = {
531 .on = epsonQcif_disp_on,
532 .off = epsonQcif_disp_off,
533 .set_rect = epsonQcif_disp_set_rect,
534};
535
536static struct platform_device this_device = {
537 .name = "ebi2_epson_qcif",
538 .id = 0,
539 .dev = {
540 .platform_data = &epsonQcif_panel_data,
541 }
542};
543
544static int __init epsonQcif_init(void)
545{
546 int ret;
547 struct msm_panel_info *pinfo;
548
549 ret = platform_driver_register(&this_driver);
550 if (!ret) {
551 pinfo = &epsonQcif_panel_data.panel_info;
552 pinfo->xres = QCIF_WIDTH;
553 pinfo->yres = QCIF_HEIGHT;
554 pinfo->type = EBI2_PANEL;
555 pinfo->pdest = DISPLAY_2;
556 pinfo->wait_cycle = 0x808000;
557 pinfo->bpp = 16;
558 pinfo->fb_num = 2;
559 pinfo->lcd.vsync_enable = FALSE;
560
561 ret = platform_device_register(&this_device);
562 if (ret)
563 platform_driver_unregister(&this_driver);
564 }
565
566 return ret;
567}
568
569module_init(epsonQcif_init);
diff --git a/drivers/staging/msm/ebi2_lcd.c b/drivers/staging/msm/ebi2_lcd.c
new file mode 100644
index 000000000000..b41e1230ceca
--- /dev/null
+++ b/drivers/staging/msm/ebi2_lcd.c
@@ -0,0 +1,250 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/mm.h>
24#include <linux/fb.h>
25#include <linux/init.h>
26#include <linux/ioport.h>
27#include <linux/device.h>
28#include <linux/dma-mapping.h>
29#include <linux/uaccess.h>
30#include <linux/workqueue.h>
31#include <linux/string.h>
32#include <linux/version.h>
33#include <linux/proc_fs.h>
34#include <linux/vmalloc.h>
35#include <linux/debugfs.h>
36
37#include "msm_fb.h"
38
39static int ebi2_lcd_probe(struct platform_device *pdev);
40static int ebi2_lcd_remove(struct platform_device *pdev);
41
42static struct platform_driver ebi2_lcd_driver = {
43 .probe = ebi2_lcd_probe,
44 .remove = ebi2_lcd_remove,
45 .suspend = NULL,
46 .suspend_late = NULL,
47 .resume_early = NULL,
48 .resume = NULL,
49 .shutdown = NULL,
50 .driver = {
51 .name = "ebi2_lcd",
52 },
53};
54
55static void *ebi2_base;
56static void *ebi2_lcd_cfg0;
57static void *ebi2_lcd_cfg1;
58static void __iomem *lcd01_base;
59static void __iomem *lcd02_base;
60static int ebi2_lcd_resource_initialized;
61
62static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
63static int pdev_list_cnt;
64
65static int ebi2_lcd_probe(struct platform_device *pdev)
66{
67 struct msm_fb_data_type *mfd;
68 struct platform_device *mdp_dev = NULL;
69 struct msm_fb_panel_data *pdata = NULL;
70 int rc, i;
71
72 if (pdev->id == 0) {
73 for (i = 0; i < pdev->num_resources; i++) {
74 if (!strncmp(pdev->resource[i].name, "base", 4)) {
75 ebi2_base = ioremap(pdev->resource[i].start,
76 pdev->resource[i].end -
77 pdev->resource[i].start + 1);
78 if (!ebi2_base) {
79 printk(KERN_ERR
80 "ebi2_base ioremap failed!\n");
81 return -ENOMEM;
82 }
83 ebi2_lcd_cfg0 = (void *)(ebi2_base + 0x20);
84 ebi2_lcd_cfg1 = (void *)(ebi2_base + 0x24);
85 } else if (!strncmp(pdev->resource[i].name,
86 "lcd01", 5)) {
87 lcd01_base = ioremap(pdev->resource[i].start,
88 pdev->resource[i].end -
89 pdev->resource[i].start + 1);
90 if (!lcd01_base) {
91 printk(KERN_ERR
92 "lcd01_base ioremap failed!\n");
93 return -ENOMEM;
94 }
95 } else if (!strncmp(pdev->resource[i].name,
96 "lcd02", 5)) {
97 lcd02_base = ioremap(pdev->resource[i].start,
98 pdev->resource[i].end -
99 pdev->resource[i].start + 1);
100 if (!lcd02_base) {
101 printk(KERN_ERR
102 "lcd02_base ioremap failed!\n");
103 return -ENOMEM;
104 }
105 }
106 }
107 ebi2_lcd_resource_initialized = 1;
108 return 0;
109 }
110
111 if (!ebi2_lcd_resource_initialized)
112 return -EPERM;
113
114 mfd = platform_get_drvdata(pdev);
115
116 if (!mfd)
117 return -ENODEV;
118
119 if (mfd->key != MFD_KEY)
120 return -EINVAL;
121
122 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
123 return -ENOMEM;
124
125 if (ebi2_base == NULL)
126 return -ENOMEM;
127
128 mdp_dev = platform_device_alloc("mdp", pdev->id);
129 if (!mdp_dev)
130 return -ENOMEM;
131
132 /* link to the latest pdev */
133 mfd->pdev = mdp_dev;
134 mfd->dest = DISPLAY_LCD;
135
136 /* add panel data */
137 if (platform_device_add_data
138 (mdp_dev, pdev->dev.platform_data,
139 sizeof(struct msm_fb_panel_data))) {
140 printk(KERN_ERR "ebi2_lcd_probe: platform_device_add_data failed!\n");
141 platform_device_put(mdp_dev);
142 return -ENOMEM;
143 }
144
145 /* data chain */
146 pdata = mdp_dev->dev.platform_data;
147 pdata->on = panel_next_on;
148 pdata->off = panel_next_off;
149 pdata->next = pdev;
150
151 /* get/set panel specific fb info */
152 mfd->panel_info = pdata->panel_info;
153
154 if (mfd->panel_info.bpp == 24)
155 mfd->fb_imgType = MDP_RGB_888;
156 else
157 mfd->fb_imgType = MDP_RGB_565;
158
159 /* config msm ebi2 lcd register */
160 if (mfd->panel_info.pdest == DISPLAY_1) {
161 outp32(ebi2_base,
162 (inp32(ebi2_base) & (~(EBI2_PRIM_LCD_CLR))) |
163 EBI2_PRIM_LCD_SEL);
164 /*
165 * current design has one set of cfg0/1 register to control
166 * both EBI2 channels. so, we're using the PRIM channel to
167 * configure both.
168 */
169 outp32(ebi2_lcd_cfg0, mfd->panel_info.wait_cycle);
170 if (mfd->panel_info.bpp == 18)
171 outp32(ebi2_lcd_cfg1, 0x01000000);
172 else
173 outp32(ebi2_lcd_cfg1, 0x0);
174 } else {
175#ifdef DEBUG_EBI2_LCD
176 /*
177 * confliting with QCOM SURF FPGA CS.
178 * OEM should enable below for their CS mapping
179 */
180 outp32(ebi2_base, (inp32(ebi2_base)&(~(EBI2_SECD_LCD_CLR)))
181 |EBI2_SECD_LCD_SEL);
182#endif
183 }
184
185 /*
186 * map cs (chip select) address
187 */
188 if (mfd->panel_info.pdest == DISPLAY_1) {
189 mfd->cmd_port = lcd01_base;
190 mfd->data_port =
191 (void *)((uint32) mfd->cmd_port + EBI2_PRIM_LCD_RS_PIN);
192 mfd->data_port_phys =
193 (void *)(LCD_PRIM_BASE_PHYS + EBI2_PRIM_LCD_RS_PIN);
194 } else {
195 mfd->cmd_port = lcd01_base;
196 mfd->data_port =
197 (void *)((uint32) mfd->cmd_port + EBI2_SECD_LCD_RS_PIN);
198 mfd->data_port_phys =
199 (void *)(LCD_SECD_BASE_PHYS + EBI2_SECD_LCD_RS_PIN);
200 }
201
202 /*
203 * set driver data
204 */
205 platform_set_drvdata(mdp_dev, mfd);
206
207 /*
208 * register in mdp driver
209 */
210 rc = platform_device_add(mdp_dev);
211 if (rc) {
212 goto ebi2_lcd_probe_err;
213 }
214
215 pdev_list[pdev_list_cnt++] = pdev;
216 return 0;
217
218 ebi2_lcd_probe_err:
219 platform_device_put(mdp_dev);
220 return rc;
221}
222
223static int ebi2_lcd_remove(struct platform_device *pdev)
224{
225 struct msm_fb_data_type *mfd;
226
227 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
228
229 if (!mfd)
230 return 0;
231
232 if (mfd->key != MFD_KEY)
233 return 0;
234
235 iounmap(mfd->cmd_port);
236
237 return 0;
238}
239
240static int ebi2_lcd_register_driver(void)
241{
242 return platform_driver_register(&ebi2_lcd_driver);
243}
244
245static int __init ebi2_lcd_driver_init(void)
246{
247 return ebi2_lcd_register_driver();
248}
249
250module_init(ebi2_lcd_driver_init); \ No newline at end of file
diff --git a/drivers/staging/msm/ebi2_tmd20.c b/drivers/staging/msm/ebi2_tmd20.c
new file mode 100644
index 000000000000..d66d03978253
--- /dev/null
+++ b/drivers/staging/msm/ebi2_tmd20.c
@@ -0,0 +1,1122 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19
20#include <linux/memory.h>
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/time.h>
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include "linux/proc_fs.h"
27
28#include <linux/delay.h>
29
30#include <mach/hardware.h>
31#include <linux/io.h>
32
33#include <asm/system.h>
34#include <asm/mach-types.h>
35
36/* #define TMD20QVGA_LCD_18BPP */
37#define QVGA_WIDTH 240
38#define QVGA_HEIGHT 320
39
40#ifdef TMD20QVGA_LCD_18BPP
41#define DISP_QVGA_18BPP(x) ((((x)<<2) & 0x3FC00)|(( (x)<<1)& 0x1FE))
42#define DISP_REG(name) uint32 register_##name;
43#define OUTPORT(x, y) outpdw(x, y)
44#define INPORT(x) inpdw(x)
45#else
46#define DISP_QVGA_18BPP(x) (x)
47#define DISP_REG(name) uint16 register_##name;
48#define OUTPORT(x, y) outpw(x, y)
49#define INPORT(x) intpw(x)
50#endif
51
52static void *DISP_CMD_PORT;
53static void *DISP_DATA_PORT;
54
55#define DISP_RNTI 0x10
56
57#define DISP_CMD_OUT(cmd) OUTPORT(DISP_CMD_PORT, DISP_QVGA_18BPP(cmd))
58#define DISP_DATA_OUT(data) OUTPORT(DISP_DATA_PORT, data)
59#define DISP_DATA_IN() INPORT(DISP_DATA_PORT)
60
61#if (defined(TMD20QVGA_LCD_18BPP))
62#define DISP_DATA_OUT_16TO18BPP(x) \
63 DISP_DATA_OUT((((x)&0xf800)<<2|((x)&0x80000)>>3) \
64 | (((x)&0x7e0)<<1) \
65 | (((x)&0x1F)<<1|((x)&0x10)>>4))
66#else
67#define DISP_DATA_OUT_16TO18BPP(x) \
68 DISP_DATA_OUT(x)
69#endif
70
71#define DISP_WRITE_OUT(addr, data) \
72 register_##addr = DISP_QVGA_18BPP(data); \
73 DISP_CMD_OUT(addr); \
74 DISP_DATA_OUT(register_##addr);
75
76#define DISP_UPDATE_VALUE(addr, bitmask, data) \
77 DISP_WRITE_OUT(##addr, (register_##addr & ~(bitmask)) | (data));
78
79#define DISP_VAL_IF(bitvalue, bitmask) \
80 ((bitvalue) ? (bitmask) : 0)
81
82/* QVGA = 256 x 320 */
83/* actual display is 240 x 320...offset by 0x10 */
84#define DISP_ROW_COL_TO_ADDR(row, col) ((row) * 0x100 + col)
85#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \
86 { \
87 DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_1_ADDR, (ulhc_col) + tmd20qvga_panel_offset); \
88 DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_2_ADDR, (lrhc_col) + tmd20qvga_panel_offset); \
89 DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_1_ADDR, (ulhc_row)); \
90 DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_2_ADDR, (lrhc_row)); \
91 DISP_WRITE_OUT(DISP_RAM_ADDR_SET_1_ADDR, (ulhc_col) + tmd20qvga_panel_offset); \
92 DISP_WRITE_OUT(DISP_RAM_ADDR_SET_2_ADDR, (ulhc_row)); \
93 }
94
95#define WAIT_MSEC(msec) mdelay(msec)
96
97/*
98 * TMD QVGA Address
99 */
100/* Display Control */
101#define DISP_START_OSCILLATION_ADDR 0x000
102DISP_REG(DISP_START_OSCILLATION_ADDR)
103#define DISP_DRIVER_OUTPUT_CTL_ADDR 0x001
104 DISP_REG(DISP_DRIVER_OUTPUT_CTL_ADDR)
105#define DISP_LCD_DRIVING_SIG_ADDR 0x002
106 DISP_REG(DISP_LCD_DRIVING_SIG_ADDR)
107#define DISP_ENTRY_MODE_ADDR 0x003
108 DISP_REG(DISP_ENTRY_MODE_ADDR)
109#define DISP_DISPLAY_CTL_1_ADDR 0x007
110 DISP_REG(DISP_DISPLAY_CTL_1_ADDR)
111#define DISP_DISPLAY_CTL_2_ADDR 0x008
112 DISP_REG(DISP_DISPLAY_CTL_2_ADDR)
113
114/* DISPLAY MODE 0x009 partial display not supported */
115#define DISP_POWER_SUPPLY_INTF_ADDR 0x00A
116 DISP_REG(DISP_POWER_SUPPLY_INTF_ADDR)
117
118/* DISPLAY MODE 0x00B xZoom feature is not supported */
119#define DISP_EXT_DISPLAY_CTL_1_ADDR 0x00C
120 DISP_REG(DISP_EXT_DISPLAY_CTL_1_ADDR)
121
122#define DISP_FRAME_CYCLE_CTL_ADDR 0x00D
123 DISP_REG(DISP_FRAME_CYCLE_CTL_ADDR)
124
125#define DISP_EXT_DISPLAY_CTL_2_ADDR 0x00E
126 DISP_REG(DISP_EXT_DISPLAY_CTL_2_ADDR)
127
128#define DISP_EXT_DISPLAY_CTL_3_ADDR 0x00F
129 DISP_REG(DISP_EXT_DISPLAY_CTL_3_ADDR)
130
131#define DISP_LTPS_CTL_1_ADDR 0x012
132 DISP_REG(DISP_LTPS_CTL_1_ADDR)
133#define DISP_LTPS_CTL_2_ADDR 0x013
134 DISP_REG(DISP_LTPS_CTL_2_ADDR)
135#define DISP_LTPS_CTL_3_ADDR 0x014
136 DISP_REG(DISP_LTPS_CTL_3_ADDR)
137#define DISP_LTPS_CTL_4_ADDR 0x018
138 DISP_REG(DISP_LTPS_CTL_4_ADDR)
139#define DISP_LTPS_CTL_5_ADDR 0x019
140 DISP_REG(DISP_LTPS_CTL_5_ADDR)
141#define DISP_LTPS_CTL_6_ADDR 0x01A
142 DISP_REG(DISP_LTPS_CTL_6_ADDR)
143#define DISP_AMP_SETTING_ADDR 0x01C
144 DISP_REG(DISP_AMP_SETTING_ADDR)
145#define DISP_MODE_SETTING_ADDR 0x01D
146 DISP_REG(DISP_MODE_SETTING_ADDR)
147#define DISP_POFF_LN_SETTING_ADDR 0x01E
148 DISP_REG(DISP_POFF_LN_SETTING_ADDR)
149/* Power Contol */
150#define DISP_POWER_CTL_1_ADDR 0x100
151 DISP_REG(DISP_POWER_CTL_1_ADDR)
152#define DISP_POWER_CTL_2_ADDR 0x101
153 DISP_REG(DISP_POWER_CTL_2_ADDR)
154#define DISP_POWER_CTL_3_ADDR 0x102
155 DISP_REG(DISP_POWER_CTL_3_ADDR)
156#define DISP_POWER_CTL_4_ADDR 0x103
157 DISP_REG(DISP_POWER_CTL_4_ADDR)
158#define DISP_POWER_CTL_5_ADDR 0x104
159 DISP_REG(DISP_POWER_CTL_5_ADDR)
160#define DISP_POWER_CTL_6_ADDR 0x105
161 DISP_REG(DISP_POWER_CTL_6_ADDR)
162#define DISP_POWER_CTL_7_ADDR 0x106
163 DISP_REG(DISP_POWER_CTL_7_ADDR)
164/* RAM Access */
165#define DISP_RAM_ADDR_SET_1_ADDR 0x200
166 DISP_REG(DISP_RAM_ADDR_SET_1_ADDR)
167#define DISP_RAM_ADDR_SET_2_ADDR 0x201
168 DISP_REG(DISP_RAM_ADDR_SET_2_ADDR)
169#define DISP_CMD_RAMRD DISP_CMD_RAMWR
170#define DISP_CMD_RAMWR 0x202
171 DISP_REG(DISP_CMD_RAMWR)
172#define DISP_RAM_DATA_MASK_1_ADDR 0x203
173 DISP_REG(DISP_RAM_DATA_MASK_1_ADDR)
174#define DISP_RAM_DATA_MASK_2_ADDR 0x204
175 DISP_REG(DISP_RAM_DATA_MASK_2_ADDR)
176/* Gamma Control, Contrast, Gray Scale Setting */
177#define DISP_GAMMA_CONTROL_1_ADDR 0x300
178 DISP_REG(DISP_GAMMA_CONTROL_1_ADDR)
179#define DISP_GAMMA_CONTROL_2_ADDR 0x301
180 DISP_REG(DISP_GAMMA_CONTROL_2_ADDR)
181#define DISP_GAMMA_CONTROL_3_ADDR 0x302
182 DISP_REG(DISP_GAMMA_CONTROL_3_ADDR)
183#define DISP_GAMMA_CONTROL_4_ADDR 0x303
184 DISP_REG(DISP_GAMMA_CONTROL_4_ADDR)
185#define DISP_GAMMA_CONTROL_5_ADDR 0x304
186 DISP_REG(DISP_GAMMA_CONTROL_5_ADDR)
187/* Coordinate Control */
188#define DISP_VERT_SCROLL_CTL_1_ADDR 0x400
189 DISP_REG(DISP_VERT_SCROLL_CTL_1_ADDR)
190#define DISP_VERT_SCROLL_CTL_2_ADDR 0x401
191 DISP_REG(DISP_VERT_SCROLL_CTL_2_ADDR)
192#define DISP_SCREEN_1_DRV_POS_1_ADDR 0x402
193 DISP_REG(DISP_SCREEN_1_DRV_POS_1_ADDR)
194#define DISP_SCREEN_1_DRV_POS_2_ADDR 0x403
195 DISP_REG(DISP_SCREEN_1_DRV_POS_2_ADDR)
196#define DISP_SCREEN_2_DRV_POS_1_ADDR 0x404
197 DISP_REG(DISP_SCREEN_2_DRV_POS_1_ADDR)
198#define DISP_SCREEN_2_DRV_POS_2_ADDR 0x405
199 DISP_REG(DISP_SCREEN_2_DRV_POS_2_ADDR)
200#define DISP_HORZ_RAM_ADDR_POS_1_ADDR 0x406
201 DISP_REG(DISP_HORZ_RAM_ADDR_POS_1_ADDR)
202#define DISP_HORZ_RAM_ADDR_POS_2_ADDR 0x407
203 DISP_REG(DISP_HORZ_RAM_ADDR_POS_2_ADDR)
204#define DISP_VERT_RAM_ADDR_POS_1_ADDR 0x408
205 DISP_REG(DISP_VERT_RAM_ADDR_POS_1_ADDR)
206#define DISP_VERT_RAM_ADDR_POS_2_ADDR 0x409
207 DISP_REG(DISP_VERT_RAM_ADDR_POS_2_ADDR)
208#define DISP_TMD_700_ADDR 0x700 /* 0x700 */
209 DISP_REG(DISP_TMD_700_ADDR)
210#define DISP_TMD_015_ADDR 0x015 /* 0x700 */
211 DISP_REG(DISP_TMD_015_ADDR)
212#define DISP_TMD_305_ADDR 0x305 /* 0x700 */
213 DISP_REG(DISP_TMD_305_ADDR)
214
215/*
216 * TMD QVGA Bit Definations
217 */
218
219#define DISP_BIT_IB15 0x8000
220#define DISP_BIT_IB14 0x4000
221#define DISP_BIT_IB13 0x2000
222#define DISP_BIT_IB12 0x1000
223#define DISP_BIT_IB11 0x0800
224#define DISP_BIT_IB10 0x0400
225#define DISP_BIT_IB09 0x0200
226#define DISP_BIT_IB08 0x0100
227#define DISP_BIT_IB07 0x0080
228#define DISP_BIT_IB06 0x0040
229#define DISP_BIT_IB05 0x0020
230#define DISP_BIT_IB04 0x0010
231#define DISP_BIT_IB03 0x0008
232#define DISP_BIT_IB02 0x0004
233#define DISP_BIT_IB01 0x0002
234#define DISP_BIT_IB00 0x0001
235/*
236 * Display Control
237 * DISP_START_OSCILLATION_ADDR Start Oscillation
238 * DISP_DRIVER_OUTPUT_CTL_ADDR Driver Output Control
239 */
240#define DISP_BITMASK_SS DISP_BIT_IB08
241#define DISP_BITMASK_NL5 DISP_BIT_IB05
242#define DISP_BITMASK_NL4 DISP_BIT_IB04
243#define DISP_BITMASK_NL3 DISP_BIT_IB03
244#define DISP_BITMASK_NL2 DISP_BIT_IB02
245#define DISP_BITMASK_NL1 DISP_BIT_IB01
246#define DISP_BITMASK_NL0 DISP_BIT_IB00
247/* DISP_LCD_DRIVING_SIG_ADDR LCD Driving Signal Setting */
248#define DISP_BITMASK_BC DISP_BIT_IB09
249/* DISP_ENTRY_MODE_ADDR Entry Mode */
250#define DISP_BITMASK_TRI DISP_BIT_IB15
251#define DISP_BITMASK_DFM1 DISP_BIT_IB14
252#define DISP_BITMASK_DFM0 DISP_BIT_IB13
253#define DISP_BITMASK_BGR DISP_BIT_IB12
254#define DISP_BITMASK_HWM0 DISP_BIT_IB08
255#define DISP_BITMASK_ID1 DISP_BIT_IB05
256#define DISP_BITMASK_ID0 DISP_BIT_IB04
257#define DISP_BITMASK_AM DISP_BIT_IB03
258/* DISP_DISPLAY_CTL_1_ADDR Display Control (1) */
259#define DISP_BITMASK_COL1 DISP_BIT_IB15
260#define DISP_BITMASK_COL0 DISP_BIT_IB14
261#define DISP_BITMASK_VLE2 DISP_BIT_IB10
262#define DISP_BITMASK_VLE1 DISP_BIT_IB09
263#define DISP_BITMASK_SPT DISP_BIT_IB08
264#define DISP_BITMASK_PT1 DISP_BIT_IB07
265#define DISP_BITMASK_PT0 DISP_BIT_IB06
266#define DISP_BITMASK_REV DISP_BIT_IB02
267/* DISP_DISPLAY_CTL_2_ADDR Display Control (2) */
268#define DISP_BITMASK_FP3 DISP_BIT_IB11
269#define DISP_BITMASK_FP2 DISP_BIT_IB10
270#define DISP_BITMASK_FP1 DISP_BIT_IB09
271#define DISP_BITMASK_FP0 DISP_BIT_IB08
272#define DISP_BITMASK_BP3 DISP_BIT_IB03
273#define DISP_BITMASK_BP2 DISP_BIT_IB02
274#define DISP_BITMASK_BP1 DISP_BIT_IB01
275#define DISP_BITMASK_BP0 DISP_BIT_IB00
276/* DISP_POWER_SUPPLY_INTF_ADDR Power Supply IC Interface Control */
277#define DISP_BITMASK_CSE DISP_BIT_IB12
278#define DISP_BITMASK_TE DISP_BIT_IB08
279#define DISP_BITMASK_IX3 DISP_BIT_IB03
280#define DISP_BITMASK_IX2 DISP_BIT_IB02
281#define DISP_BITMASK_IX1 DISP_BIT_IB01
282#define DISP_BITMASK_IX0 DISP_BIT_IB00
283/* DISP_EXT_DISPLAY_CTL_1_ADDR External Display Interface Control (1) */
284#define DISP_BITMASK_RM DISP_BIT_IB08
285#define DISP_BITMASK_DM1 DISP_BIT_IB05
286#define DISP_BITMASK_DM0 DISP_BIT_IB04
287#define DISP_BITMASK_RIM1 DISP_BIT_IB01
288#define DISP_BITMASK_RIM0 DISP_BIT_IB00
289/* DISP_FRAME_CYCLE_CTL_ADDR Frame Frequency Adjustment Control */
290#define DISP_BITMASK_DIVI1 DISP_BIT_IB09
291#define DISP_BITMASK_DIVI0 DISP_BIT_IB08
292#define DISP_BITMASK_RTNI4 DISP_BIT_IB04
293#define DISP_BITMASK_RTNI3 DISP_BIT_IB03
294#define DISP_BITMASK_RTNI2 DISP_BIT_IB02
295#define DISP_BITMASK_RTNI1 DISP_BIT_IB01
296#define DISP_BITMASK_RTNI0 DISP_BIT_IB00
297/* DISP_EXT_DISPLAY_CTL_2_ADDR External Display Interface Control (2) */
298#define DISP_BITMASK_DIVE1 DISP_BIT_IB09
299#define DISP_BITMASK_DIVE0 DISP_BIT_IB08
300#define DISP_BITMASK_RTNE7 DISP_BIT_IB07
301#define DISP_BITMASK_RTNE6 DISP_BIT_IB06
302#define DISP_BITMASK_RTNE5 DISP_BIT_IB05
303#define DISP_BITMASK_RTNE4 DISP_BIT_IB04
304#define DISP_BITMASK_RTNE3 DISP_BIT_IB03
305#define DISP_BITMASK_RTNE2 DISP_BIT_IB02
306#define DISP_BITMASK_RTNE1 DISP_BIT_IB01
307#define DISP_BITMASK_RTNE0 DISP_BIT_IB00
308/* DISP_EXT_DISPLAY_CTL_3_ADDR External Display Interface Control (3) */
309#define DISP_BITMASK_VSPL DISP_BIT_IB04
310#define DISP_BITMASK_HSPL DISP_BIT_IB03
311#define DISP_BITMASK_VPL DISP_BIT_IB02
312#define DISP_BITMASK_EPL DISP_BIT_IB01
313#define DISP_BITMASK_DPL DISP_BIT_IB00
314/* DISP_LTPS_CTL_1_ADDR LTPS Interface Control (1) */
315#define DISP_BITMASK_CLWI3 DISP_BIT_IB11
316#define DISP_BITMASK_CLWI2 DISP_BIT_IB10
317#define DISP_BITMASK_CLWI1 DISP_BIT_IB09
318#define DISP_BITMASK_CLWI0 DISP_BIT_IB08
319#define DISP_BITMASK_CLTI1 DISP_BIT_IB01
320#define DISP_BITMASK_CLTI0 DISP_BIT_IB00
321/* DISP_LTPS_CTL_2_ADDR LTPS Interface Control (2) */
322#define DISP_BITMASK_OEVBI1 DISP_BIT_IB09
323#define DISP_BITMASK_OEVBI0 DISP_BIT_IB08
324#define DISP_BITMASK_OEVFI1 DISP_BIT_IB01
325#define DISP_BITMASK_OEVFI0 DISP_BIT_IB00
326/* DISP_LTPS_CTL_3_ADDR LTPS Interface Control (3) */
327#define DISP_BITMASK_SHI1 DISP_BIT_IB01
328#define DISP_BITMASK_SHI0 DISP_BIT_IB00
329/* DISP_LTPS_CTL_4_ADDR LTPS Interface Control (4) */
330#define DISP_BITMASK_CLWE5 DISP_BIT_IB13
331#define DISP_BITMASK_CLWE4 DISP_BIT_IB12
332#define DISP_BITMASK_CLWE3 DISP_BIT_IB11
333#define DISP_BITMASK_CLWE2 DISP_BIT_IB10
334#define DISP_BITMASK_CLWE1 DISP_BIT_IB09
335#define DISP_BITMASK_CLWE0 DISP_BIT_IB08
336#define DISP_BITMASK_CLTE3 DISP_BIT_IB03
337#define DISP_BITMASK_CLTE2 DISP_BIT_IB02
338#define DISP_BITMASK_CLTE1 DISP_BIT_IB01
339#define DISP_BITMASK_CLTE0 DISP_BIT_IB00
340/* DISP_LTPS_CTL_5_ADDR LTPS Interface Control (5) */
341#define DISP_BITMASK_OEVBE3 DISP_BIT_IB11
342#define DISP_BITMASK_OEVBE2 DISP_BIT_IB10
343#define DISP_BITMASK_OEVBE1 DISP_BIT_IB09
344#define DISP_BITMASK_OEVBE0 DISP_BIT_IB08
345#define DISP_BITMASK_OEVFE3 DISP_BIT_IB03
346#define DISP_BITMASK_OEVFE2 DISP_BIT_IB02
347#define DISP_BITMASK_OEVFE1 DISP_BIT_IB01
348#define DISP_BITMASK_OEVFE0 DISP_BIT_IB00
349/* DISP_LTPS_CTL_6_ADDR LTPS Interface Control (6) */
350#define DISP_BITMASK_SHE3 DISP_BIT_IB03
351#define DISP_BITMASK_SHE2 DISP_BIT_IB02
352#define DISP_BITMASK_SHE1 DISP_BIT_IB01
353#define DISP_BITMASK_SHE0 DISP_BIT_IB00
354/* DISP_AMP_SETTING_ADDR Amplify Setting */
355#define DISP_BITMASK_ABSW1 DISP_BIT_IB01
356#define DISP_BITMASK_ABSW0 DISP_BIT_IB00
357/* DISP_MODE_SETTING_ADDR Mode Setting */
358#define DISP_BITMASK_DSTB DISP_BIT_IB02
359#define DISP_BITMASK_STB DISP_BIT_IB00
360/* DISP_POFF_LN_SETTING_ADDR Power Off Line Setting */
361#define DISP_BITMASK_POFH3 DISP_BIT_IB03
362#define DISP_BITMASK_POFH2 DISP_BIT_IB02
363#define DISP_BITMASK_POFH1 DISP_BIT_IB01
364#define DISP_BITMASK_POFH0 DISP_BIT_IB00
365
366/* Power Contol */
367/* DISP_POWER_CTL_1_ADDR Power Control (1) */
368#define DISP_BITMASK_PO DISP_BIT_IB11
369#define DISP_BITMASK_VCD DISP_BIT_IB09
370#define DISP_BITMASK_VSC DISP_BIT_IB08
371#define DISP_BITMASK_CON DISP_BIT_IB07
372#define DISP_BITMASK_ASW1 DISP_BIT_IB06
373#define DISP_BITMASK_ASW0 DISP_BIT_IB05
374#define DISP_BITMASK_OEV DISP_BIT_IB04
375#define DISP_BITMASK_OEVE DISP_BIT_IB03
376#define DISP_BITMASK_FR DISP_BIT_IB02
377#define DISP_BITMASK_D1 DISP_BIT_IB01
378#define DISP_BITMASK_D0 DISP_BIT_IB00
379/* DISP_POWER_CTL_2_ADDR Power Control (2) */
380#define DISP_BITMASK_DC4 DISP_BIT_IB15
381#define DISP_BITMASK_DC3 DISP_BIT_IB14
382#define DISP_BITMASK_SAP2 DISP_BIT_IB13
383#define DISP_BITMASK_SAP1 DISP_BIT_IB12
384#define DISP_BITMASK_SAP0 DISP_BIT_IB11
385#define DISP_BITMASK_BT2 DISP_BIT_IB10
386#define DISP_BITMASK_BT1 DISP_BIT_IB09
387#define DISP_BITMASK_BT0 DISP_BIT_IB08
388#define DISP_BITMASK_DC2 DISP_BIT_IB07
389#define DISP_BITMASK_DC1 DISP_BIT_IB06
390#define DISP_BITMASK_DC0 DISP_BIT_IB05
391#define DISP_BITMASK_AP2 DISP_BIT_IB04
392#define DISP_BITMASK_AP1 DISP_BIT_IB03
393#define DISP_BITMASK_AP0 DISP_BIT_IB02
394/* DISP_POWER_CTL_3_ADDR Power Control (3) */
395#define DISP_BITMASK_VGL4 DISP_BIT_IB10
396#define DISP_BITMASK_VGL3 DISP_BIT_IB09
397#define DISP_BITMASK_VGL2 DISP_BIT_IB08
398#define DISP_BITMASK_VGL1 DISP_BIT_IB07
399#define DISP_BITMASK_VGL0 DISP_BIT_IB06
400#define DISP_BITMASK_VGH4 DISP_BIT_IB04
401#define DISP_BITMASK_VGH3 DISP_BIT_IB03
402#define DISP_BITMASK_VGH2 DISP_BIT_IB02
403#define DISP_BITMASK_VGH1 DISP_BIT_IB01
404#define DISP_BITMASK_VGH0 DISP_BIT_IB00
405/* DISP_POWER_CTL_4_ADDR Power Control (4) */
406#define DISP_BITMASK_VC2 DISP_BIT_IB02
407#define DISP_BITMASK_VC1 DISP_BIT_IB01
408#define DISP_BITMASK_VC0 DISP_BIT_IB00
409/* DISP_POWER_CTL_5_ADDR Power Control (5) */
410#define DISP_BITMASK_VRL3 DISP_BIT_IB11
411#define DISP_BITMASK_VRL2 DISP_BIT_IB10
412#define DISP_BITMASK_VRL1 DISP_BIT_IB09
413#define DISP_BITMASK_VRL0 DISP_BIT_IB08
414#define DISP_BITMASK_PON DISP_BIT_IB04
415#define DISP_BITMASK_VRH3 DISP_BIT_IB03
416#define DISP_BITMASK_VRH2 DISP_BIT_IB02
417#define DISP_BITMASK_VRH1 DISP_BIT_IB01
418#define DISP_BITMASK_VRH0 DISP_BIT_IB00
419/* DISP_POWER_CTL_6_ADDR Power Control (6) */
420#define DISP_BITMASK_VCOMG DISP_BIT_IB13
421#define DISP_BITMASK_VDV4 DISP_BIT_IB12
422#define DISP_BITMASK_VDV3 DISP_BIT_IB11
423#define DISP_BITMASK_VDV2 DISP_BIT_IB10
424#define DISP_BITMASK_VDV1 DISP_BIT_IB09
425#define DISP_BITMASK_VDV0 DISP_BIT_IB08
426#define DISP_BITMASK_VCM4 DISP_BIT_IB04
427#define DISP_BITMASK_VCM3 DISP_BIT_IB03
428#define DISP_BITMASK_VCM2 DISP_BIT_IB02
429#define DISP_BITMASK_VCM1 DISP_BIT_IB01
430#define DISP_BITMASK_VCM0 DISP_BIT_IB00
431/* RAM Access */
432/* DISP_RAM_ADDR_SET_1_ADDR RAM Address Set (1) */
433#define DISP_BITMASK_AD7 DISP_BIT_IB07
434#define DISP_BITMASK_AD6 DISP_BIT_IB06
435#define DISP_BITMASK_AD5 DISP_BIT_IB05
436#define DISP_BITMASK_AD4 DISP_BIT_IB04
437#define DISP_BITMASK_AD3 DISP_BIT_IB03
438#define DISP_BITMASK_AD2 DISP_BIT_IB02
439#define DISP_BITMASK_AD1 DISP_BIT_IB01
440#define DISP_BITMASK_AD0 DISP_BIT_IB00
441/* DISP_RAM_ADDR_SET_2_ADDR RAM Address Set (2) */
442#define DISP_BITMASK_AD16 DISP_BIT_IB08
443#define DISP_BITMASK_AD15 DISP_BIT_IB07
444#define DISP_BITMASK_AD14 DISP_BIT_IB06
445#define DISP_BITMASK_AD13 DISP_BIT_IB05
446#define DISP_BITMASK_AD12 DISP_BIT_IB04
447#define DISP_BITMASK_AD11 DISP_BIT_IB03
448#define DISP_BITMASK_AD10 DISP_BIT_IB02
449#define DISP_BITMASK_AD9 DISP_BIT_IB01
450#define DISP_BITMASK_AD8 DISP_BIT_IB00
451/*
452 * DISP_CMD_RAMWR RAM Data Read/Write
453 * Use Data Bit Configuration
454 */
455/* DISP_RAM_DATA_MASK_1_ADDR RAM Write Data Mask (1) */
456#define DISP_BITMASK_WM11 DISP_BIT_IB13
457#define DISP_BITMASK_WM10 DISP_BIT_IB12
458#define DISP_BITMASK_WM9 DISP_BIT_IB11
459#define DISP_BITMASK_WM8 DISP_BIT_IB10
460#define DISP_BITMASK_WM7 DISP_BIT_IB09
461#define DISP_BITMASK_WM6 DISP_BIT_IB08
462#define DISP_BITMASK_WM5 DISP_BIT_IB05
463#define DISP_BITMASK_WM4 DISP_BIT_IB04
464#define DISP_BITMASK_WM3 DISP_BIT_IB03
465#define DISP_BITMASK_WM2 DISP_BIT_IB02
466#define DISP_BITMASK_WM1 DISP_BIT_IB01
467#define DISP_BITMASK_WM0 DISP_BIT_IB00
468/* DISP_RAM_DATA_MASK_2_ADDR RAM Write Data Mask (2) */
469#define DISP_BITMASK_WM17 DISP_BIT_IB05
470#define DISP_BITMASK_WM16 DISP_BIT_IB04
471#define DISP_BITMASK_WM15 DISP_BIT_IB03
472#define DISP_BITMASK_WM14 DISP_BIT_IB02
473#define DISP_BITMASK_WM13 DISP_BIT_IB01
474#define DISP_BITMASK_WM12 DISP_BIT_IB00
475/*Gamma Control */
476/* DISP_GAMMA_CONTROL_1_ADDR Gamma Control (1) */
477#define DISP_BITMASK_PKP12 DISP_BIT_IB10
478#define DISP_BITMASK_PKP11 DISP_BIT_IB08
479#define DISP_BITMASK_PKP10 DISP_BIT_IB09
480#define DISP_BITMASK_PKP02 DISP_BIT_IB02
481#define DISP_BITMASK_PKP01 DISP_BIT_IB01
482#define DISP_BITMASK_PKP00 DISP_BIT_IB00
483/* DISP_GAMMA_CONTROL_2_ADDR Gamma Control (2) */
484#define DISP_BITMASK_PKP32 DISP_BIT_IB10
485#define DISP_BITMASK_PKP31 DISP_BIT_IB09
486#define DISP_BITMASK_PKP30 DISP_BIT_IB08
487#define DISP_BITMASK_PKP22 DISP_BIT_IB02
488#define DISP_BITMASK_PKP21 DISP_BIT_IB01
489#define DISP_BITMASK_PKP20 DISP_BIT_IB00
490/* DISP_GAMMA_CONTROL_3_ADDR Gamma Control (3) */
491#define DISP_BITMASK_PKP52 DISP_BIT_IB10
492#define DISP_BITMASK_PKP51 DISP_BIT_IB09
493#define DISP_BITMASK_PKP50 DISP_BIT_IB08
494#define DISP_BITMASK_PKP42 DISP_BIT_IB02
495#define DISP_BITMASK_PKP41 DISP_BIT_IB01
496#define DISP_BITMASK_PKP40 DISP_BIT_IB00
497/* DISP_GAMMA_CONTROL_4_ADDR Gamma Control (4) */
498#define DISP_BITMASK_PRP12 DISP_BIT_IB10
499#define DISP_BITMASK_PRP11 DISP_BIT_IB08
500#define DISP_BITMASK_PRP10 DISP_BIT_IB09
501#define DISP_BITMASK_PRP02 DISP_BIT_IB02
502#define DISP_BITMASK_PRP01 DISP_BIT_IB01
503#define DISP_BITMASK_PRP00 DISP_BIT_IB00
504/* DISP_GAMMA_CONTROL_5_ADDR Gamma Control (5) */
505#define DISP_BITMASK_VRP14 DISP_BIT_IB12
506#define DISP_BITMASK_VRP13 DISP_BIT_IB11
507#define DISP_BITMASK_VRP12 DISP_BIT_IB10
508#define DISP_BITMASK_VRP11 DISP_BIT_IB08
509#define DISP_BITMASK_VRP10 DISP_BIT_IB09
510#define DISP_BITMASK_VRP03 DISP_BIT_IB03
511#define DISP_BITMASK_VRP02 DISP_BIT_IB02
512#define DISP_BITMASK_VRP01 DISP_BIT_IB01
513#define DISP_BITMASK_VRP00 DISP_BIT_IB00
514/* DISP_GAMMA_CONTROL_6_ADDR Gamma Control (6) */
515#define DISP_BITMASK_PKN12 DISP_BIT_IB10
516#define DISP_BITMASK_PKN11 DISP_BIT_IB08
517#define DISP_BITMASK_PKN10 DISP_BIT_IB09
518#define DISP_BITMASK_PKN02 DISP_BIT_IB02
519#define DISP_BITMASK_PKN01 DISP_BIT_IB01
520#define DISP_BITMASK_PKN00 DISP_BIT_IB00
521/* DISP_GAMMA_CONTROL_7_ADDR Gamma Control (7) */
522#define DISP_BITMASK_PKN32 DISP_BIT_IB10
523#define DISP_BITMASK_PKN31 DISP_BIT_IB08
524#define DISP_BITMASK_PKN30 DISP_BIT_IB09
525#define DISP_BITMASK_PKN22 DISP_BIT_IB02
526#define DISP_BITMASK_PKN21 DISP_BIT_IB01
527#define DISP_BITMASK_PKN20 DISP_BIT_IB00
528/* DISP_GAMMA_CONTROL_8_ADDR Gamma Control (8) */
529#define DISP_BITMASK_PKN52 DISP_BIT_IB10
530#define DISP_BITMASK_PKN51 DISP_BIT_IB08
531#define DISP_BITMASK_PKN50 DISP_BIT_IB09
532#define DISP_BITMASK_PKN42 DISP_BIT_IB02
533#define DISP_BITMASK_PKN41 DISP_BIT_IB01
534#define DISP_BITMASK_PKN40 DISP_BIT_IB00
535/* DISP_GAMMA_CONTROL_9_ADDR Gamma Control (9) */
536#define DISP_BITMASK_PRN12 DISP_BIT_IB10
537#define DISP_BITMASK_PRN11 DISP_BIT_IB08
538#define DISP_BITMASK_PRN10 DISP_BIT_IB09
539#define DISP_BITMASK_PRN02 DISP_BIT_IB02
540#define DISP_BITMASK_PRN01 DISP_BIT_IB01
541#define DISP_BITMASK_PRN00 DISP_BIT_IB00
542/* DISP_GAMMA_CONTROL_10_ADDR Gamma Control (10) */
543#define DISP_BITMASK_VRN14 DISP_BIT_IB12
544#define DISP_BITMASK_VRN13 DISP_BIT_IB11
545#define DISP_BITMASK_VRN12 DISP_BIT_IB10
546#define DISP_BITMASK_VRN11 DISP_BIT_IB08
547#define DISP_BITMASK_VRN10 DISP_BIT_IB09
548#define DISP_BITMASK_VRN03 DISP_BIT_IB03
549#define DISP_BITMASK_VRN02 DISP_BIT_IB02
550#define DISP_BITMASK_VRN01 DISP_BIT_IB01
551#define DISP_BITMASK_VRN00 DISP_BIT_IB00
552/* Coordinate Control */
553/* DISP_VERT_SCROLL_CTL_1_ADDR Vertical Scroll Control (1) */
554#define DISP_BITMASK_VL18 DISP_BIT_IB08
555#define DISP_BITMASK_VL17 DISP_BIT_IB07
556#define DISP_BITMASK_VL16 DISP_BIT_IB06
557#define DISP_BITMASK_VL15 DISP_BIT_IB05
558#define DISP_BITMASK_VL14 DISP_BIT_IB04
559#define DISP_BITMASK_VL13 DISP_BIT_IB03
560#define DISP_BITMASK_VL12 DISP_BIT_IB02
561#define DISP_BITMASK_VL11 DISP_BIT_IB01
562#define DISP_BITMASK_VL10 DISP_BIT_IB00
563/* DISP_VERT_SCROLL_CTL_2_ADDR Vertical Scroll Control (2) */
564#define DISP_BITMASK_VL28 DISP_BIT_IB08
565#define DISP_BITMASK_VL27 DISP_BIT_IB07
566#define DISP_BITMASK_VL26 DISP_BIT_IB06
567#define DISP_BITMASK_VL25 DISP_BIT_IB05
568#define DISP_BITMASK_VL24 DISP_BIT_IB04
569#define DISP_BITMASK_VL23 DISP_BIT_IB03
570#define DISP_BITMASK_VL22 DISP_BIT_IB02
571#define DISP_BITMASK_VL21 DISP_BIT_IB01
572#define DISP_BITMASK_VL20 DISP_BIT_IB00
573/* DISP_SCREEN_1_DRV_POS_1_ADDR First Screen Driving Position (1) */
574#define DISP_BITMASK_SS18 DISP_BIT_IB08
575#define DISP_BITMASK_SS17 DISP_BIT_IB07
576#define DISP_BITMASK_SS16 DISP_BIT_IB06
577#define DISP_BITMASK_SS15 DISP_BIT_IB05
578#define DISP_BITMASK_SS14 DISP_BIT_IB04
579#define DISP_BITMASK_SS13 DISP_BIT_IB03
580#define DISP_BITMASK_SS12 DISP_BIT_IB02
581#define DISP_BITMASK_SS11 DISP_BIT_IB01
582#define DISP_BITMASK_SS10 DISP_BIT_IB00
583/* DISP_SCREEN_1_DRV_POS_2_ADDR First Screen Driving Position (2) */
584#define DISP_BITMASK_SE18 DISP_BIT_IB08
585#define DISP_BITMASK_SE17 DISP_BIT_IB07
586#define DISP_BITMASK_SE16 DISP_BIT_IB06
587#define DISP_BITMASK_SE15 DISP_BIT_IB05
588#define DISP_BITMASK_SE14 DISP_BIT_IB04
589#define DISP_BITMASK_SE13 DISP_BIT_IB03
590#define DISP_BITMASK_SE12 DISP_BIT_IB02
591#define DISP_BITMASK_SE11 DISP_BIT_IB01
592#define DISP_BITMASK_SE10 DISP_BIT_IB00
593/* DISP_SCREEN_2_DRV_POS_1_ADDR Second Screen Driving Position (1) */
594#define DISP_BITMASK_SS28 DISP_BIT_IB08
595#define DISP_BITMASK_SS27 DISP_BIT_IB07
596#define DISP_BITMASK_SS26 DISP_BIT_IB06
597#define DISP_BITMASK_SS25 DISP_BIT_IB05
598#define DISP_BITMASK_SS24 DISP_BIT_IB04
599#define DISP_BITMASK_SS23 DISP_BIT_IB03
600#define DISP_BITMASK_SS22 DISP_BIT_IB02
601#define DISP_BITMASK_SS21 DISP_BIT_IB01
602#define DISP_BITMASK_SS20 DISP_BIT_IB00
603/* DISP_SCREEN_3_DRV_POS_2_ADDR Second Screen Driving Position (2) */
604#define DISP_BITMASK_SE28 DISP_BIT_IB08
605#define DISP_BITMASK_SE27 DISP_BIT_IB07
606#define DISP_BITMASK_SE26 DISP_BIT_IB06
607#define DISP_BITMASK_SE25 DISP_BIT_IB05
608#define DISP_BITMASK_SE24 DISP_BIT_IB04
609#define DISP_BITMASK_SE23 DISP_BIT_IB03
610#define DISP_BITMASK_SE22 DISP_BIT_IB02
611#define DISP_BITMASK_SE21 DISP_BIT_IB01
612#define DISP_BITMASK_SE20 DISP_BIT_IB00
613/* DISP_HORZ_RAM_ADDR_POS_1_ADDR Horizontal RAM Address Position (1) */
614#define DISP_BITMASK_HSA7 DISP_BIT_IB07
615#define DISP_BITMASK_HSA6 DISP_BIT_IB06
616#define DISP_BITMASK_HSA5 DISP_BIT_IB05
617#define DISP_BITMASK_HSA4 DISP_BIT_IB04
618#define DISP_BITMASK_HSA3 DISP_BIT_IB03
619#define DISP_BITMASK_HSA2 DISP_BIT_IB02
620#define DISP_BITMASK_HSA1 DISP_BIT_IB01
621#define DISP_BITMASK_HSA0 DISP_BIT_IB00
622/* DISP_HORZ_RAM_ADDR_POS_2_ADDR Horizontal RAM Address Position (2) */
623#define DISP_BITMASK_HEA7 DISP_BIT_IB07
624#define DISP_BITMASK_HEA6 DISP_BIT_IB06
625#define DISP_BITMASK_HEA5 DISP_BIT_IB05
626#define DISP_BITMASK_HEA4 DISP_BIT_IB04
627#define DISP_BITMASK_HEA3 DISP_BIT_IB03
628#define DISP_BITMASK_HEA2 DISP_BIT_IB02
629#define DISP_BITMASK_HEA1 DISP_BIT_IB01
630#define DISP_BITMASK_HEA0 DISP_BIT_IB00
631/* DISP_VERT_RAM_ADDR_POS_1_ADDR Vertical RAM Address Position (1) */
632#define DISP_BITMASK_VSA8 DISP_BIT_IB08
633#define DISP_BITMASK_VSA7 DISP_BIT_IB07
634#define DISP_BITMASK_VSA6 DISP_BIT_IB06
635#define DISP_BITMASK_VSA5 DISP_BIT_IB05
636#define DISP_BITMASK_VSA4 DISP_BIT_IB04
637#define DISP_BITMASK_VSA3 DISP_BIT_IB03
638#define DISP_BITMASK_VSA2 DISP_BIT_IB02
639#define DISP_BITMASK_VSA1 DISP_BIT_IB01
640#define DISP_BITMASK_VSA0 DISP_BIT_IB00
641/* DISP_VERT_RAM_ADDR_POS_2_ADDR Vertical RAM Address Position (2) */
642#define DISP_BITMASK_VEA8 DISP_BIT_IB08
643#define DISP_BITMASK_VEA7 DISP_BIT_IB07
644#define DISP_BITMASK_VEA6 DISP_BIT_IB06
645#define DISP_BITMASK_VEA5 DISP_BIT_IB05
646#define DISP_BITMASK_VEA4 DISP_BIT_IB04
647#define DISP_BITMASK_VEA3 DISP_BIT_IB03
648#define DISP_BITMASK_VEA2 DISP_BIT_IB02
649#define DISP_BITMASK_VEA1 DISP_BIT_IB01
650#define DISP_BITMASK_VEA0 DISP_BIT_IB00
651static word disp_area_start_row;
652static word disp_area_end_row;
653static boolean disp_initialized = FALSE;
654/* For some reason the contrast set at init time is not good. Need to do
655* it again
656*/
657static boolean display_on = FALSE;
658
659static uint32 tmd20qvga_lcd_rev;
660uint16 tmd20qvga_panel_offset;
661
662#ifdef DISP_DEVICE_8BPP
663static word convert_8_to_16_tbl[256] = {
664 0x0000, 0x2000, 0x4000, 0x6000, 0x8000, 0xA000, 0xC000, 0xE000,
665 0x0100, 0x2100, 0x4100, 0x6100, 0x8100, 0xA100, 0xC100, 0xE100,
666 0x0200, 0x2200, 0x4200, 0x6200, 0x8200, 0xA200, 0xC200, 0xE200,
667 0x0300, 0x2300, 0x4300, 0x6300, 0x8300, 0xA300, 0xC300, 0xE300,
668 0x0400, 0x2400, 0x4400, 0x6400, 0x8400, 0xA400, 0xC400, 0xE400,
669 0x0500, 0x2500, 0x4500, 0x6500, 0x8500, 0xA500, 0xC500, 0xE500,
670 0x0600, 0x2600, 0x4600, 0x6600, 0x8600, 0xA600, 0xC600, 0xE600,
671 0x0700, 0x2700, 0x4700, 0x6700, 0x8700, 0xA700, 0xC700, 0xE700,
672 0x0008, 0x2008, 0x4008, 0x6008, 0x8008, 0xA008, 0xC008, 0xE008,
673 0x0108, 0x2108, 0x4108, 0x6108, 0x8108, 0xA108, 0xC108, 0xE108,
674 0x0208, 0x2208, 0x4208, 0x6208, 0x8208, 0xA208, 0xC208, 0xE208,
675 0x0308, 0x2308, 0x4308, 0x6308, 0x8308, 0xA308, 0xC308, 0xE308,
676 0x0408, 0x2408, 0x4408, 0x6408, 0x8408, 0xA408, 0xC408, 0xE408,
677 0x0508, 0x2508, 0x4508, 0x6508, 0x8508, 0xA508, 0xC508, 0xE508,
678 0x0608, 0x2608, 0x4608, 0x6608, 0x8608, 0xA608, 0xC608, 0xE608,
679 0x0708, 0x2708, 0x4708, 0x6708, 0x8708, 0xA708, 0xC708, 0xE708,
680 0x0010, 0x2010, 0x4010, 0x6010, 0x8010, 0xA010, 0xC010, 0xE010,
681 0x0110, 0x2110, 0x4110, 0x6110, 0x8110, 0xA110, 0xC110, 0xE110,
682 0x0210, 0x2210, 0x4210, 0x6210, 0x8210, 0xA210, 0xC210, 0xE210,
683 0x0310, 0x2310, 0x4310, 0x6310, 0x8310, 0xA310, 0xC310, 0xE310,
684 0x0410, 0x2410, 0x4410, 0x6410, 0x8410, 0xA410, 0xC410, 0xE410,
685 0x0510, 0x2510, 0x4510, 0x6510, 0x8510, 0xA510, 0xC510, 0xE510,
686 0x0610, 0x2610, 0x4610, 0x6610, 0x8610, 0xA610, 0xC610, 0xE610,
687 0x0710, 0x2710, 0x4710, 0x6710, 0x8710, 0xA710, 0xC710, 0xE710,
688 0x0018, 0x2018, 0x4018, 0x6018, 0x8018, 0xA018, 0xC018, 0xE018,
689 0x0118, 0x2118, 0x4118, 0x6118, 0x8118, 0xA118, 0xC118, 0xE118,
690 0x0218, 0x2218, 0x4218, 0x6218, 0x8218, 0xA218, 0xC218, 0xE218,
691 0x0318, 0x2318, 0x4318, 0x6318, 0x8318, 0xA318, 0xC318, 0xE318,
692 0x0418, 0x2418, 0x4418, 0x6418, 0x8418, 0xA418, 0xC418, 0xE418,
693 0x0518, 0x2518, 0x4518, 0x6518, 0x8518, 0xA518, 0xC518, 0xE518,
694 0x0618, 0x2618, 0x4618, 0x6618, 0x8618, 0xA618, 0xC618, 0xE618,
695 0x0718, 0x2718, 0x4718, 0x6718, 0x8718, 0xA718, 0xC718, 0xE718
696};
697#endif /* DISP_DEVICE_8BPP */
698
699static void tmd20qvga_disp_set_rect(int x, int y, int xres, int yres);
700static void tmd20qvga_disp_init(struct platform_device *pdev);
701static void tmd20qvga_disp_set_contrast(void);
702static void tmd20qvga_disp_set_display_area(word start_row, word end_row);
703static int tmd20qvga_disp_off(struct platform_device *pdev);
704static int tmd20qvga_disp_on(struct platform_device *pdev);
705static void tmd20qvga_set_revId(int);
706
707/* future use */
708void tmd20qvga_disp_clear_screen_area(word start_row, word end_row,
709 word start_column, word end_column);
710
711static void tmd20qvga_set_revId(int id)
712{
713
714 tmd20qvga_lcd_rev = id;
715
716 if (tmd20qvga_lcd_rev == 1)
717 tmd20qvga_panel_offset = 0x10;
718 else
719 tmd20qvga_panel_offset = 0;
720}
721
722static void tmd20qvga_disp_init(struct platform_device *pdev)
723{
724 struct msm_fb_data_type *mfd;
725
726 if (disp_initialized)
727 return;
728
729 mfd = platform_get_drvdata(pdev);
730
731 DISP_CMD_PORT = mfd->cmd_port;
732 DISP_DATA_PORT = mfd->data_port;
733
734#ifdef TMD20QVGA_LCD_18BPP
735 tmd20qvga_set_revId(2);
736#else
737 tmd20qvga_set_revId(1);
738#endif
739
740 disp_initialized = TRUE;
741 tmd20qvga_disp_set_contrast();
742 tmd20qvga_disp_set_display_area(0, QVGA_HEIGHT - 1);
743}
744
745static void tmd20qvga_disp_set_rect(int x, int y, int xres, int yres)
746{
747 if (!disp_initialized)
748 return;
749
750 DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1);
751
752 DISP_CMD_OUT(DISP_CMD_RAMWR);
753}
754
755static void tmd20qvga_disp_set_display_area(word start_row, word end_row)
756{
757 word start_driving = start_row;
758 word end_driving = end_row;
759
760 if (!disp_initialized)
761 return;
762
763 /* Range checking
764 */
765 if (end_driving >= QVGA_HEIGHT)
766 end_driving = QVGA_HEIGHT - 1;
767 if (start_driving > end_driving) {
768 /* Probably Backwards Switch */
769 start_driving = end_driving;
770 end_driving = start_row; /* Has not changed */
771 if (end_driving >= QVGA_HEIGHT)
772 end_driving = QVGA_HEIGHT - 1;
773 }
774
775 if ((start_driving == disp_area_start_row)
776 && (end_driving == disp_area_end_row))
777 return;
778
779 disp_area_start_row = start_driving;
780 disp_area_end_row = end_driving;
781
782 DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR,
783 DISP_VAL_IF(start_driving & 0x100,
784 DISP_BITMASK_SS18) |
785 DISP_VAL_IF(start_driving & 0x080,
786 DISP_BITMASK_SS17) |
787 DISP_VAL_IF(start_driving & 0x040,
788 DISP_BITMASK_SS16) |
789 DISP_VAL_IF(start_driving & 0x020,
790 DISP_BITMASK_SS15) |
791 DISP_VAL_IF(start_driving & 0x010,
792 DISP_BITMASK_SS14) |
793 DISP_VAL_IF(start_driving & 0x008,
794 DISP_BITMASK_SS13) |
795 DISP_VAL_IF(start_driving & 0x004,
796 DISP_BITMASK_SS12) |
797 DISP_VAL_IF(start_driving & 0x002,
798 DISP_BITMASK_SS11) |
799 DISP_VAL_IF(start_driving & 0x001, DISP_BITMASK_SS10));
800
801 DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR,
802 DISP_VAL_IF(end_driving & 0x100, DISP_BITMASK_SE18) |
803 DISP_VAL_IF(end_driving & 0x080, DISP_BITMASK_SE17) |
804 DISP_VAL_IF(end_driving & 0x040, DISP_BITMASK_SE16) |
805 DISP_VAL_IF(end_driving & 0x020, DISP_BITMASK_SE15) |
806 DISP_VAL_IF(end_driving & 0x010, DISP_BITMASK_SE14) |
807 DISP_VAL_IF(end_driving & 0x008, DISP_BITMASK_SE13) |
808 DISP_VAL_IF(end_driving & 0x004, DISP_BITMASK_SE12) |
809 DISP_VAL_IF(end_driving & 0x002, DISP_BITMASK_SE11) |
810 DISP_VAL_IF(end_driving & 0x001, DISP_BITMASK_SE10));
811}
812
813static int tmd20qvga_disp_off(struct platform_device *pdev)
814{
815 if (!disp_initialized)
816 tmd20qvga_disp_init(pdev);
817
818 if (display_on) {
819 if (tmd20qvga_lcd_rev == 2) {
820 DISP_WRITE_OUT(DISP_POFF_LN_SETTING_ADDR, 0x000A);
821 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xFFEE);
822 WAIT_MSEC(40);
823 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xF812);
824 WAIT_MSEC(40);
825 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xE811);
826 WAIT_MSEC(40);
827 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xC011);
828 WAIT_MSEC(40);
829 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x4011);
830 WAIT_MSEC(20);
831 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0010);
832
833 } else {
834 DISP_WRITE_OUT(DISP_POFF_LN_SETTING_ADDR, 0x000F);
835 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BFE);
836 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
837 WAIT_MSEC(40);
838 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BED);
839 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
840 WAIT_MSEC(40);
841 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x00CD);
842 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
843 WAIT_MSEC(20);
844 DISP_WRITE_OUT(DISP_START_OSCILLATION_ADDR, 0x0);
845 }
846
847 DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0004);
848 DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0000);
849
850 display_on = FALSE;
851 }
852
853 return 0;
854}
855
856static int tmd20qvga_disp_on(struct platform_device *pdev)
857{
858 if (!disp_initialized)
859 tmd20qvga_disp_init(pdev);
860
861 if (!display_on) {
862 /* Deep Stand-by -> Stand-by */
863 DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR);
864 WAIT_MSEC(1);
865 DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR);
866 WAIT_MSEC(1);
867 DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR);
868 WAIT_MSEC(1);
869
870 /* OFF -> Deep Stan-By -> Stand-by */
871 /* let's change the state from "Stand-by" to "Sleep" */
872 DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0005);
873 WAIT_MSEC(1);
874
875 /* Sleep -> Displaying */
876 DISP_WRITE_OUT(DISP_START_OSCILLATION_ADDR, 0x0001);
877 DISP_WRITE_OUT(DISP_DRIVER_OUTPUT_CTL_ADDR, 0x0127);
878 DISP_WRITE_OUT(DISP_LCD_DRIVING_SIG_ADDR, 0x200);
879 /* fast write mode */
880 DISP_WRITE_OUT(DISP_ENTRY_MODE_ADDR, 0x0130);
881 if (tmd20qvga_lcd_rev == 2)
882 DISP_WRITE_OUT(DISP_TMD_700_ADDR, 0x0003);
883 /* back porch = 14 + front porch = 2 --> 16 lines */
884 if (tmd20qvga_lcd_rev == 2) {
885#ifdef TMD20QVGA_LCD_18BPP
886 /* 256k color */
887 DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x0000);
888#else
889 /* 65k color */
890 DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x4000);
891#endif
892 DISP_WRITE_OUT(DISP_DISPLAY_CTL_2_ADDR, 0x0302);
893 } else {
894#ifdef TMD20QVGA_LCD_18BPP
895 /* 256k color */
896 DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x0004);
897#else
898 /* 65k color */
899 DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x4004);
900#endif
901 DISP_WRITE_OUT(DISP_DISPLAY_CTL_2_ADDR, 0x020E);
902 }
903 /* 16 bit one transfer */
904 if (tmd20qvga_lcd_rev == 2) {
905 DISP_WRITE_OUT(DISP_EXT_DISPLAY_CTL_1_ADDR, 0x0000);
906 DISP_WRITE_OUT(DISP_FRAME_CYCLE_CTL_ADDR, 0x0010);
907 DISP_WRITE_OUT(DISP_LTPS_CTL_1_ADDR, 0x0302);
908 DISP_WRITE_OUT(DISP_LTPS_CTL_2_ADDR, 0x0102);
909 DISP_WRITE_OUT(DISP_LTPS_CTL_3_ADDR, 0x0000);
910 DISP_WRITE_OUT(DISP_TMD_015_ADDR, 0x2000);
911
912 DISP_WRITE_OUT(DISP_AMP_SETTING_ADDR, 0x0000);
913 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403);
914 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0304);
915 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0403);
916 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303);
917 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0101);
918 DISP_WRITE_OUT(DISP_TMD_305_ADDR, 0);
919
920 DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR, 0x0000);
921 DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR, 0x013F);
922
923 DISP_WRITE_OUT(DISP_POWER_CTL_3_ADDR, 0x077D);
924
925 DISP_WRITE_OUT(DISP_POWER_CTL_4_ADDR, 0x0005);
926 DISP_WRITE_OUT(DISP_POWER_CTL_5_ADDR, 0x0000);
927 DISP_WRITE_OUT(DISP_POWER_CTL_6_ADDR, 0x0015);
928 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xC010);
929 WAIT_MSEC(1);
930
931 DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x0001);
932 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xFFFE);
933 WAIT_MSEC(60);
934 } else {
935 DISP_WRITE_OUT(DISP_EXT_DISPLAY_CTL_1_ADDR, 0x0001);
936 DISP_WRITE_OUT(DISP_FRAME_CYCLE_CTL_ADDR, 0x0010);
937 DISP_WRITE_OUT(DISP_LTPS_CTL_1_ADDR, 0x0301);
938 DISP_WRITE_OUT(DISP_LTPS_CTL_2_ADDR, 0x0001);
939 DISP_WRITE_OUT(DISP_LTPS_CTL_3_ADDR, 0x0000);
940 DISP_WRITE_OUT(DISP_AMP_SETTING_ADDR, 0x0000);
941 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0507);
942 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0405);
943 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0607);
944 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0502);
945 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0301);
946 DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR, 0x0000);
947 DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR, 0x013F);
948 DISP_WRITE_OUT(DISP_POWER_CTL_3_ADDR, 0x0795);
949
950 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0102);
951 WAIT_MSEC(1);
952
953 DISP_WRITE_OUT(DISP_POWER_CTL_4_ADDR, 0x0450);
954 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0103);
955 WAIT_MSEC(1);
956
957 DISP_WRITE_OUT(DISP_POWER_CTL_5_ADDR, 0x0008);
958 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0104);
959 WAIT_MSEC(1);
960
961 DISP_WRITE_OUT(DISP_POWER_CTL_6_ADDR, 0x0C00);
962 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0105);
963 WAIT_MSEC(1);
964
965 DISP_WRITE_OUT(DISP_POWER_CTL_7_ADDR, 0x0000);
966 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0106);
967 WAIT_MSEC(1);
968
969 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0801);
970 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
971 WAIT_MSEC(1);
972
973 DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x001F);
974 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0101);
975 WAIT_MSEC(60);
976
977 DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x009F);
978 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0101);
979 WAIT_MSEC(10);
980
981 DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_1_ADDR, 0x0010);
982 DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_2_ADDR, 0x00FF);
983 DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_1_ADDR, 0x0000);
984 DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_2_ADDR, 0x013F);
985 /* RAM starts at address 0x10 */
986 DISP_WRITE_OUT(DISP_RAM_ADDR_SET_1_ADDR, 0x0010);
987 DISP_WRITE_OUT(DISP_RAM_ADDR_SET_2_ADDR, 0x0000);
988
989 /* lcd controller uses internal clock, not ext. vsync */
990 DISP_CMD_OUT(DISP_CMD_RAMWR);
991
992 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0881);
993 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
994 WAIT_MSEC(40);
995
996 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BE1);
997 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
998 WAIT_MSEC(40);
999
1000 DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BFF);
1001 DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
1002 }
1003 display_on = TRUE;
1004 }
1005
1006 return 0;
1007}
1008
1009static void tmd20qvga_disp_set_contrast(void)
1010{
1011#if (defined(TMD20QVGA_LCD_18BPP))
1012
1013 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403);
1014 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0302);
1015 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0403);
1016 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303);
1017 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0F07);
1018
1019#else
1020 int newcontrast = 0x46;
1021
1022 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403);
1023
1024 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR,
1025 DISP_VAL_IF(newcontrast & 0x0001, DISP_BITMASK_PKP20) |
1026 DISP_VAL_IF(newcontrast & 0x0002, DISP_BITMASK_PKP21) |
1027 DISP_VAL_IF(newcontrast & 0x0004, DISP_BITMASK_PKP22) |
1028 DISP_VAL_IF(newcontrast & 0x0010, DISP_BITMASK_PKP30) |
1029 DISP_VAL_IF(newcontrast & 0x0020, DISP_BITMASK_PKP31) |
1030 DISP_VAL_IF(newcontrast & 0x0040, DISP_BITMASK_PKP32));
1031
1032 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR,
1033 DISP_VAL_IF(newcontrast & 0x0010, DISP_BITMASK_PKP40) |
1034 DISP_VAL_IF(newcontrast & 0x0020, DISP_BITMASK_PKP41) |
1035 DISP_VAL_IF(newcontrast & 0x0040, DISP_BITMASK_PKP42) |
1036 DISP_VAL_IF(newcontrast & 0x0001, DISP_BITMASK_PKP50) |
1037 DISP_VAL_IF(newcontrast & 0x0002, DISP_BITMASK_PKP51) |
1038 DISP_VAL_IF(newcontrast & 0x0004, DISP_BITMASK_PKP52));
1039
1040 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303);
1041 DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0F07);
1042
1043#endif /* defined(TMD20QVGA_LCD_18BPP) */
1044
1045} /* End disp_set_contrast */
1046
1047void tmd20qvga_disp_clear_screen_area
1048 (word start_row, word end_row, word start_column, word end_column) {
1049 int32 i;
1050
1051 /* Clear the display screen */
1052 DISP_SET_RECT(start_row, end_row, start_column, end_column);
1053 DISP_CMD_OUT(DISP_CMD_RAMWR);
1054 i = (end_row - start_row + 1) * (end_column - start_column + 1);
1055 for (; i > 0; i--)
1056 DISP_DATA_OUT_16TO18BPP(0x0);
1057}
1058
1059static int __init tmd20qvga_probe(struct platform_device *pdev)
1060{
1061 msm_fb_add_device(pdev);
1062
1063 return 0;
1064}
1065
1066static struct platform_driver this_driver = {
1067 .probe = tmd20qvga_probe,
1068 .driver = {
1069 .name = "ebi2_tmd_qvga",
1070 },
1071};
1072
1073static struct msm_fb_panel_data tmd20qvga_panel_data = {
1074 .on = tmd20qvga_disp_on,
1075 .off = tmd20qvga_disp_off,
1076 .set_rect = tmd20qvga_disp_set_rect,
1077};
1078
1079static struct platform_device this_device = {
1080 .name = "ebi2_tmd_qvga",
1081 .id = 0,
1082 .dev = {
1083 .platform_data = &tmd20qvga_panel_data,
1084 }
1085};
1086
1087static int __init tmd20qvga_init(void)
1088{
1089 int ret;
1090 struct msm_panel_info *pinfo;
1091
1092 ret = platform_driver_register(&this_driver);
1093 if (!ret) {
1094 pinfo = &tmd20qvga_panel_data.panel_info;
1095 pinfo->xres = 240;
1096 pinfo->yres = 320;
1097 pinfo->type = EBI2_PANEL;
1098 pinfo->pdest = DISPLAY_1;
1099 pinfo->wait_cycle = 0x808000;
1100#ifdef TMD20QVGA_LCD_18BPP
1101 pinfo->bpp = 18;
1102#else
1103 pinfo->bpp = 16;
1104#endif
1105 pinfo->fb_num = 2;
1106 pinfo->lcd.vsync_enable = TRUE;
1107 pinfo->lcd.refx100 = 6000;
1108 pinfo->lcd.v_back_porch = 16;
1109 pinfo->lcd.v_front_porch = 4;
1110 pinfo->lcd.v_pulse_width = 0;
1111 pinfo->lcd.hw_vsync_mode = FALSE;
1112 pinfo->lcd.vsync_notifier_period = 0;
1113
1114 ret = platform_device_register(&this_device);
1115 if (ret)
1116 platform_driver_unregister(&this_driver);
1117 }
1118
1119 return ret;
1120}
1121
1122module_init(tmd20qvga_init);
diff --git a/drivers/staging/msm/hdmi_sii9022.c b/drivers/staging/msm/hdmi_sii9022.c
new file mode 100644
index 000000000000..6b82b56a77b6
--- /dev/null
+++ b/drivers/staging/msm/hdmi_sii9022.c
@@ -0,0 +1,248 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/i2c.h>
19#include <linux/delay.h>
20#include "msm_fb.h"
21
22#define DEVICE_NAME "sii9022"
23#define SII9022_DEVICE_ID 0xB0
24
25struct sii9022_i2c_addr_data{
26 u8 addr;
27 u8 data;
28};
29
30/* video mode data */
31static u8 video_mode_data[] = {
32 0x00,
33 0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
34};
35
36static u8 avi_io_format[] = {
37 0x09,
38 0x00, 0x00,
39};
40
41/* power state */
42static struct sii9022_i2c_addr_data regset0[] = {
43 { 0x60, 0x04 },
44 { 0x63, 0x00 },
45 { 0x1E, 0x00 },
46};
47
48static u8 video_infoframe[] = {
49 0x0C,
50 0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
51 0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
52};
53
54/* configure audio */
55static struct sii9022_i2c_addr_data regset1[] = {
56 { 0x26, 0x90 },
57 { 0x20, 0x90 },
58 { 0x1F, 0x80 },
59 { 0x26, 0x80 },
60 { 0x24, 0x02 },
61 { 0x25, 0x0B },
62 { 0xBC, 0x02 },
63 { 0xBD, 0x24 },
64 { 0xBE, 0x02 },
65};
66
67/* enable audio */
68static u8 misc_infoframe[] = {
69 0xBF,
70 0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72};
73
74/* set HDMI, active */
75static struct sii9022_i2c_addr_data regset2[] = {
76 { 0x1A, 0x01 },
77 { 0x3D, 0x00 },
78};
79
80static int send_i2c_data(struct i2c_client *client,
81 struct sii9022_i2c_addr_data *regset,
82 int size)
83{
84 int i;
85 int rc = 0;
86
87 for (i = 0; i < size; i++) {
88 rc = i2c_smbus_write_byte_data(
89 client,
90 regset[i].addr, regset[i].data);
91 if (rc)
92 break;
93 }
94 return rc;
95}
96
97static int hdmi_sii_enable(struct i2c_client *client)
98{
99 int rc;
100 int retries = 10;
101 int count;
102
103 rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
104 if (rc)
105 goto enable_exit;
106
107 do {
108 msleep(1);
109 rc = i2c_smbus_read_byte_data(client, 0x1B);
110 } while ((rc != SII9022_DEVICE_ID) && retries--);
111
112 if (rc != SII9022_DEVICE_ID)
113 return -ENODEV;
114
115 rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
116 if (rc)
117 goto enable_exit;
118
119 count = ARRAY_SIZE(video_mode_data);
120 rc = i2c_master_send(client, video_mode_data, count);
121 if (rc != count) {
122 rc = -EIO;
123 goto enable_exit;
124 }
125
126 rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
127 if (rc)
128 goto enable_exit;
129 count = ARRAY_SIZE(avi_io_format);
130 rc = i2c_master_send(client, avi_io_format, count);
131 if (rc != count) {
132 rc = -EIO;
133 goto enable_exit;
134 }
135
136 rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
137 if (rc)
138 goto enable_exit;
139
140 count = ARRAY_SIZE(video_infoframe);
141 rc = i2c_master_send(client, video_infoframe, count);
142 if (rc != count) {
143 rc = -EIO;
144 goto enable_exit;
145 }
146
147 rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
148 if (rc)
149 goto enable_exit;
150
151 count = ARRAY_SIZE(misc_infoframe);
152 rc = i2c_master_send(client, misc_infoframe, count);
153 if (rc != count) {
154 rc = -EIO;
155 goto enable_exit;
156 }
157
158 rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
159 if (rc)
160 goto enable_exit;
161
162 return 0;
163enable_exit:
164 printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
165 return rc;
166}
167
168static const struct i2c_device_id hmdi_sii_id[] = {
169 { DEVICE_NAME, 0 },
170 { }
171};
172
173static int hdmi_sii_probe(struct i2c_client *client,
174 const struct i2c_device_id *id)
175{
176 int rc;
177
178 if (!i2c_check_functionality(client->adapter,
179 I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
180 return -ENODEV;
181 rc = hdmi_sii_enable(client);
182 return rc;
183}
184
185
186static struct i2c_driver hdmi_sii_i2c_driver = {
187 .driver = {
188 .name = DEVICE_NAME,
189 .owner = THIS_MODULE,
190 },
191 .probe = hdmi_sii_probe,
192 .remove = __exit_p(hdmi_sii_remove),
193 .id_table = hmdi_sii_id,
194};
195
196static int __init hdmi_sii_init(void)
197{
198 int ret;
199 struct msm_panel_info pinfo;
200
201 if (msm_fb_detect_client("hdmi_sii9022"))
202 return 0;
203
204 pinfo.xres = 1280;
205 pinfo.yres = 720;
206 pinfo.type = HDMI_PANEL;
207 pinfo.pdest = DISPLAY_1;
208 pinfo.wait_cycle = 0;
209 pinfo.bpp = 24;
210 pinfo.fb_num = 2;
211 pinfo.clk_rate = 74250000;
212
213 pinfo.lcdc.h_back_porch = 124;
214 pinfo.lcdc.h_front_porch = 110;
215 pinfo.lcdc.h_pulse_width = 136;
216 pinfo.lcdc.v_back_porch = 19;
217 pinfo.lcdc.v_front_porch = 5;
218 pinfo.lcdc.v_pulse_width = 6;
219 pinfo.lcdc.border_clr = 0;
220 pinfo.lcdc.underflow_clr = 0xff;
221 pinfo.lcdc.hsync_skew = 0;
222
223 ret = lcdc_device_register(&pinfo);
224 if (ret) {
225 printk(KERN_ERR "%s: failed to register device\n", __func__);
226 goto init_exit;
227 }
228
229 ret = i2c_add_driver(&hdmi_sii_i2c_driver);
230 if (ret)
231 printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
232
233init_exit:
234 return ret;
235}
236
237static void __exit hdmi_sii_exit(void)
238{
239 i2c_del_driver(&hdmi_sii_i2c_driver);
240}
241
242module_init(hdmi_sii_init);
243module_exit(hdmi_sii_exit);
244MODULE_LICENSE("GPL v2");
245MODULE_VERSION("0.1");
246MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
247MODULE_DESCRIPTION("SiI9022 HDMI driver");
248MODULE_ALIAS("platform:hdmi-sii9022");
diff --git a/drivers/staging/msm/lcdc.c b/drivers/staging/msm/lcdc.c
new file mode 100644
index 000000000000..735280ab72cb
--- /dev/null
+++ b/drivers/staging/msm/lcdc.c
@@ -0,0 +1,239 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/uaccess.h>
33#include <linux/clk.h>
34#include <linux/platform_device.h>
35#include <linux/pm_qos_params.h>
36
37#include "msm_fb.h"
38
39static int lcdc_probe(struct platform_device *pdev);
40static int lcdc_remove(struct platform_device *pdev);
41
42static int lcdc_off(struct platform_device *pdev);
43static int lcdc_on(struct platform_device *pdev);
44
45static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
46static int pdev_list_cnt;
47
48static struct clk *mdp_lcdc_pclk_clk;
49static struct clk *mdp_lcdc_pad_pclk_clk;
50
51int mdp_lcdc_pclk_clk_rate;
52int mdp_lcdc_pad_pclk_clk_rate;
53
54static struct platform_driver lcdc_driver = {
55 .probe = lcdc_probe,
56 .remove = lcdc_remove,
57 .suspend = NULL,
58 .resume = NULL,
59 .shutdown = NULL,
60 .driver = {
61 .name = "lcdc",
62 },
63};
64
65static struct lcdc_platform_data *lcdc_pdata;
66
67static int lcdc_off(struct platform_device *pdev)
68{
69 int ret = 0;
70
71 ret = panel_next_off(pdev);
72
73 clk_disable(mdp_lcdc_pclk_clk);
74 clk_disable(mdp_lcdc_pad_pclk_clk);
75
76 if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
77 lcdc_pdata->lcdc_power_save(0);
78
79 if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
80 ret = lcdc_pdata->lcdc_gpio_config(0);
81
82// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
83// PM_QOS_DEFAULT_VALUE);
84
85 return ret;
86}
87
88static int lcdc_on(struct platform_device *pdev)
89{
90 int ret = 0;
91 struct msm_fb_data_type *mfd;
92 unsigned long panel_pixclock_freq , pm_qos_freq;
93
94 mfd = platform_get_drvdata(pdev);
95 panel_pixclock_freq = mfd->fbi->var.pixclock;
96
97 if (panel_pixclock_freq > 58000000)
98 /* pm_qos_freq should be in Khz */
99 pm_qos_freq = panel_pixclock_freq / 1000 ;
100 else
101 pm_qos_freq = 58000;
102
103// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
104// pm_qos_freq);
105 mfd = platform_get_drvdata(pdev);
106
107 clk_enable(mdp_lcdc_pclk_clk);
108 clk_enable(mdp_lcdc_pad_pclk_clk);
109
110 if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
111 lcdc_pdata->lcdc_power_save(1);
112 if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
113 ret = lcdc_pdata->lcdc_gpio_config(1);
114
115 clk_set_rate(mdp_lcdc_pclk_clk, mfd->fbi->var.pixclock);
116 clk_set_rate(mdp_lcdc_pad_pclk_clk, mfd->fbi->var.pixclock);
117 mdp_lcdc_pclk_clk_rate = clk_get_rate(mdp_lcdc_pclk_clk);
118 mdp_lcdc_pad_pclk_clk_rate = clk_get_rate(mdp_lcdc_pad_pclk_clk);
119
120 ret = panel_next_on(pdev);
121 return ret;
122}
123
124static int lcdc_probe(struct platform_device *pdev)
125{
126 struct msm_fb_data_type *mfd;
127 struct fb_info *fbi;
128 struct platform_device *mdp_dev = NULL;
129 struct msm_fb_panel_data *pdata = NULL;
130 int rc;
131
132 if (pdev->id == 0) {
133 lcdc_pdata = pdev->dev.platform_data;
134 return 0;
135 }
136
137 mfd = platform_get_drvdata(pdev);
138
139 if (!mfd)
140 return -ENODEV;
141
142 if (mfd->key != MFD_KEY)
143 return -EINVAL;
144
145 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
146 return -ENOMEM;
147
148 mdp_dev = platform_device_alloc("mdp", pdev->id);
149 if (!mdp_dev)
150 return -ENOMEM;
151
152 /*
153 * link to the latest pdev
154 */
155 mfd->pdev = mdp_dev;
156 mfd->dest = DISPLAY_LCDC;
157
158 /*
159 * alloc panel device data
160 */
161 if (platform_device_add_data
162 (mdp_dev, pdev->dev.platform_data,
163 sizeof(struct msm_fb_panel_data))) {
164 printk(KERN_ERR "lcdc_probe: platform_device_add_data failed!\n");
165 platform_device_put(mdp_dev);
166 return -ENOMEM;
167 }
168 /*
169 * data chain
170 */
171 pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data;
172 pdata->on = lcdc_on;
173 pdata->off = lcdc_off;
174 pdata->next = pdev;
175
176 /*
177 * get/set panel specific fb info
178 */
179 mfd->panel_info = pdata->panel_info;
180 mfd->fb_imgType = MDP_RGB_565;
181
182 fbi = mfd->fbi;
183 fbi->var.pixclock = mfd->panel_info.clk_rate;
184 fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
185 fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
186 fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
187 fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch;
188 fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width;
189 fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width;
190
191 /*
192 * set driver data
193 */
194 platform_set_drvdata(mdp_dev, mfd);
195
196 /*
197 * register in mdp driver
198 */
199 rc = platform_device_add(mdp_dev);
200 if (rc)
201 goto lcdc_probe_err;
202
203 pdev_list[pdev_list_cnt++] = pdev;
204 return 0;
205
206lcdc_probe_err:
207 platform_device_put(mdp_dev);
208 return rc;
209}
210
211static int lcdc_remove(struct platform_device *pdev)
212{
213// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc");
214 return 0;
215}
216
217static int lcdc_register_driver(void)
218{
219 return platform_driver_register(&lcdc_driver);
220}
221
222static int __init lcdc_driver_init(void)
223{
224 mdp_lcdc_pclk_clk = clk_get(NULL, "mdp_lcdc_pclk_clk");
225 if (IS_ERR(mdp_lcdc_pclk_clk)) {
226 printk(KERN_ERR "error: can't get mdp_lcdc_pclk_clk!\n");
227 return IS_ERR(mdp_lcdc_pclk_clk);
228 }
229 mdp_lcdc_pad_pclk_clk = clk_get(NULL, "mdp_lcdc_pad_pclk_clk");
230 if (IS_ERR(mdp_lcdc_pad_pclk_clk)) {
231 printk(KERN_ERR "error: can't get mdp_lcdc_pad_pclk_clk!\n");
232 return IS_ERR(mdp_lcdc_pad_pclk_clk);
233 }
234// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
235// PM_QOS_DEFAULT_VALUE);
236 return lcdc_register_driver();
237}
238
239module_init(lcdc_driver_init);
diff --git a/drivers/staging/msm/lcdc_external.c b/drivers/staging/msm/lcdc_external.c
new file mode 100644
index 000000000000..45ff78527111
--- /dev/null
+++ b/drivers/staging/msm/lcdc_external.c
@@ -0,0 +1,54 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19
20static int __init lcdc_external_init(void)
21{
22 int ret;
23 struct msm_panel_info pinfo;
24
25 if (msm_fb_detect_client("lcdc_external"))
26 return 0;
27
28 pinfo.xres = 1280;
29 pinfo.yres = 720;
30 pinfo.type = LCDC_PANEL;
31 pinfo.pdest = DISPLAY_1;
32 pinfo.wait_cycle = 0;
33 pinfo.bpp = 24;
34 pinfo.fb_num = 2;
35 pinfo.clk_rate = 74250000;
36
37 pinfo.lcdc.h_back_porch = 124;
38 pinfo.lcdc.h_front_porch = 110;
39 pinfo.lcdc.h_pulse_width = 136;
40 pinfo.lcdc.v_back_porch = 19;
41 pinfo.lcdc.v_front_porch = 5;
42 pinfo.lcdc.v_pulse_width = 6;
43 pinfo.lcdc.border_clr = 0; /* blk */
44 pinfo.lcdc.underflow_clr = 0xff; /* blue */
45 pinfo.lcdc.hsync_skew = 0;
46
47 ret = lcdc_device_register(&pinfo);
48 if (ret)
49 printk(KERN_ERR "%s: failed to register device!\n", __func__);
50
51 return ret;
52}
53
54module_init(lcdc_external_init);
diff --git a/drivers/staging/msm/lcdc_gordon.c b/drivers/staging/msm/lcdc_gordon.c
new file mode 100644
index 000000000000..399ec8c791ec
--- /dev/null
+++ b/drivers/staging/msm/lcdc_gordon.c
@@ -0,0 +1,446 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/delay.h>
19#include <mach/gpio.h>
20#include "msm_fb.h"
21
22/* registers */
23#define GORDON_REG_NOP 0x00
24#define GORDON_REG_IMGCTL1 0x10
25#define GORDON_REG_IMGCTL2 0x11
26#define GORDON_REG_IMGSET1 0x12
27#define GORDON_REG_IMGSET2 0x13
28#define GORDON_REG_IVBP1 0x14
29#define GORDON_REG_IHBP1 0x15
30#define GORDON_REG_IVNUM1 0x16
31#define GORDON_REG_IHNUM1 0x17
32#define GORDON_REG_IVBP2 0x18
33#define GORDON_REG_IHBP2 0x19
34#define GORDON_REG_IVNUM2 0x1A
35#define GORDON_REG_IHNUM2 0x1B
36#define GORDON_REG_LCDIFCTL1 0x30
37#define GORDON_REG_VALTRAN 0x31
38#define GORDON_REG_AVCTL 0x33
39#define GORDON_REG_LCDIFCTL2 0x34
40#define GORDON_REG_LCDIFCTL3 0x35
41#define GORDON_REG_LCDIFSET1 0x36
42#define GORDON_REG_PCCTL 0x3C
43#define GORDON_REG_TPARAM1 0x40
44#define GORDON_REG_TLCDIF1 0x41
45#define GORDON_REG_TSSPB_ST1 0x42
46#define GORDON_REG_TSSPB_ED1 0x43
47#define GORDON_REG_TSCK_ST1 0x44
48#define GORDON_REG_TSCK_WD1 0x45
49#define GORDON_REG_TGSPB_VST1 0x46
50#define GORDON_REG_TGSPB_VED1 0x47
51#define GORDON_REG_TGSPB_CH1 0x48
52#define GORDON_REG_TGCK_ST1 0x49
53#define GORDON_REG_TGCK_ED1 0x4A
54#define GORDON_REG_TPCTL_ST1 0x4B
55#define GORDON_REG_TPCTL_ED1 0x4C
56#define GORDON_REG_TPCHG_ED1 0x4D
57#define GORDON_REG_TCOM_CH1 0x4E
58#define GORDON_REG_THBP1 0x4F
59#define GORDON_REG_TPHCTL1 0x50
60#define GORDON_REG_EVPH1 0x51
61#define GORDON_REG_EVPL1 0x52
62#define GORDON_REG_EVNH1 0x53
63#define GORDON_REG_EVNL1 0x54
64#define GORDON_REG_TBIAS1 0x55
65#define GORDON_REG_TPARAM2 0x56
66#define GORDON_REG_TLCDIF2 0x57
67#define GORDON_REG_TSSPB_ST2 0x58
68#define GORDON_REG_TSSPB_ED2 0x59
69#define GORDON_REG_TSCK_ST2 0x5A
70#define GORDON_REG_TSCK_WD2 0x5B
71#define GORDON_REG_TGSPB_VST2 0x5C
72#define GORDON_REG_TGSPB_VED2 0x5D
73#define GORDON_REG_TGSPB_CH2 0x5E
74#define GORDON_REG_TGCK_ST2 0x5F
75#define GORDON_REG_TGCK_ED2 0x60
76#define GORDON_REG_TPCTL_ST2 0x61
77#define GORDON_REG_TPCTL_ED2 0x62
78#define GORDON_REG_TPCHG_ED2 0x63
79#define GORDON_REG_TCOM_CH2 0x64
80#define GORDON_REG_THBP2 0x65
81#define GORDON_REG_TPHCTL2 0x66
82#define GORDON_REG_POWCTL 0x80
83
84static int lcdc_gordon_panel_off(struct platform_device *pdev);
85
86static int spi_cs;
87static int spi_sclk;
88static int spi_sdo;
89static int spi_sdi;
90static int spi_dac;
91static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
92 (1 << 6),
93 (1 << 5),
94 (1 << 4),
95 (1 << 3),
96 (1 << 2),
97 (1 << 1),
98 (1 << 0) /* LSB */
99};
100
101struct gordon_state_type{
102 boolean disp_initialized;
103 boolean display_on;
104 boolean disp_powered_up;
105};
106
107static struct gordon_state_type gordon_state = { 0 };
108static struct msm_panel_common_pdata *lcdc_gordon_pdata;
109
110static void serigo(uint16 reg, uint8 data)
111{
112 unsigned int tx_val = ((0x00FF & reg) << 8) | data;
113 unsigned char i, val = 0;
114
115 /* Enable the Chip Select */
116 gpio_set_value(spi_cs, 1);
117 udelay(33);
118
119 /* Transmit it in two parts, Higher Byte first, then Lower Byte */
120 val = (unsigned char)((tx_val & 0xFF00) >> 8);
121
122 /* Clock should be Low before entering ! */
123 for (i = 0; i < 8; i++) {
124 /* #1: Drive the Data (High or Low) */
125 if (val & bit_shift[i])
126 gpio_set_value(spi_sdi, 1);
127 else
128 gpio_set_value(spi_sdi, 0);
129
130 /* #2: Drive the Clk High and then Low */
131 udelay(33);
132 gpio_set_value(spi_sclk, 1);
133 udelay(33);
134 gpio_set_value(spi_sclk, 0);
135 }
136
137 /* Idle state of SDO (MOSI) is Low */
138 gpio_set_value(spi_sdi, 0);
139 /* ..then Lower Byte */
140 val = (uint8) (tx_val & 0x00FF);
141 /* Before we enter here the Clock should be Low ! */
142
143 for (i = 0; i < 8; i++) {
144 /* #1: Drive the Data (High or Low) */
145 if (val & bit_shift[i])
146 gpio_set_value(spi_sdi, 1);
147 else
148 gpio_set_value(spi_sdi, 0);
149
150 /* #2: Drive the Clk High and then Low */
151 udelay(33);
152
153 gpio_set_value(spi_sclk, 1);
154 udelay(33);
155 gpio_set_value(spi_sclk, 0);
156 }
157
158 /* Idle state of SDO (MOSI) is Low */
159 gpio_set_value(spi_sdi, 0);
160
161 /* Now Disable the Chip Select */
162 udelay(33);
163 gpio_set_value(spi_cs, 0);
164}
165
166static void spi_init(void)
167{
168 /* Setting the Default GPIO's */
169 spi_sclk = *(lcdc_gordon_pdata->gpio_num);
170 spi_cs = *(lcdc_gordon_pdata->gpio_num + 1);
171 spi_sdi = *(lcdc_gordon_pdata->gpio_num + 2);
172 spi_sdo = *(lcdc_gordon_pdata->gpio_num + 3);
173
174 /* Set the output so that we dont disturb the slave device */
175 gpio_set_value(spi_sclk, 0);
176 gpio_set_value(spi_sdi, 0);
177
178 /* Set the Chip Select De-asserted */
179 gpio_set_value(spi_cs, 0);
180
181}
182
183static void gordon_disp_powerup(void)
184{
185 if (!gordon_state.disp_powered_up && !gordon_state.display_on) {
186 /* Reset the hardware first */
187 /* Include DAC power up implementation here */
188 gordon_state.disp_powered_up = TRUE;
189 }
190}
191
192static void gordon_init(void)
193{
194 /* Image interface settings */
195 serigo(GORDON_REG_IMGCTL2, 0x00);
196 serigo(GORDON_REG_IMGSET1, 0x00);
197
198 /* Exchange the RGB signal for J510(Softbank mobile) */
199 serigo(GORDON_REG_IMGSET2, 0x12);
200 serigo(GORDON_REG_LCDIFSET1, 0x00);
201
202 /* Pre-charge settings */
203 serigo(GORDON_REG_PCCTL, 0x09);
204 serigo(GORDON_REG_LCDIFCTL2, 0x7B);
205
206 mdelay(1);
207}
208
209static void gordon_disp_on(void)
210{
211 if (gordon_state.disp_powered_up && !gordon_state.display_on) {
212 gordon_init();
213 mdelay(20);
214 /* gordon_dispmode setting */
215 serigo(GORDON_REG_TPARAM1, 0x30);
216 serigo(GORDON_REG_TLCDIF1, 0x00);
217 serigo(GORDON_REG_TSSPB_ST1, 0x8B);
218 serigo(GORDON_REG_TSSPB_ED1, 0x93);
219 serigo(GORDON_REG_TSCK_ST1, 0x88);
220 serigo(GORDON_REG_TSCK_WD1, 0x00);
221 serigo(GORDON_REG_TGSPB_VST1, 0x01);
222 serigo(GORDON_REG_TGSPB_VED1, 0x02);
223 serigo(GORDON_REG_TGSPB_CH1, 0x5E);
224 serigo(GORDON_REG_TGCK_ST1, 0x80);
225 serigo(GORDON_REG_TGCK_ED1, 0x3C);
226 serigo(GORDON_REG_TPCTL_ST1, 0x50);
227 serigo(GORDON_REG_TPCTL_ED1, 0x74);
228 serigo(GORDON_REG_TPCHG_ED1, 0x78);
229 serigo(GORDON_REG_TCOM_CH1, 0x50);
230 serigo(GORDON_REG_THBP1, 0x84);
231 serigo(GORDON_REG_TPHCTL1, 0x00);
232 serigo(GORDON_REG_EVPH1, 0x70);
233 serigo(GORDON_REG_EVPL1, 0x64);
234 serigo(GORDON_REG_EVNH1, 0x56);
235 serigo(GORDON_REG_EVNL1, 0x48);
236 serigo(GORDON_REG_TBIAS1, 0x88);
237
238 /* QVGA settings */
239 serigo(GORDON_REG_TPARAM2, 0x28);
240 serigo(GORDON_REG_TLCDIF2, 0x14);
241 serigo(GORDON_REG_TSSPB_ST2, 0x49);
242 serigo(GORDON_REG_TSSPB_ED2, 0x4B);
243 serigo(GORDON_REG_TSCK_ST2, 0x4A);
244 serigo(GORDON_REG_TSCK_WD2, 0x02);
245 serigo(GORDON_REG_TGSPB_VST2, 0x02);
246 serigo(GORDON_REG_TGSPB_VED2, 0x03);
247 serigo(GORDON_REG_TGSPB_CH2, 0x2F);
248 serigo(GORDON_REG_TGCK_ST2, 0x40);
249 serigo(GORDON_REG_TGCK_ED2, 0x1E);
250 serigo(GORDON_REG_TPCTL_ST2, 0x2C);
251 serigo(GORDON_REG_TPCTL_ED2, 0x3A);
252 serigo(GORDON_REG_TPCHG_ED2, 0x3C);
253 serigo(GORDON_REG_TCOM_CH2, 0x28);
254 serigo(GORDON_REG_THBP2, 0x4D);
255 serigo(GORDON_REG_TPHCTL2, 0x1A);
256
257 /* VGA settings */
258 serigo(GORDON_REG_IVBP1, 0x02);
259 serigo(GORDON_REG_IHBP1, 0x90);
260 serigo(GORDON_REG_IVNUM1, 0xA0);
261 serigo(GORDON_REG_IHNUM1, 0x78);
262
263 /* QVGA settings */
264 serigo(GORDON_REG_IVBP2, 0x02);
265 serigo(GORDON_REG_IHBP2, 0x48);
266 serigo(GORDON_REG_IVNUM2, 0x50);
267 serigo(GORDON_REG_IHNUM2, 0x3C);
268
269 /* Gordon Charge pump settings and ON */
270 serigo(GORDON_REG_POWCTL, 0x03);
271 mdelay(15);
272 serigo(GORDON_REG_POWCTL, 0x07);
273 mdelay(15);
274
275 serigo(GORDON_REG_POWCTL, 0x0F);
276 mdelay(15);
277
278 serigo(GORDON_REG_AVCTL, 0x03);
279 mdelay(15);
280
281 serigo(GORDON_REG_POWCTL, 0x1F);
282 mdelay(15);
283
284 serigo(GORDON_REG_POWCTL, 0x5F);
285 mdelay(15);
286
287 serigo(GORDON_REG_POWCTL, 0x7F);
288 mdelay(15);
289
290 serigo(GORDON_REG_LCDIFCTL1, 0x02);
291 mdelay(15);
292
293 serigo(GORDON_REG_IMGCTL1, 0x00);
294 mdelay(15);
295
296 serigo(GORDON_REG_LCDIFCTL3, 0x00);
297 mdelay(15);
298
299 serigo(GORDON_REG_VALTRAN, 0x01);
300 mdelay(15);
301
302 serigo(GORDON_REG_LCDIFCTL1, 0x03);
303 mdelay(1);
304 gordon_state.display_on = TRUE;
305 }
306}
307
308static int lcdc_gordon_panel_on(struct platform_device *pdev)
309{
310 if (!gordon_state.disp_initialized) {
311 /* Configure reset GPIO that drives DAC */
312 lcdc_gordon_pdata->panel_config_gpio(1);
313 spi_dac = *(lcdc_gordon_pdata->gpio_num + 4);
314 gpio_set_value(spi_dac, 0);
315 udelay(15);
316 gpio_set_value(spi_dac, 1);
317 spi_init(); /* LCD needs SPI */
318 gordon_disp_powerup();
319 gordon_disp_on();
320 gordon_state.disp_initialized = TRUE;
321 }
322 return 0;
323}
324
325static int lcdc_gordon_panel_off(struct platform_device *pdev)
326{
327 if (gordon_state.disp_powered_up && gordon_state.display_on) {
328 serigo(GORDON_REG_LCDIFCTL2, 0x7B);
329 serigo(GORDON_REG_VALTRAN, 0x01);
330 serigo(GORDON_REG_LCDIFCTL1, 0x02);
331 serigo(GORDON_REG_LCDIFCTL3, 0x01);
332 mdelay(20);
333 serigo(GORDON_REG_VALTRAN, 0x01);
334 serigo(GORDON_REG_IMGCTL1, 0x01);
335 serigo(GORDON_REG_LCDIFCTL1, 0x00);
336 mdelay(20);
337
338 serigo(GORDON_REG_POWCTL, 0x1F);
339 mdelay(40);
340
341 serigo(GORDON_REG_POWCTL, 0x07);
342 mdelay(40);
343
344 serigo(GORDON_REG_POWCTL, 0x03);
345 mdelay(40);
346
347 serigo(GORDON_REG_POWCTL, 0x00);
348 mdelay(40);
349 lcdc_gordon_pdata->panel_config_gpio(0);
350 gordon_state.display_on = FALSE;
351 gordon_state.disp_initialized = FALSE;
352 }
353 return 0;
354}
355
356static void lcdc_gordon_set_backlight(struct msm_fb_data_type *mfd)
357{
358 int bl_level = mfd->bl_level;
359
360 if (bl_level <= 1) {
361 /* keep back light OFF */
362 serigo(GORDON_REG_LCDIFCTL2, 0x0B);
363 udelay(15);
364 serigo(GORDON_REG_VALTRAN, 0x01);
365 } else {
366 /* keep back light ON */
367 serigo(GORDON_REG_LCDIFCTL2, 0x7B);
368 udelay(15);
369 serigo(GORDON_REG_VALTRAN, 0x01);
370 }
371}
372
373static int __init gordon_probe(struct platform_device *pdev)
374{
375 if (pdev->id == 0) {
376 lcdc_gordon_pdata = pdev->dev.platform_data;
377 return 0;
378 }
379 msm_fb_add_device(pdev);
380 return 0;
381}
382
383static struct platform_driver this_driver = {
384 .probe = gordon_probe,
385 .driver = {
386 .name = "lcdc_gordon_vga",
387 },
388};
389
390static struct msm_fb_panel_data gordon_panel_data = {
391 .on = lcdc_gordon_panel_on,
392 .off = lcdc_gordon_panel_off,
393 .set_backlight = lcdc_gordon_set_backlight,
394};
395
396static struct platform_device this_device = {
397 .name = "lcdc_gordon_vga",
398 .id = 1,
399 .dev = {
400 .platform_data = &gordon_panel_data,
401 }
402};
403
404static int __init lcdc_gordon_panel_init(void)
405{
406 int ret;
407 struct msm_panel_info *pinfo;
408
409#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
410 if (msm_fb_detect_client("lcdc_gordon_vga"))
411 return 0;
412#endif
413 ret = platform_driver_register(&this_driver);
414 if (ret)
415 return ret;
416
417 pinfo = &gordon_panel_data.panel_info;
418 pinfo->xres = 480;
419 pinfo->yres = 640;
420 pinfo->type = LCDC_PANEL;
421 pinfo->pdest = DISPLAY_1;
422 pinfo->wait_cycle = 0;
423 pinfo->bpp = 24;
424 pinfo->fb_num = 2;
425 pinfo->clk_rate = 24500000;
426 pinfo->bl_max = 4;
427 pinfo->bl_min = 1;
428
429 pinfo->lcdc.h_back_porch = 84;
430 pinfo->lcdc.h_front_porch = 33;
431 pinfo->lcdc.h_pulse_width = 60;
432 pinfo->lcdc.v_back_porch = 0;
433 pinfo->lcdc.v_front_porch = 2;
434 pinfo->lcdc.v_pulse_width = 2;
435 pinfo->lcdc.border_clr = 0; /* blk */
436 pinfo->lcdc.underflow_clr = 0xff; /* blue */
437 pinfo->lcdc.hsync_skew = 0;
438
439 ret = platform_device_register(&this_device);
440 if (ret)
441 platform_driver_unregister(&this_driver);
442
443 return ret;
444}
445
446module_init(lcdc_gordon_panel_init);
diff --git a/drivers/staging/msm/lcdc_grapefruit.c b/drivers/staging/msm/lcdc_grapefruit.c
new file mode 100644
index 000000000000..7284649ea0ae
--- /dev/null
+++ b/drivers/staging/msm/lcdc_grapefruit.c
@@ -0,0 +1,60 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19
20#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
21#include "mddihosti.h"
22#endif
23
24static int __init lcdc_grapefruit_init(void)
25{
26 int ret;
27 struct msm_panel_info pinfo;
28
29#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
30 if (msm_fb_detect_client("lcdc_grapefruit_vga"))
31 return 0;
32#endif
33
34 pinfo.xres = 1024;
35 pinfo.yres = 600;
36 pinfo.type = LCDC_PANEL;
37 pinfo.pdest = DISPLAY_1;
38 pinfo.wait_cycle = 0;
39 pinfo.bpp = 18;
40 pinfo.fb_num = 2;
41 pinfo.clk_rate = 40000000;
42
43 pinfo.lcdc.h_back_porch = 88;
44 pinfo.lcdc.h_front_porch = 40;
45 pinfo.lcdc.h_pulse_width = 128;
46 pinfo.lcdc.v_back_porch = 23;
47 pinfo.lcdc.v_front_porch = 1;
48 pinfo.lcdc.v_pulse_width = 4;
49 pinfo.lcdc.border_clr = 0; /* blk */
50 pinfo.lcdc.underflow_clr = 0xff; /* blue */
51 pinfo.lcdc.hsync_skew = 0;
52
53 ret = lcdc_device_register(&pinfo);
54 if (ret)
55 printk(KERN_ERR "%s: failed to register device!\n", __func__);
56
57 return ret;
58}
59
60module_init(lcdc_grapefruit_init);
diff --git a/drivers/staging/msm/lcdc_panel.c b/drivers/staging/msm/lcdc_panel.c
new file mode 100644
index 000000000000..b40974e1f27c
--- /dev/null
+++ b/drivers/staging/msm/lcdc_panel.c
@@ -0,0 +1,88 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19
20static int lcdc_panel_on(struct platform_device *pdev)
21{
22 return 0;
23}
24
25static int lcdc_panel_off(struct platform_device *pdev)
26{
27 return 0;
28}
29
30static int __init lcdc_panel_probe(struct platform_device *pdev)
31{
32 msm_fb_add_device(pdev);
33
34 return 0;
35}
36
37static struct platform_driver this_driver = {
38 .probe = lcdc_panel_probe,
39 .driver = {
40 .name = "lcdc_panel",
41 },
42};
43
44static struct msm_fb_panel_data lcdc_panel_data = {
45 .on = lcdc_panel_on,
46 .off = lcdc_panel_off,
47};
48
49static int lcdc_dev_id;
50
51int lcdc_device_register(struct msm_panel_info *pinfo)
52{
53 struct platform_device *pdev = NULL;
54 int ret;
55
56 pdev = platform_device_alloc("lcdc_panel", ++lcdc_dev_id);
57 if (!pdev)
58 return -ENOMEM;
59
60 lcdc_panel_data.panel_info = *pinfo;
61 ret = platform_device_add_data(pdev, &lcdc_panel_data,
62 sizeof(lcdc_panel_data));
63 if (ret) {
64 printk(KERN_ERR
65 "%s: platform_device_add_data failed!\n", __func__);
66 goto err_device_put;
67 }
68
69 ret = platform_device_add(pdev);
70 if (ret) {
71 printk(KERN_ERR
72 "%s: platform_device_register failed!\n", __func__);
73 goto err_device_put;
74 }
75
76 return 0;
77
78err_device_put:
79 platform_device_put(pdev);
80 return ret;
81}
82
83static int __init lcdc_panel_init(void)
84{
85 return platform_driver_register(&this_driver);
86}
87
88module_init(lcdc_panel_init);
diff --git a/drivers/staging/msm/lcdc_prism.c b/drivers/staging/msm/lcdc_prism.c
new file mode 100644
index 000000000000..d102c98447c1
--- /dev/null
+++ b/drivers/staging/msm/lcdc_prism.c
@@ -0,0 +1,64 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19
20#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
21#include "mddihosti.h"
22#endif
23
24static int __init lcdc_prism_init(void)
25{
26 int ret;
27 struct msm_panel_info pinfo;
28
29#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
30 ret = msm_fb_detect_client("lcdc_prism_wvga");
31 if (ret == -ENODEV)
32 return 0;
33
34 if (ret && (mddi_get_client_id() != 0))
35 return 0;
36#endif
37
38 pinfo.xres = 800;
39 pinfo.yres = 480;
40 pinfo.type = LCDC_PANEL;
41 pinfo.pdest = DISPLAY_1;
42 pinfo.wait_cycle = 0;
43 pinfo.bpp = 24;
44 pinfo.fb_num = 2;
45 pinfo.clk_rate = 38460000;
46
47 pinfo.lcdc.h_back_porch = 21;
48 pinfo.lcdc.h_front_porch = 81;
49 pinfo.lcdc.h_pulse_width = 60;
50 pinfo.lcdc.v_back_porch = 18;
51 pinfo.lcdc.v_front_porch = 27;
52 pinfo.lcdc.v_pulse_width = 2;
53 pinfo.lcdc.border_clr = 0; /* blk */
54 pinfo.lcdc.underflow_clr = 0xff; /* blue */
55 pinfo.lcdc.hsync_skew = 0;
56
57 ret = lcdc_device_register(&pinfo);
58 if (ret)
59 printk(KERN_ERR "%s: failed to register device!\n", __func__);
60
61 return ret;
62}
63
64module_init(lcdc_prism_init);
diff --git a/drivers/staging/msm/lcdc_sharp_wvga_pt.c b/drivers/staging/msm/lcdc_sharp_wvga_pt.c
new file mode 100644
index 000000000000..1f08cf9bc217
--- /dev/null
+++ b/drivers/staging/msm/lcdc_sharp_wvga_pt.c
@@ -0,0 +1,290 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/delay.h>
19#ifdef CONFIG_ARCH_MSM7X30
20#include <linux/mfd/pmic8058.h>
21#endif
22#include <mach/gpio.h>
23#include "msm_fb.h"
24
25static int lcdc_sharp_panel_off(struct platform_device *pdev);
26
27static int spi_cs;
28static int spi_sclk;
29static int spi_mosi;
30static int spi_miso;
31static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
32 (1 << 6),
33 (1 << 5),
34 (1 << 4),
35 (1 << 3),
36 (1 << 2),
37 (1 << 1),
38 (1 << 0) /* LSB */
39};
40
41struct sharp_state_type {
42 boolean disp_initialized;
43 boolean display_on;
44 boolean disp_powered_up;
45};
46
47struct sharp_spi_data {
48 u8 addr;
49 u8 data;
50};
51
52static struct sharp_spi_data init_sequence[] = {
53 { 15, 0x01 },
54 { 5, 0x01 },
55 { 7, 0x10 },
56 { 9, 0x1E },
57 { 10, 0x04 },
58 { 17, 0xFF },
59 { 21, 0x8A },
60 { 22, 0x00 },
61 { 23, 0x82 },
62 { 24, 0x24 },
63 { 25, 0x22 },
64 { 26, 0x6D },
65 { 27, 0xEB },
66 { 28, 0xB9 },
67 { 29, 0x3A },
68 { 49, 0x1A },
69 { 50, 0x16 },
70 { 51, 0x05 },
71 { 55, 0x7F },
72 { 56, 0x15 },
73 { 57, 0x7B },
74 { 60, 0x05 },
75 { 61, 0x0C },
76 { 62, 0x80 },
77 { 63, 0x00 },
78 { 92, 0x90 },
79 { 97, 0x01 },
80 { 98, 0xFF },
81 { 113, 0x11 },
82 { 114, 0x02 },
83 { 115, 0x08 },
84 { 123, 0xAB },
85 { 124, 0x04 },
86 { 6, 0x02 },
87 { 133, 0x00 },
88 { 134, 0xFE },
89 { 135, 0x22 },
90 { 136, 0x0B },
91 { 137, 0xFF },
92 { 138, 0x0F },
93 { 139, 0x00 },
94 { 140, 0xFE },
95 { 141, 0x22 },
96 { 142, 0x0B },
97 { 143, 0xFF },
98 { 144, 0x0F },
99 { 145, 0x00 },
100 { 146, 0xFE },
101 { 147, 0x22 },
102 { 148, 0x0B },
103 { 149, 0xFF },
104 { 150, 0x0F },
105 { 202, 0x30 },
106 { 30, 0x01 },
107 { 4, 0x01 },
108 { 31, 0x41 },
109};
110
111static struct sharp_state_type sharp_state = { 0 };
112static struct msm_panel_common_pdata *lcdc_sharp_pdata;
113
114static void sharp_spi_write_byte(u8 val)
115{
116 int i;
117
118 /* Clock should be Low before entering */
119 for (i = 0; i < 8; i++) {
120 /* #1: Drive the Data (High or Low) */
121 if (val & bit_shift[i])
122 gpio_set_value(spi_mosi, 1);
123 else
124 gpio_set_value(spi_mosi, 0);
125
126 /* #2: Drive the Clk High and then Low */
127 gpio_set_value(spi_sclk, 1);
128 gpio_set_value(spi_sclk, 0);
129 }
130}
131
132static void serigo(u8 reg, u8 data)
133{
134 /* Enable the Chip Select - low */
135 gpio_set_value(spi_cs, 0);
136 udelay(1);
137
138 /* Transmit register address first, then data */
139 sharp_spi_write_byte(reg);
140
141 /* Idle state of MOSI is Low */
142 gpio_set_value(spi_mosi, 0);
143 udelay(1);
144 sharp_spi_write_byte(data);
145
146 gpio_set_value(spi_mosi, 0);
147 gpio_set_value(spi_cs, 1);
148}
149
150static void sharp_spi_init(void)
151{
152 spi_sclk = *(lcdc_sharp_pdata->gpio_num);
153 spi_cs = *(lcdc_sharp_pdata->gpio_num + 1);
154 spi_mosi = *(lcdc_sharp_pdata->gpio_num + 2);
155 spi_miso = *(lcdc_sharp_pdata->gpio_num + 3);
156
157 /* Set the output so that we don't disturb the slave device */
158 gpio_set_value(spi_sclk, 0);
159 gpio_set_value(spi_mosi, 0);
160
161 /* Set the Chip Select deasserted (active low) */
162 gpio_set_value(spi_cs, 1);
163}
164
165static void sharp_disp_powerup(void)
166{
167 if (!sharp_state.disp_powered_up && !sharp_state.display_on)
168 sharp_state.disp_powered_up = TRUE;
169}
170
171static void sharp_disp_on(void)
172{
173 int i;
174
175 if (sharp_state.disp_powered_up && !sharp_state.display_on) {
176 for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
177 serigo(init_sequence[i].addr,
178 init_sequence[i].data);
179 }
180 mdelay(10);
181 serigo(31, 0xC1);
182 mdelay(10);
183 serigo(31, 0xD9);
184 serigo(31, 0xDF);
185
186 sharp_state.display_on = TRUE;
187 }
188}
189
190static int lcdc_sharp_panel_on(struct platform_device *pdev)
191{
192 if (!sharp_state.disp_initialized) {
193 lcdc_sharp_pdata->panel_config_gpio(1);
194 sharp_spi_init();
195 sharp_disp_powerup();
196 sharp_disp_on();
197 sharp_state.disp_initialized = TRUE;
198 }
199 return 0;
200}
201
202static int lcdc_sharp_panel_off(struct platform_device *pdev)
203{
204 if (sharp_state.disp_powered_up && sharp_state.display_on) {
205 serigo(4, 0x00);
206 mdelay(40);
207 serigo(31, 0xC1);
208 mdelay(40);
209 serigo(31, 0x00);
210 mdelay(100);
211 sharp_state.display_on = FALSE;
212 sharp_state.disp_initialized = FALSE;
213 }
214 return 0;
215}
216
217static int __init sharp_probe(struct platform_device *pdev)
218{
219 if (pdev->id == 0) {
220 lcdc_sharp_pdata = pdev->dev.platform_data;
221 return 0;
222 }
223 msm_fb_add_device(pdev);
224 return 0;
225}
226
227static struct platform_driver this_driver = {
228 .probe = sharp_probe,
229 .driver = {
230 .name = "lcdc_sharp_wvga",
231 },
232};
233
234static struct msm_fb_panel_data sharp_panel_data = {
235 .on = lcdc_sharp_panel_on,
236 .off = lcdc_sharp_panel_off,
237};
238
239static struct platform_device this_device = {
240 .name = "lcdc_sharp_wvga",
241 .id = 1,
242 .dev = {
243 .platform_data = &sharp_panel_data,
244 }
245};
246
247static int __init lcdc_sharp_panel_init(void)
248{
249 int ret;
250 struct msm_panel_info *pinfo;
251
252#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
253 if (msm_fb_detect_client("lcdc_sharp_wvga_pt"))
254 return 0;
255#endif
256
257 ret = platform_driver_register(&this_driver);
258 if (ret)
259 return ret;
260
261 pinfo = &sharp_panel_data.panel_info;
262 pinfo->xres = 480;
263 pinfo->yres = 800;
264 pinfo->type = LCDC_PANEL;
265 pinfo->pdest = DISPLAY_1;
266 pinfo->wait_cycle = 0;
267 pinfo->bpp = 18;
268 pinfo->fb_num = 2;
269 pinfo->clk_rate = 24500000;
270 pinfo->bl_max = 4;
271 pinfo->bl_min = 1;
272
273 pinfo->lcdc.h_back_porch = 20;
274 pinfo->lcdc.h_front_porch = 10;
275 pinfo->lcdc.h_pulse_width = 10;
276 pinfo->lcdc.v_back_porch = 2;
277 pinfo->lcdc.v_front_porch = 2;
278 pinfo->lcdc.v_pulse_width = 2;
279 pinfo->lcdc.border_clr = 0;
280 pinfo->lcdc.underflow_clr = 0xff;
281 pinfo->lcdc.hsync_skew = 0;
282
283 ret = platform_device_register(&this_device);
284 if (ret)
285 platform_driver_unregister(&this_driver);
286
287 return ret;
288}
289
290module_init(lcdc_sharp_panel_init);
diff --git a/drivers/staging/msm/lcdc_st15.c b/drivers/staging/msm/lcdc_st15.c
new file mode 100644
index 000000000000..fed8278eb153
--- /dev/null
+++ b/drivers/staging/msm/lcdc_st15.c
@@ -0,0 +1,237 @@
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/i2c.h>
19#include <linux/delay.h>
20#include "msm_fb.h"
21
22#define DEVICE_NAME "sii9022"
23#define SII9022_DEVICE_ID 0xB0
24
25struct sii9022_i2c_addr_data{
26 u8 addr;
27 u8 data;
28};
29
30/* video mode data */
31static u8 video_mode_data[] = {
32 0x00,
33 0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
34};
35
36static u8 avi_io_format[] = {
37 0x09,
38 0x00, 0x00,
39};
40
41/* power state */
42static struct sii9022_i2c_addr_data regset0[] = {
43 { 0x60, 0x04 },
44 { 0x63, 0x00 },
45 { 0x1E, 0x00 },
46};
47
48static u8 video_infoframe[] = {
49 0x0C,
50 0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
51 0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
52};
53
54/* configure audio */
55static struct sii9022_i2c_addr_data regset1[] = {
56 { 0x26, 0x90 },
57 { 0x20, 0x90 },
58 { 0x1F, 0x80 },
59 { 0x26, 0x80 },
60 { 0x24, 0x02 },
61 { 0x25, 0x0B },
62 { 0xBC, 0x02 },
63 { 0xBD, 0x24 },
64 { 0xBE, 0x02 },
65};
66
67/* enable audio */
68static u8 misc_infoframe[] = {
69 0xBF,
70 0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72};
73
74/* set HDMI, active */
75static struct sii9022_i2c_addr_data regset2[] = {
76 { 0x1A, 0x01 },
77 { 0x3D, 0x00 },
78};
79
80static int send_i2c_data(struct i2c_client *client,
81 struct sii9022_i2c_addr_data *regset,
82 int size)
83{
84 int i;
85 int rc = 0;
86
87 for (i = 0; i < size; i++) {
88 rc = i2c_smbus_write_byte_data(
89 client,
90 regset[i].addr, regset[i].data);
91 if (rc)
92 break;
93 }
94 return rc;
95}
96
97static int hdmi_sii_enable(struct i2c_client *client)
98{
99 int rc;
100 int retries = 10;
101 int count;
102
103 rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
104 if (rc)
105 goto enable_exit;
106
107 do {
108 msleep(1);
109 rc = i2c_smbus_read_byte_data(client, 0x1B);
110 } while ((rc != SII9022_DEVICE_ID) && retries--);
111
112 if (rc != SII9022_DEVICE_ID)
113 return -ENODEV;
114
115 rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
116 if (rc)
117 goto enable_exit;
118
119 count = ARRAY_SIZE(video_mode_data);
120 rc = i2c_master_send(client, video_mode_data, count);
121 if (rc != count) {
122 rc = -EIO;
123 goto enable_exit;
124 }
125
126 rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
127 if (rc)
128 goto enable_exit;
129 count = ARRAY_SIZE(avi_io_format);
130 rc = i2c_master_send(client, avi_io_format, count);
131 if (rc != count) {
132 rc = -EIO;
133 goto enable_exit;
134 }
135
136 rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
137 if (rc)
138 goto enable_exit;
139
140 count = ARRAY_SIZE(video_infoframe);
141 rc = i2c_master_send(client, video_infoframe, count);
142 if (rc != count) {
143 rc = -EIO;
144 goto enable_exit;
145 }
146
147 rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
148 if (rc)
149 goto enable_exit;
150
151 count = ARRAY_SIZE(misc_infoframe);
152 rc = i2c_master_send(client, misc_infoframe, count);
153 if (rc != count) {
154 rc = -EIO;
155 goto enable_exit;
156 }
157
158 rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
159 if (rc)
160 goto enable_exit;
161
162 return 0;
163enable_exit:
164 printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
165 return rc;
166}
167
168static const struct i2c_device_id hmdi_sii_id[] = {
169 { DEVICE_NAME, 0 },
170 { }
171};
172
173static int hdmi_sii_probe(struct i2c_client *client,
174 const struct i2c_device_id *id)
175{
176 int rc;
177
178 if (!i2c_check_functionality(client->adapter,
179 I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
180 return -ENODEV;
181 rc = hdmi_sii_enable(client);
182 return rc;
183}
184
185
186static struct i2c_driver hdmi_sii_i2c_driver = {
187 .driver = {
188 .name = DEVICE_NAME,
189 .owner = THIS_MODULE,
190 },
191 .probe = hdmi_sii_probe,
192 .remove = __exit_p(hdmi_sii_remove),
193 .id_table = hmdi_sii_id,
194};
195
196static int __init lcdc_st15_init(void)
197{
198 int ret;
199 struct msm_panel_info pinfo;
200
201 if (msm_fb_detect_client("lcdc_st15"))
202 return 0;
203
204 pinfo.xres = 1366;
205 pinfo.yres = 768;
206 pinfo.type = LCDC_PANEL;
207 pinfo.pdest = DISPLAY_1;
208 pinfo.wait_cycle = 0;
209 pinfo.bpp = 24;
210 pinfo.fb_num = 2;
211 pinfo.clk_rate = 74250000;
212
213 pinfo.lcdc.h_back_porch = 120;
214 pinfo.lcdc.h_front_porch = 20;
215 pinfo.lcdc.h_pulse_width = 40;
216 pinfo.lcdc.v_back_porch = 25;
217 pinfo.lcdc.v_front_porch = 1;
218 pinfo.lcdc.v_pulse_width = 7;
219 pinfo.lcdc.border_clr = 0; /* blk */
220 pinfo.lcdc.underflow_clr = 0xff; /* blue */
221 pinfo.lcdc.hsync_skew = 0;
222
223 ret = lcdc_device_register(&pinfo);
224 if (ret) {
225 printk(KERN_ERR "%s: failed to register device!\n", __func__);
226 goto init_exit;
227 }
228
229 ret = i2c_add_driver(&hdmi_sii_i2c_driver);
230 if (ret)
231 printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
232
233init_exit:
234 return ret;
235}
236
237module_init(lcdc_st15_init);
diff --git a/drivers/staging/msm/lcdc_st1_wxga.c b/drivers/staging/msm/lcdc_st1_wxga.c
new file mode 100644
index 000000000000..73760019cf2e
--- /dev/null
+++ b/drivers/staging/msm/lcdc_st1_wxga.c
@@ -0,0 +1,54 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19
20static int __init lcdc_st1_wxga_init(void)
21{
22 int ret;
23 struct msm_panel_info pinfo;
24
25 if (msm_fb_detect_client("lcdc_st1_wxga"))
26 return 0;
27
28 pinfo.xres = 1280;
29 pinfo.yres = 720;
30 pinfo.type = LCDC_PANEL;
31 pinfo.pdest = DISPLAY_1;
32 pinfo.wait_cycle = 0;
33 pinfo.bpp = 18;
34 pinfo.fb_num = 2;
35 pinfo.clk_rate = 74250000;
36
37 pinfo.lcdc.h_back_porch = 124;
38 pinfo.lcdc.h_front_porch = 110;
39 pinfo.lcdc.h_pulse_width = 136;
40 pinfo.lcdc.v_back_porch = 19;
41 pinfo.lcdc.v_front_porch = 5;
42 pinfo.lcdc.v_pulse_width = 6;
43 pinfo.lcdc.border_clr = 0; /* blk */
44 pinfo.lcdc.underflow_clr = 0xff; /* blue */
45 pinfo.lcdc.hsync_skew = 0;
46
47 ret = lcdc_device_register(&pinfo);
48 if (ret)
49 printk(KERN_ERR "%s: failed to register device!\n", __func__);
50
51 return ret;
52}
53
54module_init(lcdc_st1_wxga_init);
diff --git a/drivers/staging/msm/lcdc_toshiba_wvga_pt.c b/drivers/staging/msm/lcdc_toshiba_wvga_pt.c
new file mode 100644
index 000000000000..864d7c18913d
--- /dev/null
+++ b/drivers/staging/msm/lcdc_toshiba_wvga_pt.c
@@ -0,0 +1,374 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/delay.h>
19#include <linux/module.h>
20#include <mach/gpio.h>
21#include <mach/pmic.h>
22#include "msm_fb.h"
23
24#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
25#include "mddihosti.h"
26#endif
27
28static int spi_cs;
29static int spi_sclk;
30static int spi_mosi;
31static int spi_miso;
32
33struct toshiba_state_type{
34 boolean disp_initialized;
35 boolean display_on;
36 boolean disp_powered_up;
37};
38
39static struct toshiba_state_type toshiba_state = { 0 };
40static struct msm_panel_common_pdata *lcdc_toshiba_pdata;
41
42static void toshiba_spi_write_byte(char dc, uint8 data)
43{
44 uint32 bit;
45 int bnum;
46
47 gpio_set_value(spi_sclk, 0); /* clk low */
48 /* dc: 0 for command, 1 for parameter */
49 gpio_set_value(spi_mosi, dc);
50 udelay(1); /* at least 20 ns */
51 gpio_set_value(spi_sclk, 1); /* clk high */
52 udelay(1); /* at least 20 ns */
53 bnum = 8; /* 8 data bits */
54 bit = 0x80;
55 while (bnum) {
56 gpio_set_value(spi_sclk, 0); /* clk low */
57 if (data & bit)
58 gpio_set_value(spi_mosi, 1);
59 else
60 gpio_set_value(spi_mosi, 0);
61 udelay(1);
62 gpio_set_value(spi_sclk, 1); /* clk high */
63 udelay(1);
64 bit >>= 1;
65 bnum--;
66 }
67}
68
69static void toshiba_spi_write(char cmd, uint32 data, int num)
70{
71 char *bp;
72
73 gpio_set_value(spi_cs, 1); /* cs high */
74
75 /* command byte first */
76 toshiba_spi_write_byte(0, cmd);
77
78 /* followed by parameter bytes */
79 if (num) {
80 bp = (char *)&data;;
81 bp += (num - 1);
82 while (num) {
83 toshiba_spi_write_byte(1, *bp);
84 num--;
85 bp--;
86 }
87 }
88
89 gpio_set_value(spi_cs, 0); /* cs low */
90 udelay(1);
91}
92
93void toshiba_spi_read_bytes(char cmd, uint32 *data, int num)
94{
95 uint32 dbit, bits;
96 int bnum;
97
98 gpio_set_value(spi_cs, 1); /* cs high */
99
100 /* command byte first */
101 toshiba_spi_write_byte(0, cmd);
102
103 if (num > 1) {
104 /* extra dc bit */
105 gpio_set_value(spi_sclk, 0); /* clk low */
106 udelay(1);
107 dbit = gpio_get_value(spi_miso);/* dc bit */
108 udelay(1);
109 gpio_set_value(spi_sclk, 1); /* clk high */
110 }
111
112 /* followed by data bytes */
113 bnum = num * 8; /* number of bits */
114 bits = 0;
115 while (bnum) {
116 bits <<= 1;
117 gpio_set_value(spi_sclk, 0); /* clk low */
118 udelay(1);
119 dbit = gpio_get_value(spi_miso);
120 udelay(1);
121 gpio_set_value(spi_sclk, 1); /* clk high */
122 bits |= dbit;
123 bnum--;
124 }
125
126 *data = bits;
127
128 udelay(1);
129 gpio_set_value(spi_cs, 0); /* cs low */
130 udelay(1);
131}
132
133static void spi_pin_assign(void)
134{
135 /* Setting the Default GPIO's */
136 spi_sclk = *(lcdc_toshiba_pdata->gpio_num);
137 spi_cs = *(lcdc_toshiba_pdata->gpio_num + 1);
138 spi_mosi = *(lcdc_toshiba_pdata->gpio_num + 2);
139 spi_miso = *(lcdc_toshiba_pdata->gpio_num + 3);
140}
141
142static void toshiba_disp_powerup(void)
143{
144 if (!toshiba_state.disp_powered_up && !toshiba_state.display_on) {
145 /* Reset the hardware first */
146 /* Include DAC power up implementation here */
147 toshiba_state.disp_powered_up = TRUE;
148 }
149}
150
151static void toshiba_disp_on(void)
152{
153 uint32 data;
154
155 gpio_set_value(spi_cs, 0); /* low */
156 gpio_set_value(spi_sclk, 1); /* high */
157 gpio_set_value(spi_mosi, 0);
158 gpio_set_value(spi_miso, 0);
159
160 if (toshiba_state.disp_powered_up && !toshiba_state.display_on) {
161 toshiba_spi_write(0, 0, 0);
162 mdelay(7);
163 toshiba_spi_write(0, 0, 0);
164 mdelay(7);
165 toshiba_spi_write(0, 0, 0);
166 mdelay(7);
167 toshiba_spi_write(0xba, 0x11, 1);
168 toshiba_spi_write(0x36, 0x00, 1);
169 mdelay(1);
170 toshiba_spi_write(0x3a, 0x60, 1);
171 toshiba_spi_write(0xb1, 0x5d, 1);
172 mdelay(1);
173 toshiba_spi_write(0xb2, 0x33, 1);
174 toshiba_spi_write(0xb3, 0x22, 1);
175 mdelay(1);
176 toshiba_spi_write(0xb4, 0x02, 1);
177 toshiba_spi_write(0xb5, 0x1e, 1); /* vcs -- adjust brightness */
178 mdelay(1);
179 toshiba_spi_write(0xb6, 0x27, 1);
180 toshiba_spi_write(0xb7, 0x03, 1);
181 mdelay(1);
182 toshiba_spi_write(0xb9, 0x24, 1);
183 toshiba_spi_write(0xbd, 0xa1, 1);
184 mdelay(1);
185 toshiba_spi_write(0xbb, 0x00, 1);
186 toshiba_spi_write(0xbf, 0x01, 1);
187 mdelay(1);
188 toshiba_spi_write(0xbe, 0x00, 1);
189 toshiba_spi_write(0xc0, 0x11, 1);
190 mdelay(1);
191 toshiba_spi_write(0xc1, 0x11, 1);
192 toshiba_spi_write(0xc2, 0x11, 1);
193 mdelay(1);
194 toshiba_spi_write(0xc3, 0x3232, 2);
195 mdelay(1);
196 toshiba_spi_write(0xc4, 0x3232, 2);
197 mdelay(1);
198 toshiba_spi_write(0xc5, 0x3232, 2);
199 mdelay(1);
200 toshiba_spi_write(0xc6, 0x3232, 2);
201 mdelay(1);
202 toshiba_spi_write(0xc7, 0x6445, 2);
203 mdelay(1);
204 toshiba_spi_write(0xc8, 0x44, 1);
205 toshiba_spi_write(0xc9, 0x52, 1);
206 mdelay(1);
207 toshiba_spi_write(0xca, 0x00, 1);
208 mdelay(1);
209 toshiba_spi_write(0xec, 0x02a4, 2); /* 0x02a4 */
210 mdelay(1);
211 toshiba_spi_write(0xcf, 0x01, 1);
212 mdelay(1);
213 toshiba_spi_write(0xd0, 0xc003, 2); /* c003 */
214 mdelay(1);
215 toshiba_spi_write(0xd1, 0x01, 1);
216 mdelay(1);
217 toshiba_spi_write(0xd2, 0x0028, 2);
218 mdelay(1);
219 toshiba_spi_write(0xd3, 0x0028, 2);
220 mdelay(1);
221 toshiba_spi_write(0xd4, 0x26a4, 2);
222 mdelay(1);
223 toshiba_spi_write(0xd5, 0x20, 1);
224 mdelay(1);
225 toshiba_spi_write(0xef, 0x3200, 2);
226 mdelay(32);
227 toshiba_spi_write(0xbc, 0x80, 1); /* wvga pass through */
228 toshiba_spi_write(0x3b, 0x00, 1);
229 mdelay(1);
230 toshiba_spi_write(0xb0, 0x16, 1);
231 mdelay(1);
232 toshiba_spi_write(0xb8, 0xfff5, 2);
233 mdelay(1);
234 toshiba_spi_write(0x11, 0, 0);
235 mdelay(5);
236 toshiba_spi_write(0x29, 0, 0);
237 mdelay(5);
238 toshiba_state.display_on = TRUE;
239 }
240
241 data = 0;
242 toshiba_spi_read_bytes(0x04, &data, 3);
243 printk(KERN_INFO "toshiba_disp_on: id=%x\n", data);
244
245}
246
247static int lcdc_toshiba_panel_on(struct platform_device *pdev)
248{
249 if (!toshiba_state.disp_initialized) {
250 /* Configure reset GPIO that drives DAC */
251 if (lcdc_toshiba_pdata->panel_config_gpio)
252 lcdc_toshiba_pdata->panel_config_gpio(1);
253 toshiba_disp_powerup();
254 toshiba_disp_on();
255 toshiba_state.disp_initialized = TRUE;
256 }
257 return 0;
258}
259
260static int lcdc_toshiba_panel_off(struct platform_device *pdev)
261{
262 if (toshiba_state.disp_powered_up && toshiba_state.display_on) {
263 /* Main panel power off (Deep standby in) */
264
265 toshiba_spi_write(0x28, 0, 0); /* display off */
266 mdelay(1);
267 toshiba_spi_write(0xb8, 0x8002, 2); /* output control */
268 mdelay(1);
269 toshiba_spi_write(0x10, 0x00, 1); /* sleep mode in */
270 mdelay(85); /* wait 85 msec */
271 toshiba_spi_write(0xb0, 0x00, 1); /* deep standby in */
272 mdelay(1);
273 if (lcdc_toshiba_pdata->panel_config_gpio)
274 lcdc_toshiba_pdata->panel_config_gpio(0);
275 toshiba_state.display_on = FALSE;
276 toshiba_state.disp_initialized = FALSE;
277 }
278 return 0;
279}
280
281static void lcdc_toshiba_set_backlight(struct msm_fb_data_type *mfd)
282{
283 int bl_level;
284 int ret = -EPERM;
285
286 bl_level = mfd->bl_level;
287 ret = pmic_set_led_intensity(LED_LCD, bl_level);
288
289 if (ret)
290 printk(KERN_WARNING "%s: can't set lcd backlight!\n",
291 __func__);
292}
293
294static int __init toshiba_probe(struct platform_device *pdev)
295{
296 if (pdev->id == 0) {
297 lcdc_toshiba_pdata = pdev->dev.platform_data;
298 spi_pin_assign();
299 return 0;
300 }
301 msm_fb_add_device(pdev);
302 return 0;
303}
304
305static struct platform_driver this_driver = {
306 .probe = toshiba_probe,
307 .driver = {
308 .name = "lcdc_toshiba_wvga",
309 },
310};
311
312static struct msm_fb_panel_data toshiba_panel_data = {
313 .on = lcdc_toshiba_panel_on,
314 .off = lcdc_toshiba_panel_off,
315 .set_backlight = lcdc_toshiba_set_backlight,
316};
317
318static struct platform_device this_device = {
319 .name = "lcdc_toshiba_wvga",
320 .id = 1,
321 .dev = {
322 .platform_data = &toshiba_panel_data,
323 }
324};
325
326static int __init lcdc_toshiba_panel_init(void)
327{
328 int ret;
329 struct msm_panel_info *pinfo;
330#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
331 if (mddi_get_client_id() != 0)
332 return 0;
333
334 ret = msm_fb_detect_client("lcdc_toshiba_wvga_pt");
335 if (ret)
336 return 0;
337
338#endif
339
340 ret = platform_driver_register(&this_driver);
341 if (ret)
342 return ret;
343
344 pinfo = &toshiba_panel_data.panel_info;
345 pinfo->xres = 480;
346 pinfo->yres = 800;
347 pinfo->type = LCDC_PANEL;
348 pinfo->pdest = DISPLAY_1;
349 pinfo->wait_cycle = 0;
350 pinfo->bpp = 18;
351 pinfo->fb_num = 2;
352 /* 30Mhz mdp_lcdc_pclk and mdp_lcdc_pad_pcl */
353 pinfo->clk_rate = 27648000;
354 pinfo->bl_max = 15;
355 pinfo->bl_min = 1;
356
357 pinfo->lcdc.h_back_porch = 184; /* hsw = 8 + hbp=184 */
358 pinfo->lcdc.h_front_porch = 4;
359 pinfo->lcdc.h_pulse_width = 8;
360 pinfo->lcdc.v_back_porch = 2; /* vsw=1 + vbp = 2 */
361 pinfo->lcdc.v_front_porch = 3;
362 pinfo->lcdc.v_pulse_width = 1;
363 pinfo->lcdc.border_clr = 0; /* blk */
364 pinfo->lcdc.underflow_clr = 0xff; /* blue */
365 pinfo->lcdc.hsync_skew = 0;
366
367 ret = platform_device_register(&this_device);
368 if (ret)
369 platform_driver_unregister(&this_driver);
370
371 return ret;
372}
373
374device_initcall(lcdc_toshiba_panel_init);
diff --git a/drivers/staging/msm/lcdc_wxga.c b/drivers/staging/msm/lcdc_wxga.c
new file mode 100644
index 000000000000..202c92c0ef54
--- /dev/null
+++ b/drivers/staging/msm/lcdc_wxga.c
@@ -0,0 +1,56 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19
20static int __init lcdc_wxga_init(void)
21{
22 int ret;
23 struct msm_panel_info pinfo;
24
25#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
26 if (msm_fb_detect_client("lcdc_wxga"))
27 return 0;
28#endif
29
30 pinfo.xres = 1280;
31 pinfo.yres = 720;
32 pinfo.type = LCDC_PANEL;
33 pinfo.pdest = DISPLAY_1;
34 pinfo.wait_cycle = 0;
35 pinfo.bpp = 24;
36 pinfo.fb_num = 2;
37 pinfo.clk_rate = 74250000;
38
39 pinfo.lcdc.h_back_porch = 124;
40 pinfo.lcdc.h_front_porch = 110;
41 pinfo.lcdc.h_pulse_width = 136;
42 pinfo.lcdc.v_back_porch = 19;
43 pinfo.lcdc.v_front_porch = 5;
44 pinfo.lcdc.v_pulse_width = 6;
45 pinfo.lcdc.border_clr = 0; /* blk */
46 pinfo.lcdc.underflow_clr = 0xff; /* blue */
47 pinfo.lcdc.hsync_skew = 0;
48
49 ret = lcdc_device_register(&pinfo);
50 if (ret)
51 printk(KERN_ERR "%s: failed to register device!\n", __func__);
52
53 return ret;
54}
55
56module_init(lcdc_wxga_init);
diff --git a/drivers/staging/msm/logo.c b/drivers/staging/msm/logo.c
new file mode 100644
index 000000000000..7272765f48cd
--- /dev/null
+++ b/drivers/staging/msm/logo.c
@@ -0,0 +1,98 @@
1/* drivers/video/msm/logo.c
2 *
3 * Show Logo in RLE 565 format
4 *
5 * Copyright (C) 2008 Google Incorporated
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17#include <linux/module.h>
18#include <linux/types.h>
19#include <linux/fb.h>
20#include <linux/vt_kern.h>
21#include <linux/unistd.h>
22#include <linux/syscalls.h>
23
24#include <linux/irq.h>
25#include <asm/system.h>
26
27#define fb_width(fb) ((fb)->var.xres)
28#define fb_height(fb) ((fb)->var.yres)
29#define fb_size(fb) ((fb)->var.xres * (fb)->var.yres * 2)
30
31static void memset16(void *_ptr, unsigned short val, unsigned count)
32{
33 unsigned short *ptr = _ptr;
34 count >>= 1;
35 while (count--)
36 *ptr++ = val;
37}
38
39/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
40int load_565rle_image(char *filename)
41{
42 struct fb_info *info;
43 int fd, err = 0;
44 unsigned count, max;
45 unsigned short *data, *bits, *ptr;
46
47 info = registered_fb[0];
48 if (!info) {
49 printk(KERN_WARNING "%s: Can not access framebuffer\n",
50 __func__);
51 return -ENODEV;
52 }
53
54 fd = sys_open(filename, O_RDONLY, 0);
55 if (fd < 0) {
56 printk(KERN_WARNING "%s: Can not open %s\n",
57 __func__, filename);
58 return -ENOENT;
59 }
60 count = (unsigned)sys_lseek(fd, (off_t)0, 2);
61 if (count == 0) {
62 sys_close(fd);
63 err = -EIO;
64 goto err_logo_close_file;
65 }
66 sys_lseek(fd, (off_t)0, 0);
67 data = kmalloc(count, GFP_KERNEL);
68 if (!data) {
69 printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
70 err = -ENOMEM;
71 goto err_logo_close_file;
72 }
73 if ((unsigned)sys_read(fd, (char *)data, count) != count) {
74 err = -EIO;
75 goto err_logo_free_data;
76 }
77
78 max = fb_width(info) * fb_height(info);
79 ptr = data;
80 bits = (unsigned short *)(info->screen_base);
81 while (count > 3) {
82 unsigned n = ptr[0];
83 if (n > max)
84 break;
85 memset16(bits, ptr[1], n << 1);
86 bits += n;
87 max -= n;
88 ptr += 2;
89 count -= 4;
90 }
91
92err_logo_free_data:
93 kfree(data);
94err_logo_close_file:
95 sys_close(fd);
96 return err;
97}
98EXPORT_SYMBOL(load_565rle_image);
diff --git a/drivers/staging/msm/mddi.c b/drivers/staging/msm/mddi.c
new file mode 100644
index 000000000000..132eb1adff16
--- /dev/null
+++ b/drivers/staging/msm/mddi.c
@@ -0,0 +1,375 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <asm/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/uaccess.h>
33#include <linux/clk.h>
34#include <linux/platform_device.h>
35
36#include "msm_fb.h"
37#include "mddihosti.h"
38#include "mddihost.h"
39#include <mach/gpio.h>
40#include <mach/clk.h>
41
42static int mddi_probe(struct platform_device *pdev);
43static int mddi_remove(struct platform_device *pdev);
44
45static int mddi_off(struct platform_device *pdev);
46static int mddi_on(struct platform_device *pdev);
47
48static int mddi_suspend(struct platform_device *pdev, pm_message_t state);
49static int mddi_resume(struct platform_device *pdev);
50
51#ifdef CONFIG_HAS_EARLYSUSPEND
52static void mddi_early_suspend(struct early_suspend *h);
53static void mddi_early_resume(struct early_suspend *h);
54#endif
55
56static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
57static int pdev_list_cnt;
58static struct clk *mddi_clk;
59static struct clk *mddi_pclk;
60static struct mddi_platform_data *mddi_pdata;
61
62static struct platform_driver mddi_driver = {
63 .probe = mddi_probe,
64 .remove = mddi_remove,
65#ifndef CONFIG_HAS_EARLYSUSPEND
66#ifdef CONFIG_PM
67 .suspend = mddi_suspend,
68 .resume = mddi_resume,
69#endif
70#endif
71 .suspend_late = NULL,
72 .resume_early = NULL,
73 .shutdown = NULL,
74 .driver = {
75 .name = "mddi",
76 },
77};
78
79extern int int_mddi_pri_flag;
80
81static int mddi_off(struct platform_device *pdev)
82{
83 int ret = 0;
84
85 ret = panel_next_off(pdev);
86
87 if (mddi_pdata && mddi_pdata->mddi_power_save)
88 mddi_pdata->mddi_power_save(0);
89
90 return ret;
91}
92
93static int mddi_on(struct platform_device *pdev)
94{
95 int ret = 0;
96 u32 clk_rate;
97 struct msm_fb_data_type *mfd;
98
99 mfd = platform_get_drvdata(pdev);
100
101 if (mddi_pdata && mddi_pdata->mddi_power_save)
102 mddi_pdata->mddi_power_save(1);
103
104 clk_rate = mfd->fbi->var.pixclock;
105 clk_rate = min(clk_rate, mfd->panel_info.clk_max);
106
107 if (mddi_pdata &&
108 mddi_pdata->mddi_sel_clk &&
109 mddi_pdata->mddi_sel_clk(&clk_rate))
110 printk(KERN_ERR
111 "%s: can't select mddi io clk targate rate = %d\n",
112 __func__, clk_rate);
113
114 if (clk_set_min_rate(mddi_clk, clk_rate) < 0)
115 printk(KERN_ERR "%s: clk_set_min_rate failed\n",
116 __func__);
117
118 ret = panel_next_on(pdev);
119
120 return ret;
121}
122
123static int mddi_resource_initialized;
124
125static int mddi_probe(struct platform_device *pdev)
126{
127 struct msm_fb_data_type *mfd;
128 struct platform_device *mdp_dev = NULL;
129 struct msm_fb_panel_data *pdata = NULL;
130 int rc;
131 resource_size_t size ;
132 u32 clk_rate;
133
134 if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
135 mddi_pdata = pdev->dev.platform_data;
136
137 size = resource_size(&pdev->resource[0]);
138 msm_pmdh_base = ioremap(pdev->resource[0].start, size);
139
140 MSM_FB_INFO("primary mddi base phy_addr = 0x%x virt = 0x%x\n",
141 pdev->resource[0].start, (int) msm_pmdh_base);
142
143 if (unlikely(!msm_pmdh_base))
144 return -ENOMEM;
145
146 if (mddi_pdata && mddi_pdata->mddi_power_save)
147 mddi_pdata->mddi_power_save(1);
148
149 mddi_resource_initialized = 1;
150 return 0;
151 }
152
153 if (!mddi_resource_initialized)
154 return -EPERM;
155
156 mfd = platform_get_drvdata(pdev);
157
158 if (!mfd)
159 return -ENODEV;
160
161 if (mfd->key != MFD_KEY)
162 return -EINVAL;
163
164 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
165 return -ENOMEM;
166
167 mdp_dev = platform_device_alloc("mdp", pdev->id);
168 if (!mdp_dev)
169 return -ENOMEM;
170
171 /*
172 * link to the latest pdev
173 */
174 mfd->pdev = mdp_dev;
175 mfd->dest = DISPLAY_LCD;
176
177 /*
178 * alloc panel device data
179 */
180 if (platform_device_add_data
181 (mdp_dev, pdev->dev.platform_data,
182 sizeof(struct msm_fb_panel_data))) {
183 printk(KERN_ERR "mddi_probe: platform_device_add_data failed!\n");
184 platform_device_put(mdp_dev);
185 return -ENOMEM;
186 }
187 /*
188 * data chain
189 */
190 pdata = mdp_dev->dev.platform_data;
191 pdata->on = mddi_on;
192 pdata->off = mddi_off;
193 pdata->next = pdev;
194
195 /*
196 * get/set panel specific fb info
197 */
198 mfd->panel_info = pdata->panel_info;
199 mfd->fb_imgType = MDP_RGB_565;
200
201 clk_rate = mfd->panel_info.clk_max;
202 if (mddi_pdata &&
203 mddi_pdata->mddi_sel_clk &&
204 mddi_pdata->mddi_sel_clk(&clk_rate))
205 printk(KERN_ERR
206 "%s: can't select mddi io clk targate rate = %d\n",
207 __func__, clk_rate);
208
209 if (clk_set_max_rate(mddi_clk, clk_rate) < 0)
210 printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__);
211 mfd->panel_info.clk_rate = mfd->panel_info.clk_min;
212
213 /*
214 * set driver data
215 */
216 platform_set_drvdata(mdp_dev, mfd);
217
218 /*
219 * register in mdp driver
220 */
221 rc = platform_device_add(mdp_dev);
222 if (rc)
223 goto mddi_probe_err;
224
225 pdev_list[pdev_list_cnt++] = pdev;
226
227#ifdef CONFIG_HAS_EARLYSUSPEND
228 mfd->mddi_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
229 mfd->mddi_early_suspend.suspend = mddi_early_suspend;
230 mfd->mddi_early_suspend.resume = mddi_early_resume;
231 register_early_suspend(&mfd->mddi_early_suspend);
232#endif
233
234 return 0;
235
236mddi_probe_err:
237 platform_device_put(mdp_dev);
238 return rc;
239}
240
241static int mddi_pad_ctrl;
242static int mddi_power_locked;
243static int mddi_is_in_suspend;
244
245void mddi_disable(int lock)
246{
247 mddi_host_type host_idx = MDDI_HOST_PRIM;
248
249 if (mddi_power_locked)
250 return;
251
252 if (lock)
253 mddi_power_locked = 1;
254
255 if (mddi_host_timer.function)
256 del_timer_sync(&mddi_host_timer);
257
258 mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL);
259 mddi_host_reg_out(PAD_CTL, 0x0);
260
261 if (clk_set_min_rate(mddi_clk, 0) < 0)
262 printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
263
264 clk_disable(mddi_clk);
265 if (mddi_pclk)
266 clk_disable(mddi_pclk);
267 disable_irq(INT_MDDI_PRI);
268
269 if (mddi_pdata && mddi_pdata->mddi_power_save)
270 mddi_pdata->mddi_power_save(0);
271}
272
273static int mddi_suspend(struct platform_device *pdev, pm_message_t state)
274{
275 if (mddi_is_in_suspend)
276 return 0;
277
278 mddi_is_in_suspend = 1;
279 mddi_disable(0);
280 return 0;
281}
282
283static int mddi_resume(struct platform_device *pdev)
284{
285 mddi_host_type host_idx = MDDI_HOST_PRIM;
286
287 if (!mddi_is_in_suspend)
288 return 0;
289
290 mddi_is_in_suspend = 0;
291
292 if (mddi_power_locked)
293 return 0;
294
295 enable_irq(INT_MDDI_PRI);
296 clk_enable(mddi_clk);
297 if (mddi_pclk)
298 clk_enable(mddi_pclk);
299 mddi_host_reg_out(PAD_CTL, mddi_pad_ctrl);
300
301 if (mddi_host_timer.function)
302 mddi_host_timer_service(0);
303
304 return 0;
305}
306
307#ifdef CONFIG_HAS_EARLYSUSPEND
308static void mddi_early_suspend(struct early_suspend *h)
309{
310 pm_message_t state;
311 struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
312 mddi_early_suspend);
313
314 state.event = PM_EVENT_SUSPEND;
315 mddi_suspend(mfd->pdev, state);
316}
317
318static void mddi_early_resume(struct early_suspend *h)
319{
320 struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
321 mddi_early_suspend);
322 mddi_resume(mfd->pdev);
323}
324#endif
325
326static int mddi_remove(struct platform_device *pdev)
327{
328 if (mddi_host_timer.function)
329 del_timer_sync(&mddi_host_timer);
330
331 iounmap(msm_pmdh_base);
332
333 return 0;
334}
335
336static int mddi_register_driver(void)
337{
338 return platform_driver_register(&mddi_driver);
339}
340
341static int __init mddi_driver_init(void)
342{
343 int ret;
344
345 mddi_clk = clk_get(NULL, "mddi_clk");
346 if (IS_ERR(mddi_clk)) {
347 printk(KERN_ERR "can't find mddi_clk \n");
348 return PTR_ERR(mddi_clk);
349 }
350 clk_enable(mddi_clk);
351
352 mddi_pclk = clk_get(NULL, "mddi_pclk");
353 if (IS_ERR(mddi_pclk))
354 mddi_pclk = NULL;
355 else
356 clk_enable(mddi_pclk);
357
358 ret = mddi_register_driver();
359 if (ret) {
360 clk_disable(mddi_clk);
361 clk_put(mddi_clk);
362 if (mddi_pclk) {
363 clk_disable(mddi_pclk);
364 clk_put(mddi_pclk);
365 }
366 printk(KERN_ERR "mddi_register_driver() failed!\n");
367 return ret;
368 }
369
370 mddi_init();
371
372 return ret;
373}
374
375module_init(mddi_driver_init);
diff --git a/drivers/staging/msm/mddi_ext.c b/drivers/staging/msm/mddi_ext.c
new file mode 100644
index 000000000000..c0c168c7199d
--- /dev/null
+++ b/drivers/staging/msm/mddi_ext.c
@@ -0,0 +1,320 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <asm/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/uaccess.h>
33#include <linux/clk.h>
34#include <mach/clk.h>
35#include <linux/platform_device.h>
36
37#include "msm_fb.h"
38#include "mddihosti.h"
39
40static int mddi_ext_probe(struct platform_device *pdev);
41static int mddi_ext_remove(struct platform_device *pdev);
42
43static int mddi_ext_off(struct platform_device *pdev);
44static int mddi_ext_on(struct platform_device *pdev);
45
46static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
47static int pdev_list_cnt;
48
49static int mddi_ext_suspend(struct platform_device *pdev, pm_message_t state);
50static int mddi_ext_resume(struct platform_device *pdev);
51
52#ifdef CONFIG_HAS_EARLYSUSPEND
53static void mddi_ext_early_suspend(struct early_suspend *h);
54static void mddi_ext_early_resume(struct early_suspend *h);
55#endif
56
57static struct platform_driver mddi_ext_driver = {
58 .probe = mddi_ext_probe,
59 .remove = mddi_ext_remove,
60#ifndef CONFIG_HAS_EARLYSUSPEND
61#ifdef CONFIG_PM
62 .suspend = mddi_ext_suspend,
63 .resume = mddi_ext_resume,
64#endif
65#endif
66 .resume_early = NULL,
67 .resume = NULL,
68 .shutdown = NULL,
69 .driver = {
70 .name = "mddi_ext",
71 },
72};
73
74static struct clk *mddi_ext_clk;
75static struct mddi_platform_data *mddi_ext_pdata;
76
77extern int int_mddi_ext_flag;
78
79static int mddi_ext_off(struct platform_device *pdev)
80{
81 int ret = 0;
82
83 ret = panel_next_off(pdev);
84 mddi_host_stop_ext_display();
85
86 return ret;
87}
88
89static int mddi_ext_on(struct platform_device *pdev)
90{
91 int ret = 0;
92 u32 clk_rate;
93 struct msm_fb_data_type *mfd;
94
95 mfd = platform_get_drvdata(pdev);
96
97 clk_rate = mfd->fbi->var.pixclock;
98 clk_rate = min(clk_rate, mfd->panel_info.clk_max);
99
100 if (mddi_ext_pdata &&
101 mddi_ext_pdata->mddi_sel_clk &&
102 mddi_ext_pdata->mddi_sel_clk(&clk_rate))
103 printk(KERN_ERR
104 "%s: can't select mddi io clk targate rate = %d\n",
105 __func__, clk_rate);
106
107 if (clk_set_min_rate(mddi_ext_clk, clk_rate) < 0)
108 printk(KERN_ERR "%s: clk_set_min_rate failed\n",
109 __func__);
110
111 mddi_host_start_ext_display();
112 ret = panel_next_on(pdev);
113
114 return ret;
115}
116
117static int mddi_ext_resource_initialized;
118
119static int mddi_ext_probe(struct platform_device *pdev)
120{
121 struct msm_fb_data_type *mfd;
122 struct platform_device *mdp_dev = NULL;
123 struct msm_fb_panel_data *pdata = NULL;
124 int rc;
125 resource_size_t size ;
126 u32 clk_rate;
127
128 if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
129 mddi_ext_pdata = pdev->dev.platform_data;
130
131 size = resource_size(&pdev->resource[0]);
132 msm_emdh_base = ioremap(pdev->resource[0].start, size);
133
134 MSM_FB_INFO("external mddi base address = 0x%x\n",
135 pdev->resource[0].start);
136
137 if (unlikely(!msm_emdh_base))
138 return -ENOMEM;
139
140 mddi_ext_resource_initialized = 1;
141 return 0;
142 }
143
144 if (!mddi_ext_resource_initialized)
145 return -EPERM;
146
147 mfd = platform_get_drvdata(pdev);
148
149 if (!mfd)
150 return -ENODEV;
151
152 if (mfd->key != MFD_KEY)
153 return -EINVAL;
154
155 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
156 return -ENOMEM;
157
158 mdp_dev = platform_device_alloc("mdp", pdev->id);
159 if (!mdp_dev)
160 return -ENOMEM;
161
162 /*
163 * link to the latest pdev
164 */
165 mfd->pdev = mdp_dev;
166 mfd->dest = DISPLAY_EXT_MDDI;
167
168 /*
169 * alloc panel device data
170 */
171 if (platform_device_add_data
172 (mdp_dev, pdev->dev.platform_data,
173 sizeof(struct msm_fb_panel_data))) {
174 printk(KERN_ERR "mddi_ext_probe: platform_device_add_data failed!\n");
175 platform_device_put(mdp_dev);
176 return -ENOMEM;
177 }
178 /*
179 * data chain
180 */
181 pdata = mdp_dev->dev.platform_data;
182 pdata->on = mddi_ext_on;
183 pdata->off = mddi_ext_off;
184 pdata->next = pdev;
185
186 /*
187 * get/set panel specific fb info
188 */
189 mfd->panel_info = pdata->panel_info;
190 mfd->fb_imgType = MDP_RGB_565;
191
192 clk_rate = mfd->panel_info.clk_max;
193 if (mddi_ext_pdata &&
194 mddi_ext_pdata->mddi_sel_clk &&
195 mddi_ext_pdata->mddi_sel_clk(&clk_rate))
196 printk(KERN_ERR
197 "%s: can't select mddi io clk targate rate = %d\n",
198 __func__, clk_rate);
199
200 if (clk_set_max_rate(mddi_ext_clk, clk_rate) < 0)
201 printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__);
202 mfd->panel_info.clk_rate = mfd->panel_info.clk_min;
203
204 /*
205 * set driver data
206 */
207 platform_set_drvdata(mdp_dev, mfd);
208
209 /*
210 * register in mdp driver
211 */
212 rc = platform_device_add(mdp_dev);
213 if (rc)
214 goto mddi_ext_probe_err;
215
216 pdev_list[pdev_list_cnt++] = pdev;
217
218#ifdef CONFIG_HAS_EARLYSUSPEND
219 mfd->mddi_ext_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
220 mfd->mddi_ext_early_suspend.suspend = mddi_ext_early_suspend;
221 mfd->mddi_ext_early_suspend.resume = mddi_ext_early_resume;
222 register_early_suspend(&mfd->mddi_ext_early_suspend);
223#endif
224
225 return 0;
226
227mddi_ext_probe_err:
228 platform_device_put(mdp_dev);
229 return rc;
230}
231
232static int mddi_ext_is_in_suspend;
233
234static int mddi_ext_suspend(struct platform_device *pdev, pm_message_t state)
235{
236 if (mddi_ext_is_in_suspend)
237 return 0;
238
239 mddi_ext_is_in_suspend = 1;
240
241 if (clk_set_min_rate(mddi_ext_clk, 0) < 0)
242 printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
243
244 clk_disable(mddi_ext_clk);
245 disable_irq(INT_MDDI_EXT);
246
247 return 0;
248}
249
250static int mddi_ext_resume(struct platform_device *pdev)
251{
252 struct msm_fb_data_type *mfd;
253
254 mfd = platform_get_drvdata(pdev);
255
256 if (!mddi_ext_is_in_suspend)
257 return 0;
258
259 mddi_ext_is_in_suspend = 0;
260 enable_irq(INT_MDDI_EXT);
261
262 clk_enable(mddi_ext_clk);
263
264 return 0;
265}
266
267#ifdef CONFIG_HAS_EARLYSUSPEND
268static void mddi_ext_early_suspend(struct early_suspend *h)
269{
270 pm_message_t state;
271 struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
272 mddi_ext_early_suspend);
273
274 state.event = PM_EVENT_SUSPEND;
275 mddi_ext_suspend(mfd->pdev, state);
276}
277
278static void mddi_ext_early_resume(struct early_suspend *h)
279{
280 struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
281 mddi_ext_early_suspend);
282 mddi_ext_resume(mfd->pdev);
283}
284#endif
285
286static int mddi_ext_remove(struct platform_device *pdev)
287{
288 iounmap(msm_emdh_base);
289 return 0;
290}
291
292static int mddi_ext_register_driver(void)
293{
294 return platform_driver_register(&mddi_ext_driver);
295}
296
297static int __init mddi_ext_driver_init(void)
298{
299 int ret;
300
301 mddi_ext_clk = clk_get(NULL, "emdh_clk");
302 if (IS_ERR(mddi_ext_clk)) {
303 printk(KERN_ERR "can't find emdh_clk\n");
304 return PTR_ERR(mddi_ext_clk);
305 }
306 clk_enable(mddi_ext_clk);
307
308 ret = mddi_ext_register_driver();
309 if (ret) {
310 clk_disable(mddi_ext_clk);
311 clk_put(mddi_ext_clk);
312 printk(KERN_ERR "mddi_ext_register_driver() failed!\n");
313 return ret;
314 }
315 mddi_init();
316
317 return ret;
318}
319
320module_init(mddi_ext_driver_init);
diff --git a/drivers/staging/msm/mddi_ext_lcd.c b/drivers/staging/msm/mddi_ext_lcd.c
new file mode 100644
index 000000000000..502e80d17ec7
--- /dev/null
+++ b/drivers/staging/msm/mddi_ext_lcd.c
@@ -0,0 +1,91 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19#include "mddihost.h"
20#include "mddihosti.h"
21
22static int mddi_ext_lcd_on(struct platform_device *pdev);
23static int mddi_ext_lcd_off(struct platform_device *pdev);
24
25static int mddi_ext_lcd_on(struct platform_device *pdev)
26{
27 return 0;
28}
29
30static int mddi_ext_lcd_off(struct platform_device *pdev)
31{
32 return 0;
33}
34
35static int __init mddi_ext_lcd_probe(struct platform_device *pdev)
36{
37 msm_fb_add_device(pdev);
38
39 return 0;
40}
41
42static struct platform_driver this_driver = {
43 .probe = mddi_ext_lcd_probe,
44 .driver = {
45 .name = "extmddi_svga",
46 },
47};
48
49static struct msm_fb_panel_data mddi_ext_lcd_panel_data = {
50 .panel_info.xres = 800,
51 .panel_info.yres = 600,
52 .panel_info.type = EXT_MDDI_PANEL,
53 .panel_info.pdest = DISPLAY_1,
54 .panel_info.wait_cycle = 0,
55 .panel_info.bpp = 18,
56 .panel_info.fb_num = 2,
57 .panel_info.clk_rate = 122880000,
58 .panel_info.clk_min = 120000000,
59 .panel_info.clk_max = 125000000,
60 .on = mddi_ext_lcd_on,
61 .off = mddi_ext_lcd_off,
62};
63
64static struct platform_device this_device = {
65 .name = "extmddi_svga",
66 .id = 0,
67 .dev = {
68 .platform_data = &mddi_ext_lcd_panel_data,
69 }
70};
71
72static int __init mddi_ext_lcd_init(void)
73{
74 int ret;
75 struct msm_panel_info *pinfo;
76
77 ret = platform_driver_register(&this_driver);
78 if (!ret) {
79 pinfo = &mddi_ext_lcd_panel_data.panel_info;
80 pinfo->lcd.vsync_enable = FALSE;
81 pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
82
83 ret = platform_device_register(&this_device);
84 if (ret)
85 platform_driver_unregister(&this_driver);
86 }
87
88 return ret;
89}
90
91module_init(mddi_ext_lcd_init);
diff --git a/drivers/staging/msm/mddi_prism.c b/drivers/staging/msm/mddi_prism.c
new file mode 100644
index 000000000000..489d40405a5f
--- /dev/null
+++ b/drivers/staging/msm/mddi_prism.c
@@ -0,0 +1,114 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19#include "mddihost.h"
20#include "mddihosti.h"
21
22static int prism_lcd_on(struct platform_device *pdev);
23static int prism_lcd_off(struct platform_device *pdev);
24
25static int prism_lcd_on(struct platform_device *pdev)
26{
27 /* Set the MDP pixel data attributes for Primary Display */
28 mddi_host_write_pix_attr_reg(0x00C3);
29
30 return 0;
31}
32
33static int prism_lcd_off(struct platform_device *pdev)
34{
35 return 0;
36}
37
38static int __init prism_probe(struct platform_device *pdev)
39{
40 msm_fb_add_device(pdev);
41
42 return 0;
43}
44
45static struct platform_driver this_driver = {
46 .probe = prism_probe,
47 .driver = {
48 .name = "mddi_prism_wvga",
49 },
50};
51
52static struct msm_fb_panel_data prism_panel_data = {
53 .on = prism_lcd_on,
54 .off = prism_lcd_off,
55};
56
57static struct platform_device this_device = {
58 .name = "mddi_prism_wvga",
59 .id = 0,
60 .dev = {
61 .platform_data = &prism_panel_data,
62 }
63};
64
65static int __init prism_init(void)
66{
67 int ret;
68 struct msm_panel_info *pinfo;
69
70#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
71 u32 id;
72
73 ret = msm_fb_detect_client("mddi_prism_wvga");
74 if (ret == -ENODEV)
75 return 0;
76
77 if (ret) {
78 id = mddi_get_client_id();
79
80 if (((id >> 16) != 0x4474) || ((id & 0xffff) == 0x8960))
81 return 0;
82 }
83#endif
84 ret = platform_driver_register(&this_driver);
85 if (!ret) {
86 pinfo = &prism_panel_data.panel_info;
87 pinfo->xres = 800;
88 pinfo->yres = 480;
89 pinfo->type = MDDI_PANEL;
90 pinfo->pdest = DISPLAY_1;
91 pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
92 pinfo->wait_cycle = 0;
93 pinfo->bpp = 18;
94 pinfo->fb_num = 2;
95 pinfo->clk_rate = 153600000;
96 pinfo->clk_min = 150000000;
97 pinfo->clk_max = 160000000;
98 pinfo->lcd.vsync_enable = TRUE;
99 pinfo->lcd.refx100 = 6050;
100 pinfo->lcd.v_back_porch = 23;
101 pinfo->lcd.v_front_porch = 20;
102 pinfo->lcd.v_pulse_width = 105;
103 pinfo->lcd.hw_vsync_mode = TRUE;
104 pinfo->lcd.vsync_notifier_period = 0;
105
106 ret = platform_device_register(&this_device);
107 if (ret)
108 platform_driver_unregister(&this_driver);
109 }
110
111 return ret;
112}
113
114module_init(prism_init);
diff --git a/drivers/staging/msm/mddi_sharp.c b/drivers/staging/msm/mddi_sharp.c
new file mode 100644
index 000000000000..1da1be4052d0
--- /dev/null
+++ b/drivers/staging/msm/mddi_sharp.c
@@ -0,0 +1,892 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19#include "mddihost.h"
20#include "mddihosti.h"
21
22#define SHARP_QVGA_PRIM 1
23#define SHARP_128X128_SECD 2
24
25extern uint32 mddi_host_core_version;
26static boolean mddi_debug_prim_wait = FALSE;
27static boolean mddi_sharp_vsync_wake = TRUE;
28static boolean mddi_sharp_monitor_refresh_value = TRUE;
29static boolean mddi_sharp_report_refresh_measurements = FALSE;
30static uint32 mddi_sharp_rows_per_second = 13830; /* 5200000/376 */
31static uint32 mddi_sharp_rows_per_refresh = 338;
32static uint32 mddi_sharp_usecs_per_refresh = 24440; /* (376+338)/5200000 */
33static boolean mddi_sharp_debug_60hz_refresh = FALSE;
34
35extern mddi_gpio_info_type mddi_gpio;
36extern boolean mddi_vsync_detect_enabled;
37static msm_fb_vsync_handler_type mddi_sharp_vsync_handler;
38static void *mddi_sharp_vsync_handler_arg;
39static uint16 mddi_sharp_vsync_attempts;
40
41static void mddi_sharp_prim_lcd_init(void);
42static void mddi_sharp_sub_lcd_init(void);
43static void mddi_sharp_lcd_set_backlight(struct msm_fb_data_type *mfd);
44static void mddi_sharp_vsync_set_handler(msm_fb_vsync_handler_type handler,
45 void *);
46static void mddi_sharp_lcd_vsync_detected(boolean detected);
47static struct msm_panel_common_pdata *mddi_sharp_pdata;
48
49#define REG_SYSCTL 0x0000
50#define REG_INTR 0x0006
51#define REG_CLKCNF 0x000C
52#define REG_CLKDIV1 0x000E
53#define REG_CLKDIV2 0x0010
54
55#define REG_GIOD 0x0040
56#define REG_GIOA 0x0042
57
58#define REG_AGM 0x010A
59#define REG_FLFT 0x0110
60#define REG_FRGT 0x0112
61#define REG_FTOP 0x0114
62#define REG_FBTM 0x0116
63#define REG_FSTRX 0x0118
64#define REG_FSTRY 0x011A
65#define REG_VRAM 0x0202
66#define REG_SSDCTL 0x0330
67#define REG_SSD0 0x0332
68#define REG_PSTCTL1 0x0400
69#define REG_PSTCTL2 0x0402
70#define REG_PTGCTL 0x042A
71#define REG_PTHP 0x042C
72#define REG_PTHB 0x042E
73#define REG_PTHW 0x0430
74#define REG_PTHF 0x0432
75#define REG_PTVP 0x0434
76#define REG_PTVB 0x0436
77#define REG_PTVW 0x0438
78#define REG_PTVF 0x043A
79#define REG_VBLKS 0x0458
80#define REG_VBLKE 0x045A
81#define REG_SUBCTL 0x0700
82#define REG_SUBTCMD 0x0702
83#define REG_SUBTCMDD 0x0704
84#define REG_REVBYTE 0x0A02
85#define REG_REVCNT 0x0A04
86#define REG_REVATTR 0x0A06
87#define REG_REVFMT 0x0A08
88
89#define SHARP_SUB_UNKNOWN 0xffffffff
90#define SHARP_SUB_HYNIX 1
91#define SHARP_SUB_ROHM 2
92
93static uint32 sharp_subpanel_type = SHARP_SUB_UNKNOWN;
94
95static void sub_through_write(int sub_rs, uint32 sub_data)
96{
97 mddi_queue_register_write(REG_SUBTCMDD, sub_data, FALSE, 0);
98
99 /* CS=1,RD=1,WE=1,RS=sub_rs */
100 mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, FALSE, 0);
101
102 /* CS=0,RD=1,WE=1,RS=sub_rs */
103 mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
104
105 /* CS=0,RD=1,WE=0,RS=sub_rs */
106 mddi_queue_register_write(REG_SUBTCMD, 0x0004 | sub_rs, FALSE, 0);
107
108 /* CS=0,RD=1,WE=1,RS=sub_rs */
109 mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
110
111 /* CS=1,RD=1,WE=1,RS=sub_rs */
112 mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, TRUE, 0);
113}
114
115static uint32 sub_through_read(int sub_rs)
116{
117 uint32 sub_data;
118
119 /* CS=1,RD=1,WE=1,RS=sub_rs */
120 mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, FALSE, 0);
121
122 /* CS=0,RD=1,WE=1,RS=sub_rs */
123 mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
124
125 /* CS=0,RD=1,WE=0,RS=sub_rs */
126 mddi_queue_register_write(REG_SUBTCMD, 0x0002 | sub_rs, TRUE, 0);
127
128 mddi_queue_register_read(REG_SUBTCMDD, &sub_data, TRUE, 0);
129
130 /* CS=0,RD=1,WE=1,RS=sub_rs */
131 mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
132
133 /* CS=1,RD=1,WE=1,RS=sub_rs */
134 mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, TRUE, 0);
135
136 return sub_data;
137}
138
139static void serigo(uint32 ssd)
140{
141 uint32 ssdctl;
142
143 mddi_queue_register_read(REG_SSDCTL, &ssdctl, TRUE, 0);
144 ssdctl = ((ssdctl & 0xE7) | 0x02);
145
146 mddi_queue_register_write(REG_SSD0, ssd, FALSE, 0);
147 mddi_queue_register_write(REG_SSDCTL, ssdctl, TRUE, 0);
148
149 do {
150 mddi_queue_register_read(REG_SSDCTL, &ssdctl, TRUE, 0);
151 } while ((ssdctl & 0x0002) != 0);
152
153 if (mddi_debug_prim_wait)
154 mddi_wait(2);
155}
156
157static void mddi_sharp_lcd_powerdown(void)
158{
159 serigo(0x0131);
160 serigo(0x0300);
161 mddi_wait(40);
162 serigo(0x0135);
163 mddi_wait(20);
164 serigo(0x2122);
165 mddi_wait(20);
166 serigo(0x0201);
167 mddi_wait(20);
168 serigo(0x2100);
169 mddi_wait(20);
170 serigo(0x2000);
171 mddi_wait(20);
172
173 mddi_queue_register_write(REG_PSTCTL1, 0x1, TRUE, 0);
174 mddi_wait(100);
175 mddi_queue_register_write(REG_PSTCTL1, 0x0, TRUE, 0);
176 mddi_wait(2);
177 mddi_queue_register_write(REG_SYSCTL, 0x1, TRUE, 0);
178 mddi_wait(2);
179 mddi_queue_register_write(REG_CLKDIV1, 0x3, TRUE, 0);
180 mddi_wait(2);
181 mddi_queue_register_write(REG_SSDCTL, 0x0000, TRUE, 0); /* SSDRESET */
182 mddi_queue_register_write(REG_SYSCTL, 0x0, TRUE, 0);
183 mddi_wait(2);
184}
185
186static void mddi_sharp_lcd_set_backlight(struct msm_fb_data_type *mfd)
187{
188 uint32 regdata;
189 int32 level;
190 int max = mfd->panel_info.bl_max;
191 int min = mfd->panel_info.bl_min;
192
193 if (mddi_sharp_pdata && mddi_sharp_pdata->backlight_level) {
194 level = mddi_sharp_pdata->backlight_level(mfd->bl_level,
195 max,
196 min);
197
198 if (level < 0)
199 return;
200
201 /* use Rodem GPIO(2:0) to give 8 levels of backlight (7-0) */
202 /* Set lower 3 GPIOs as Outputs (set to 0) */
203 mddi_queue_register_read(REG_GIOA, &regdata, TRUE, 0);
204 mddi_queue_register_write(REG_GIOA, regdata & 0xfff8, TRUE, 0);
205
206 /* Set lower 3 GPIOs as level */
207 mddi_queue_register_read(REG_GIOD, &regdata, TRUE, 0);
208 mddi_queue_register_write(REG_GIOD,
209 (regdata & 0xfff8) | (0x07 & level), TRUE, 0);
210 }
211}
212
213static void mddi_sharp_prim_lcd_init(void)
214{
215 mddi_queue_register_write(REG_SYSCTL, 0x4000, TRUE, 0);
216 mddi_wait(1);
217 mddi_queue_register_write(REG_SYSCTL, 0x0000, TRUE, 0);
218 mddi_wait(5);
219 mddi_queue_register_write(REG_SYSCTL, 0x0001, FALSE, 0);
220 mddi_queue_register_write(REG_CLKDIV1, 0x000b, FALSE, 0);
221
222 /* new reg write below */
223 if (mddi_sharp_debug_60hz_refresh)
224 mddi_queue_register_write(REG_CLKCNF, 0x070d, FALSE, 0);
225 else
226 mddi_queue_register_write(REG_CLKCNF, 0x0708, FALSE, 0);
227
228 mddi_queue_register_write(REG_SYSCTL, 0x0201, FALSE, 0);
229 mddi_queue_register_write(REG_PTGCTL, 0x0010, FALSE, 0);
230 mddi_queue_register_write(REG_PTHP, 4, FALSE, 0);
231 mddi_queue_register_write(REG_PTHB, 40, FALSE, 0);
232 mddi_queue_register_write(REG_PTHW, 240, FALSE, 0);
233 if (mddi_sharp_debug_60hz_refresh)
234 mddi_queue_register_write(REG_PTHF, 12, FALSE, 0);
235 else
236 mddi_queue_register_write(REG_PTHF, 92, FALSE, 0);
237
238 mddi_wait(1);
239
240 mddi_queue_register_write(REG_PTVP, 1, FALSE, 0);
241 mddi_queue_register_write(REG_PTVB, 2, FALSE, 0);
242 mddi_queue_register_write(REG_PTVW, 320, FALSE, 0);
243 mddi_queue_register_write(REG_PTVF, 15, FALSE, 0);
244
245 mddi_wait(1);
246
247 /* vram_color set REG_AGM???? */
248 mddi_queue_register_write(REG_AGM, 0x0000, TRUE, 0);
249
250 mddi_queue_register_write(REG_SSDCTL, 0x0000, FALSE, 0);
251 mddi_queue_register_write(REG_SSDCTL, 0x0001, TRUE, 0);
252 mddi_wait(1);
253 mddi_queue_register_write(REG_PSTCTL1, 0x0001, TRUE, 0);
254 mddi_wait(10);
255
256 serigo(0x0701);
257 /* software reset */
258 mddi_wait(1);
259 /* Wait over 50us */
260
261 serigo(0x0400);
262 /* DCLK~ACHSYNC~ACVSYNC polarity setting */
263 serigo(0x2900);
264 /* EEPROM start read address setting */
265 serigo(0x2606);
266 /* EEPROM start read register setting */
267 mddi_wait(20);
268 /* Wait over 20ms */
269
270 serigo(0x0503);
271 /* Horizontal timing setting */
272 serigo(0x062C);
273 /* Veritical timing setting */
274 serigo(0x2001);
275 /* power initialize setting(VDC2) */
276 mddi_wait(20);
277 /* Wait over 20ms */
278
279 serigo(0x2120);
280 /* Initialize power setting(CPS) */
281 mddi_wait(20);
282 /* Wait over 20ms */
283
284 serigo(0x2130);
285 /* Initialize power setting(CPS) */
286 mddi_wait(20);
287 /* Wait over 20ms */
288
289 serigo(0x2132);
290 /* Initialize power setting(CPS) */
291 mddi_wait(10);
292 /* Wait over 10ms */
293
294 serigo(0x2133);
295 /* Initialize power setting(CPS) */
296 mddi_wait(20);
297 /* Wait over 20ms */
298
299 serigo(0x0200);
300 /* Panel initialize release(INIT) */
301 mddi_wait(1);
302 /* Wait over 1ms */
303
304 serigo(0x0131);
305 /* Panel setting(CPS) */
306 mddi_wait(1);
307 /* Wait over 1ms */
308
309 mddi_queue_register_write(REG_PSTCTL1, 0x0003, TRUE, 0);
310
311 /* if (FFA LCD is upside down) -> serigo(0x0100); */
312 serigo(0x0130);
313
314 /* Black mask release(display ON) */
315 mddi_wait(1);
316 /* Wait over 1ms */
317
318 if (mddi_sharp_vsync_wake) {
319 mddi_queue_register_write(REG_VBLKS, 0x1001, TRUE, 0);
320 mddi_queue_register_write(REG_VBLKE, 0x1002, TRUE, 0);
321 }
322
323 /* Set the MDP pixel data attributes for Primary Display */
324 mddi_host_write_pix_attr_reg(0x00C3);
325 return;
326
327}
328
329void mddi_sharp_sub_lcd_init(void)
330{
331
332 mddi_queue_register_write(REG_SYSCTL, 0x4000, FALSE, 0);
333 mddi_queue_register_write(REG_SYSCTL, 0x0000, TRUE, 0);
334 mddi_wait(100);
335
336 mddi_queue_register_write(REG_SYSCTL, 0x0001, FALSE, 0);
337 mddi_queue_register_write(REG_CLKDIV1, 0x000b, FALSE, 0);
338 mddi_queue_register_write(REG_CLKCNF, 0x0708, FALSE, 0);
339 mddi_queue_register_write(REG_SYSCTL, 0x0201, FALSE, 0);
340 mddi_queue_register_write(REG_PTGCTL, 0x0010, FALSE, 0);
341 mddi_queue_register_write(REG_PTHP, 4, FALSE, 0);
342 mddi_queue_register_write(REG_PTHB, 40, FALSE, 0);
343 mddi_queue_register_write(REG_PTHW, 128, FALSE, 0);
344 mddi_queue_register_write(REG_PTHF, 92, FALSE, 0);
345 mddi_queue_register_write(REG_PTVP, 1, FALSE, 0);
346 mddi_queue_register_write(REG_PTVB, 2, FALSE, 0);
347 mddi_queue_register_write(REG_PTVW, 128, FALSE, 0);
348 mddi_queue_register_write(REG_PTVF, 15, FALSE, 0);
349
350 /* Now the sub display..... */
351 /* Reset High */
352 mddi_queue_register_write(REG_SUBCTL, 0x0200, FALSE, 0);
353 /* CS=1,RD=1,WE=1,RS=1 */
354 mddi_queue_register_write(REG_SUBTCMD, 0x000f, TRUE, 0);
355 mddi_wait(1);
356 /* Wait 5us */
357
358 if (sharp_subpanel_type == SHARP_SUB_UNKNOWN) {
359 uint32 data;
360
361 sub_through_write(1, 0x05);
362 sub_through_write(1, 0x6A);
363 sub_through_write(1, 0x1D);
364 sub_through_write(1, 0x05);
365 data = sub_through_read(1);
366 if (data == 0x6A) {
367 sharp_subpanel_type = SHARP_SUB_HYNIX;
368 } else {
369 sub_through_write(0, 0x36);
370 sub_through_write(1, 0xA8);
371 sub_through_write(0, 0x09);
372 data = sub_through_read(1);
373 data = sub_through_read(1);
374 if (data == 0x54) {
375 sub_through_write(0, 0x36);
376 sub_through_write(1, 0x00);
377 sharp_subpanel_type = SHARP_SUB_ROHM;
378 }
379 }
380 }
381
382 if (sharp_subpanel_type == SHARP_SUB_HYNIX) {
383 sub_through_write(1, 0x00); /* Display setting 1 */
384 sub_through_write(1, 0x04);
385 sub_through_write(1, 0x01);
386 sub_through_write(1, 0x05);
387 sub_through_write(1, 0x0280);
388 sub_through_write(1, 0x0301);
389 sub_through_write(1, 0x0402);
390 sub_through_write(1, 0x0500);
391 sub_through_write(1, 0x0681);
392 sub_through_write(1, 0x077F);
393 sub_through_write(1, 0x08C0);
394 sub_through_write(1, 0x0905);
395 sub_through_write(1, 0x0A02);
396 sub_through_write(1, 0x0B00);
397 sub_through_write(1, 0x0C00);
398 sub_through_write(1, 0x0D00);
399 sub_through_write(1, 0x0E00);
400 sub_through_write(1, 0x0F00);
401
402 sub_through_write(1, 0x100B); /* Display setting 2 */
403 sub_through_write(1, 0x1103);
404 sub_through_write(1, 0x1237);
405 sub_through_write(1, 0x1300);
406 sub_through_write(1, 0x1400);
407 sub_through_write(1, 0x1500);
408 sub_through_write(1, 0x1605);
409 sub_through_write(1, 0x1700);
410 sub_through_write(1, 0x1800);
411 sub_through_write(1, 0x192E);
412 sub_through_write(1, 0x1A00);
413 sub_through_write(1, 0x1B00);
414 sub_through_write(1, 0x1C00);
415
416 sub_through_write(1, 0x151A); /* Power setting */
417
418 sub_through_write(1, 0x2002); /* Gradation Palette setting */
419 sub_through_write(1, 0x2107);
420 sub_through_write(1, 0x220C);
421 sub_through_write(1, 0x2310);
422 sub_through_write(1, 0x2414);
423 sub_through_write(1, 0x2518);
424 sub_through_write(1, 0x261C);
425 sub_through_write(1, 0x2720);
426 sub_through_write(1, 0x2824);
427 sub_through_write(1, 0x2928);
428 sub_through_write(1, 0x2A2B);
429 sub_through_write(1, 0x2B2E);
430 sub_through_write(1, 0x2C31);
431 sub_through_write(1, 0x2D34);
432 sub_through_write(1, 0x2E37);
433 sub_through_write(1, 0x2F3A);
434 sub_through_write(1, 0x303C);
435 sub_through_write(1, 0x313E);
436 sub_through_write(1, 0x323F);
437 sub_through_write(1, 0x3340);
438 sub_through_write(1, 0x3441);
439 sub_through_write(1, 0x3543);
440 sub_through_write(1, 0x3646);
441 sub_through_write(1, 0x3749);
442 sub_through_write(1, 0x384C);
443 sub_through_write(1, 0x394F);
444 sub_through_write(1, 0x3A52);
445 sub_through_write(1, 0x3B59);
446 sub_through_write(1, 0x3C60);
447 sub_through_write(1, 0x3D67);
448 sub_through_write(1, 0x3E6E);
449 sub_through_write(1, 0x3F7F);
450 sub_through_write(1, 0x4001);
451 sub_through_write(1, 0x4107);
452 sub_through_write(1, 0x420C);
453 sub_through_write(1, 0x4310);
454 sub_through_write(1, 0x4414);
455 sub_through_write(1, 0x4518);
456 sub_through_write(1, 0x461C);
457 sub_through_write(1, 0x4720);
458 sub_through_write(1, 0x4824);
459 sub_through_write(1, 0x4928);
460 sub_through_write(1, 0x4A2B);
461 sub_through_write(1, 0x4B2E);
462 sub_through_write(1, 0x4C31);
463 sub_through_write(1, 0x4D34);
464 sub_through_write(1, 0x4E37);
465 sub_through_write(1, 0x4F3A);
466 sub_through_write(1, 0x503C);
467 sub_through_write(1, 0x513E);
468 sub_through_write(1, 0x523F);
469 sub_through_write(1, 0x5340);
470 sub_through_write(1, 0x5441);
471 sub_through_write(1, 0x5543);
472 sub_through_write(1, 0x5646);
473 sub_through_write(1, 0x5749);
474 sub_through_write(1, 0x584C);
475 sub_through_write(1, 0x594F);
476 sub_through_write(1, 0x5A52);
477 sub_through_write(1, 0x5B59);
478 sub_through_write(1, 0x5C60);
479 sub_through_write(1, 0x5D67);
480 sub_through_write(1, 0x5E6E);
481 sub_through_write(1, 0x5F7E);
482 sub_through_write(1, 0x6000);
483 sub_through_write(1, 0x6107);
484 sub_through_write(1, 0x620C);
485 sub_through_write(1, 0x6310);
486 sub_through_write(1, 0x6414);
487 sub_through_write(1, 0x6518);
488 sub_through_write(1, 0x661C);
489 sub_through_write(1, 0x6720);
490 sub_through_write(1, 0x6824);
491 sub_through_write(1, 0x6928);
492 sub_through_write(1, 0x6A2B);
493 sub_through_write(1, 0x6B2E);
494 sub_through_write(1, 0x6C31);
495 sub_through_write(1, 0x6D34);
496 sub_through_write(1, 0x6E37);
497 sub_through_write(1, 0x6F3A);
498 sub_through_write(1, 0x703C);
499 sub_through_write(1, 0x713E);
500 sub_through_write(1, 0x723F);
501 sub_through_write(1, 0x7340);
502 sub_through_write(1, 0x7441);
503 sub_through_write(1, 0x7543);
504 sub_through_write(1, 0x7646);
505 sub_through_write(1, 0x7749);
506 sub_through_write(1, 0x784C);
507 sub_through_write(1, 0x794F);
508 sub_through_write(1, 0x7A52);
509 sub_through_write(1, 0x7B59);
510 sub_through_write(1, 0x7C60);
511 sub_through_write(1, 0x7D67);
512 sub_through_write(1, 0x7E6E);
513 sub_through_write(1, 0x7F7D);
514
515 sub_through_write(1, 0x1851); /* Display on */
516
517 mddi_queue_register_write(REG_AGM, 0x0000, TRUE, 0);
518
519 /* 1 pixel / 1 post clock */
520 mddi_queue_register_write(REG_CLKDIV2, 0x3b00, FALSE, 0);
521
522 /* SUB LCD select */
523 mddi_queue_register_write(REG_PSTCTL2, 0x0080, FALSE, 0);
524
525 /* RS=0,command initiate number=0,select master mode */
526 mddi_queue_register_write(REG_SUBCTL, 0x0202, FALSE, 0);
527
528 /* Sub LCD Data transform start */
529 mddi_queue_register_write(REG_PSTCTL1, 0x0003, FALSE, 0);
530
531 } else if (sharp_subpanel_type == SHARP_SUB_ROHM) {
532
533 sub_through_write(0, 0x01); /* Display setting */
534 sub_through_write(1, 0x00);
535
536 mddi_wait(1);
537 /* Wait 100us <----- ******* Update 2005/01/24 */
538
539 sub_through_write(0, 0xB6);
540 sub_through_write(1, 0x0C);
541 sub_through_write(1, 0x4A);
542 sub_through_write(1, 0x20);
543 sub_through_write(0, 0x3A);
544 sub_through_write(1, 0x05);
545 sub_through_write(0, 0xB7);
546 sub_through_write(1, 0x01);
547 sub_through_write(0, 0xBA);
548 sub_through_write(1, 0x20);
549 sub_through_write(1, 0x02);
550 sub_through_write(0, 0x25);
551 sub_through_write(1, 0x4F);
552 sub_through_write(0, 0xBB);
553 sub_through_write(1, 0x00);
554 sub_through_write(0, 0x36);
555 sub_through_write(1, 0x00);
556 sub_through_write(0, 0xB1);
557 sub_through_write(1, 0x05);
558 sub_through_write(0, 0xBE);
559 sub_through_write(1, 0x80);
560 sub_through_write(0, 0x26);
561 sub_through_write(1, 0x01);
562 sub_through_write(0, 0x2A);
563 sub_through_write(1, 0x02);
564 sub_through_write(1, 0x81);
565 sub_through_write(0, 0x2B);
566 sub_through_write(1, 0x00);
567 sub_through_write(1, 0x7F);
568
569 sub_through_write(0, 0x2C);
570 sub_through_write(0, 0x11); /* Sleep mode off */
571
572 mddi_wait(1);
573 /* Wait 100 ms <----- ******* Update 2005/01/24 */
574
575 sub_through_write(0, 0x29); /* Display on */
576 sub_through_write(0, 0xB3);
577 sub_through_write(1, 0x20);
578 sub_through_write(1, 0xAA);
579 sub_through_write(1, 0xA0);
580 sub_through_write(1, 0x20);
581 sub_through_write(1, 0x30);
582 sub_through_write(1, 0xA6);
583 sub_through_write(1, 0xFF);
584 sub_through_write(1, 0x9A);
585 sub_through_write(1, 0x9F);
586 sub_through_write(1, 0xAF);
587 sub_through_write(1, 0xBC);
588 sub_through_write(1, 0xCF);
589 sub_through_write(1, 0xDF);
590 sub_through_write(1, 0x20);
591 sub_through_write(1, 0x9C);
592 sub_through_write(1, 0x8A);
593
594 sub_through_write(0, 0x002C); /* Display on */
595
596 /* 1 pixel / 2 post clock */
597 mddi_queue_register_write(REG_CLKDIV2, 0x7b00, FALSE, 0);
598
599 /* SUB LCD select */
600 mddi_queue_register_write(REG_PSTCTL2, 0x0080, FALSE, 0);
601
602 /* RS=1,command initiate number=0,select master mode */
603 mddi_queue_register_write(REG_SUBCTL, 0x0242, FALSE, 0);
604
605 /* Sub LCD Data transform start */
606 mddi_queue_register_write(REG_PSTCTL1, 0x0003, FALSE, 0);
607
608 }
609
610 /* Set the MDP pixel data attributes for Sub Display */
611 mddi_host_write_pix_attr_reg(0x00C0);
612}
613
614void mddi_sharp_lcd_vsync_detected(boolean detected)
615{
616 /* static timetick_type start_time = 0; */
617 static struct timeval start_time;
618 static boolean first_time = TRUE;
619 /* uint32 mdp_cnt_val = 0; */
620 /* timetick_type elapsed_us; */
621 struct timeval now;
622 uint32 elapsed_us;
623 uint32 num_vsyncs;
624
625 if ((detected) || (mddi_sharp_vsync_attempts > 5)) {
626 if ((detected) && (mddi_sharp_monitor_refresh_value)) {
627 /* if (start_time != 0) */
628 if (!first_time) {
629 jiffies_to_timeval(jiffies, &now);
630 elapsed_us =
631 (now.tv_sec - start_time.tv_sec) * 1000000 +
632 now.tv_usec - start_time.tv_usec;
633 /*
634 * LCD is configured for a refresh every usecs,
635 * so to determine the number of vsyncs that
636 * have occurred since the last measurement add
637 * half that to the time difference and divide
638 * by the refresh rate.
639 */
640 num_vsyncs = (elapsed_us +
641 (mddi_sharp_usecs_per_refresh >>
642 1)) /
643 mddi_sharp_usecs_per_refresh;
644 /*
645 * LCD is configured for * hsyncs (rows) per
646 * refresh cycle. Calculate new rows_per_second
647 * value based upon these new measurements.
648 * MDP can update with this new value.
649 */
650 mddi_sharp_rows_per_second =
651 (mddi_sharp_rows_per_refresh * 1000 *
652 num_vsyncs) / (elapsed_us / 1000);
653 }
654 /* start_time = timetick_get(); */
655 first_time = FALSE;
656 jiffies_to_timeval(jiffies, &start_time);
657 if (mddi_sharp_report_refresh_measurements) {
658 /* mdp_cnt_val = MDP_LINE_COUNT; */
659 }
660 }
661 /* if detected = TRUE, client initiated wakeup was detected */
662 if (mddi_sharp_vsync_handler != NULL) {
663 (*mddi_sharp_vsync_handler)
664 (mddi_sharp_vsync_handler_arg);
665 mddi_sharp_vsync_handler = NULL;
666 }
667 mddi_vsync_detect_enabled = FALSE;
668 mddi_sharp_vsync_attempts = 0;
669 /* need to clear this vsync wakeup */
670 if (!mddi_queue_register_write_int(REG_INTR, 0x0000)) {
671 MDDI_MSG_ERR("Vsync interrupt clear failed!\n");
672 }
673 if (!detected) {
674 /* give up after 5 failed attempts but show error */
675 MDDI_MSG_NOTICE("Vsync detection failed!\n");
676 } else if ((mddi_sharp_monitor_refresh_value) &&
677 (mddi_sharp_report_refresh_measurements)) {
678 MDDI_MSG_NOTICE(" Lines Per Second=%d!\n",
679 mddi_sharp_rows_per_second);
680 }
681 } else
682 /* if detected = FALSE, we woke up from hibernation, but did not
683 * detect client initiated wakeup.
684 */
685 mddi_sharp_vsync_attempts++;
686}
687
688/* ISR to be executed */
689void mddi_sharp_vsync_set_handler(msm_fb_vsync_handler_type handler, void *arg)
690{
691 boolean error = FALSE;
692 unsigned long flags;
693
694 /* Disable interrupts */
695 spin_lock_irqsave(&mddi_host_spin_lock, flags);
696 /* INTLOCK(); */
697
698 if (mddi_sharp_vsync_handler != NULL)
699 error = TRUE;
700
701 /* Register the handler for this particular GROUP interrupt source */
702 mddi_sharp_vsync_handler = handler;
703 mddi_sharp_vsync_handler_arg = arg;
704
705 /* Restore interrupts */
706 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
707 /* INTFREE(); */
708
709 if (error)
710 MDDI_MSG_ERR("MDDI: Previous Vsync handler never called\n");
711
712 /* Enable the vsync wakeup */
713 mddi_queue_register_write(REG_INTR, 0x8100, FALSE, 0);
714
715 mddi_sharp_vsync_attempts = 1;
716 mddi_vsync_detect_enabled = TRUE;
717} /* mddi_sharp_vsync_set_handler */
718
719static int mddi_sharp_lcd_on(struct platform_device *pdev)
720{
721 struct msm_fb_data_type *mfd;
722
723 mfd = platform_get_drvdata(pdev);
724
725 if (!mfd)
726 return -ENODEV;
727
728 if (mfd->key != MFD_KEY)
729 return -EINVAL;
730
731 if (mfd->panel.id == SHARP_QVGA_PRIM)
732 mddi_sharp_prim_lcd_init();
733 else
734 mddi_sharp_sub_lcd_init();
735
736 return 0;
737}
738
739static int mddi_sharp_lcd_off(struct platform_device *pdev)
740{
741 mddi_sharp_lcd_powerdown();
742 return 0;
743}
744
745static int __init mddi_sharp_probe(struct platform_device *pdev)
746{
747 if (pdev->id == 0) {
748 mddi_sharp_pdata = pdev->dev.platform_data;
749 return 0;
750 }
751
752 msm_fb_add_device(pdev);
753
754 return 0;
755}
756
757static struct platform_driver this_driver = {
758 .probe = mddi_sharp_probe,
759 .driver = {
760 .name = "mddi_sharp_qvga",
761 },
762};
763
764static struct msm_fb_panel_data mddi_sharp_panel_data0 = {
765 .on = mddi_sharp_lcd_on,
766 .off = mddi_sharp_lcd_off,
767 .set_backlight = mddi_sharp_lcd_set_backlight,
768 .set_vsync_notifier = mddi_sharp_vsync_set_handler,
769};
770
771static struct platform_device this_device_0 = {
772 .name = "mddi_sharp_qvga",
773 .id = SHARP_QVGA_PRIM,
774 .dev = {
775 .platform_data = &mddi_sharp_panel_data0,
776 }
777};
778
779static struct msm_fb_panel_data mddi_sharp_panel_data1 = {
780 .on = mddi_sharp_lcd_on,
781 .off = mddi_sharp_lcd_off,
782};
783
784static struct platform_device this_device_1 = {
785 .name = "mddi_sharp_qvga",
786 .id = SHARP_128X128_SECD,
787 .dev = {
788 .platform_data = &mddi_sharp_panel_data1,
789 }
790};
791
792static int __init mddi_sharp_init(void)
793{
794 int ret;
795 struct msm_panel_info *pinfo;
796
797#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
798 u32 id;
799
800 ret = msm_fb_detect_client("mddi_sharp_qvga");
801 if (ret == -ENODEV)
802 return 0;
803
804 if (ret) {
805 id = mddi_get_client_id();
806
807 if (((id >> 16) != 0x0) || ((id & 0xffff) != 0x8835))
808 return 0;
809 }
810#endif
811 if (mddi_host_core_version > 8) {
812 /* can use faster refresh with newer hw revisions */
813 mddi_sharp_debug_60hz_refresh = TRUE;
814
815 /* Timing variables for tracking vsync */
816 /* dot_clock = 6.00MHz
817 * horizontal count = 296
818 * vertical count = 338
819 * refresh rate = 6000000/(296+338) = 60Hz
820 */
821 mddi_sharp_rows_per_second = 20270; /* 6000000/296 */
822 mddi_sharp_rows_per_refresh = 338;
823 mddi_sharp_usecs_per_refresh = 16674; /* (296+338)/6000000 */
824 } else {
825 /* Timing variables for tracking vsync */
826 /* dot_clock = 5.20MHz
827 * horizontal count = 376
828 * vertical count = 338
829 * refresh rate = 5200000/(376+338) = 41Hz
830 */
831 mddi_sharp_rows_per_second = 13830; /* 5200000/376 */
832 mddi_sharp_rows_per_refresh = 338;
833 mddi_sharp_usecs_per_refresh = 24440; /* (376+338)/5200000 */
834 }
835
836 ret = platform_driver_register(&this_driver);
837 if (!ret) {
838 pinfo = &mddi_sharp_panel_data0.panel_info;
839 pinfo->xres = 240;
840 pinfo->yres = 320;
841 pinfo->type = MDDI_PANEL;
842 pinfo->pdest = DISPLAY_1;
843 pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
844 pinfo->wait_cycle = 0;
845 pinfo->bpp = 18;
846 pinfo->fb_num = 2;
847 pinfo->clk_rate = 122880000;
848 pinfo->clk_min = 120000000;
849 pinfo->clk_max = 125000000;
850 pinfo->lcd.vsync_enable = TRUE;
851 pinfo->lcd.refx100 =
852 (mddi_sharp_rows_per_second * 100) /
853 mddi_sharp_rows_per_refresh;
854 pinfo->lcd.v_back_porch = 12;
855 pinfo->lcd.v_front_porch = 6;
856 pinfo->lcd.v_pulse_width = 0;
857 pinfo->lcd.hw_vsync_mode = FALSE;
858 pinfo->lcd.vsync_notifier_period = (1 * HZ);
859 pinfo->bl_max = 7;
860 pinfo->bl_min = 1;
861
862 ret = platform_device_register(&this_device_0);
863 if (ret)
864 platform_driver_unregister(&this_driver);
865
866 pinfo = &mddi_sharp_panel_data1.panel_info;
867 pinfo->xres = 128;
868 pinfo->yres = 128;
869 pinfo->type = MDDI_PANEL;
870 pinfo->pdest = DISPLAY_2;
871 pinfo->mddi.vdopkt = 0x400;
872 pinfo->wait_cycle = 0;
873 pinfo->bpp = 18;
874 pinfo->clk_rate = 122880000;
875 pinfo->clk_min = 120000000;
876 pinfo->clk_max = 125000000;
877 pinfo->fb_num = 2;
878
879 ret = platform_device_register(&this_device_1);
880 if (ret) {
881 platform_device_unregister(&this_device_0);
882 platform_driver_unregister(&this_driver);
883 }
884 }
885
886 if (!ret)
887 mddi_lcd.vsync_detected = mddi_sharp_lcd_vsync_detected;
888
889 return ret;
890}
891
892module_init(mddi_sharp_init);
diff --git a/drivers/staging/msm/mddi_toshiba.c b/drivers/staging/msm/mddi_toshiba.c
new file mode 100644
index 000000000000..e96342d477a2
--- /dev/null
+++ b/drivers/staging/msm/mddi_toshiba.c
@@ -0,0 +1,1741 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19#include "mddihost.h"
20#include "mddihosti.h"
21#include "mddi_toshiba.h"
22
23#define TM_GET_DID(id) ((id) & 0xff)
24#define TM_GET_PID(id) (((id) & 0xff00)>>8)
25
26#define MDDI_CLIENT_CORE_BASE 0x108000
27#define LCD_CONTROL_BLOCK_BASE 0x110000
28#define SPI_BLOCK_BASE 0x120000
29#define PWM_BLOCK_BASE 0x140000
30#define SYSTEM_BLOCK1_BASE 0x160000
31
32#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18)
33#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C)
34#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20)
35#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
36#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28)
37#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C)
38
39#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44)
40#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48)
41#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C)
42#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50)
43#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54)
44
45#define SRST (LCD_CONTROL_BLOCK_BASE|0x00)
46#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04)
47#define START (LCD_CONTROL_BLOCK_BASE|0x08)
48#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C)
49
50#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
51#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C)
52#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
53
54#define PXL (LCD_CONTROL_BLOCK_BASE|0x30)
55#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
56#define HSW (LCD_CONTROL_BLOCK_BASE|0x38)
57#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
58#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40)
59#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44)
60#define VSW (LCD_CONTROL_BLOCK_BASE|0x48)
61#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C)
62#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50)
63#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
64#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
65#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60)
66#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64)
67#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68)
68#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C)
69#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70)
70#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74)
71#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78)
72#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C)
73#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80)
74#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84)
75#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88)
76#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C)
77#define MONI (LCD_CONTROL_BLOCK_BASE|0xB0)
78#define VPOS (LCD_CONTROL_BLOCK_BASE|0xC0)
79
80#define SSICTL (SPI_BLOCK_BASE|0x00)
81#define SSITIME (SPI_BLOCK_BASE|0x04)
82#define SSITX (SPI_BLOCK_BASE|0x08)
83#define SSIINTS (SPI_BLOCK_BASE|0x14)
84
85#define TIMER0LOAD (PWM_BLOCK_BASE|0x00)
86#define TIMER0CTRL (PWM_BLOCK_BASE|0x08)
87#define PWM0OFF (PWM_BLOCK_BASE|0x1C)
88#define TIMER1LOAD (PWM_BLOCK_BASE|0x20)
89#define TIMER1CTRL (PWM_BLOCK_BASE|0x28)
90#define PWM1OFF (PWM_BLOCK_BASE|0x3C)
91#define TIMER2LOAD (PWM_BLOCK_BASE|0x40)
92#define TIMER2CTRL (PWM_BLOCK_BASE|0x48)
93#define PWM2OFF (PWM_BLOCK_BASE|0x5C)
94#define PWMCR (PWM_BLOCK_BASE|0x68)
95
96#define GPIOIS (GPIO_BLOCK_BASE|0x08)
97#define GPIOIEV (GPIO_BLOCK_BASE|0x10)
98#define GPIOIC (GPIO_BLOCK_BASE|0x20)
99
100#define WKREQ (SYSTEM_BLOCK1_BASE|0x00)
101#define CLKENB (SYSTEM_BLOCK1_BASE|0x04)
102#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08)
103#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C)
104#define CNT_DIS (SYSTEM_BLOCK1_BASE|0x10)
105
106typedef enum {
107 TOSHIBA_STATE_OFF,
108 TOSHIBA_STATE_PRIM_SEC_STANDBY,
109 TOSHIBA_STATE_PRIM_SEC_READY,
110 TOSHIBA_STATE_PRIM_NORMAL_MODE,
111 TOSHIBA_STATE_SEC_NORMAL_MODE
112} mddi_toshiba_state_t;
113
114static uint32 mddi_toshiba_curr_vpos;
115static boolean mddi_toshiba_monitor_refresh_value = FALSE;
116static boolean mddi_toshiba_report_refresh_measurements = FALSE;
117
118boolean mddi_toshiba_61Hz_refresh = TRUE;
119
120/* Modifications to timing to increase refresh rate to > 60Hz.
121 * 20MHz dot clock.
122 * 646 total rows.
123 * 506 total columns.
124 * refresh rate = 61.19Hz
125 */
126static uint32 mddi_toshiba_rows_per_second = 39526;
127static uint32 mddi_toshiba_usecs_per_refresh = 16344;
128static uint32 mddi_toshiba_rows_per_refresh = 646;
129extern boolean mddi_vsync_detect_enabled;
130
131static msm_fb_vsync_handler_type mddi_toshiba_vsync_handler;
132static void *mddi_toshiba_vsync_handler_arg;
133static uint16 mddi_toshiba_vsync_attempts;
134
135static mddi_toshiba_state_t toshiba_state = TOSHIBA_STATE_OFF;
136
137static struct msm_panel_common_pdata *mddi_toshiba_pdata;
138
139static int mddi_toshiba_lcd_on(struct platform_device *pdev);
140static int mddi_toshiba_lcd_off(struct platform_device *pdev);
141
142static void mddi_toshiba_state_transition(mddi_toshiba_state_t a,
143 mddi_toshiba_state_t b)
144{
145 if (toshiba_state != a) {
146 MDDI_MSG_ERR("toshiba state trans. (%d->%d) found %d\n", a, b,
147 toshiba_state);
148 }
149 toshiba_state = b;
150}
151
152#define GORDON_REG_IMGCTL1 0x10 /* Image interface control 1 */
153#define GORDON_REG_IMGCTL2 0x11 /* Image interface control 2 */
154#define GORDON_REG_IMGSET1 0x12 /* Image interface settings 1 */
155#define GORDON_REG_IMGSET2 0x13 /* Image interface settings 2 */
156#define GORDON_REG_IVBP1 0x14 /* DM0: Vert back porch */
157#define GORDON_REG_IHBP1 0x15 /* DM0: Horiz back porch */
158#define GORDON_REG_IVNUM1 0x16 /* DM0: Num of vert lines */
159#define GORDON_REG_IHNUM1 0x17 /* DM0: Num of pixels per line */
160#define GORDON_REG_IVBP2 0x18 /* DM1: Vert back porch */
161#define GORDON_REG_IHBP2 0x19 /* DM1: Horiz back porch */
162#define GORDON_REG_IVNUM2 0x1A /* DM1: Num of vert lines */
163#define GORDON_REG_IHNUM2 0x1B /* DM1: Num of pixels per line */
164#define GORDON_REG_LCDIFCTL1 0x30 /* LCD interface control 1 */
165#define GORDON_REG_VALTRAN 0x31 /* LCD IF ctl: VALTRAN sync flag */
166#define GORDON_REG_AVCTL 0x33
167#define GORDON_REG_LCDIFCTL2 0x34 /* LCD interface control 2 */
168#define GORDON_REG_LCDIFCTL3 0x35 /* LCD interface control 3 */
169#define GORDON_REG_LCDIFSET1 0x36 /* LCD interface settings 1 */
170#define GORDON_REG_PCCTL 0x3C
171#define GORDON_REG_TPARAM1 0x40
172#define GORDON_REG_TLCDIF1 0x41
173#define GORDON_REG_TSSPB_ST1 0x42
174#define GORDON_REG_TSSPB_ED1 0x43
175#define GORDON_REG_TSCK_ST1 0x44
176#define GORDON_REG_TSCK_WD1 0x45
177#define GORDON_REG_TGSPB_VST1 0x46
178#define GORDON_REG_TGSPB_VED1 0x47
179#define GORDON_REG_TGSPB_CH1 0x48
180#define GORDON_REG_TGCK_ST1 0x49
181#define GORDON_REG_TGCK_ED1 0x4A
182#define GORDON_REG_TPCTL_ST1 0x4B
183#define GORDON_REG_TPCTL_ED1 0x4C
184#define GORDON_REG_TPCHG_ED1 0x4D
185#define GORDON_REG_TCOM_CH1 0x4E
186#define GORDON_REG_THBP1 0x4F
187#define GORDON_REG_TPHCTL1 0x50
188#define GORDON_REG_EVPH1 0x51
189#define GORDON_REG_EVPL1 0x52
190#define GORDON_REG_EVNH1 0x53
191#define GORDON_REG_EVNL1 0x54
192#define GORDON_REG_TBIAS1 0x55
193#define GORDON_REG_TPARAM2 0x56
194#define GORDON_REG_TLCDIF2 0x57
195#define GORDON_REG_TSSPB_ST2 0x58
196#define GORDON_REG_TSSPB_ED2 0x59
197#define GORDON_REG_TSCK_ST2 0x5A
198#define GORDON_REG_TSCK_WD2 0x5B
199#define GORDON_REG_TGSPB_VST2 0x5C
200#define GORDON_REG_TGSPB_VED2 0x5D
201#define GORDON_REG_TGSPB_CH2 0x5E
202#define GORDON_REG_TGCK_ST2 0x5F
203#define GORDON_REG_TGCK_ED2 0x60
204#define GORDON_REG_TPCTL_ST2 0x61
205#define GORDON_REG_TPCTL_ED2 0x62
206#define GORDON_REG_TPCHG_ED2 0x63
207#define GORDON_REG_TCOM_CH2 0x64
208#define GORDON_REG_THBP2 0x65
209#define GORDON_REG_TPHCTL2 0x66
210#define GORDON_REG_EVPH2 0x67
211#define GORDON_REG_EVPL2 0x68
212#define GORDON_REG_EVNH2 0x69
213#define GORDON_REG_EVNL2 0x6A
214#define GORDON_REG_TBIAS2 0x6B
215#define GORDON_REG_POWCTL 0x80
216#define GORDON_REG_POWOSC1 0x81
217#define GORDON_REG_POWOSC2 0x82
218#define GORDON_REG_POWSET 0x83
219#define GORDON_REG_POWTRM1 0x85
220#define GORDON_REG_POWTRM2 0x86
221#define GORDON_REG_POWTRM3 0x87
222#define GORDON_REG_POWTRMSEL 0x88
223#define GORDON_REG_POWHIZ 0x89
224
225void serigo(uint16 reg, uint8 data)
226{
227 uint32 mddi_val = 0;
228 mddi_queue_register_read(SSIINTS, &mddi_val, TRUE, 0);
229 if (mddi_val & (1 << 8))
230 mddi_wait(1);
231 /* No De-assert of CS and send 2 bytes */
232 mddi_val = 0x90000 | ((0x00FF & reg) << 8) | data;
233 mddi_queue_register_write(SSITX, mddi_val, TRUE, 0);
234}
235
236void gordon_init(void)
237{
238 /* Image interface settings ***/
239 serigo(GORDON_REG_IMGCTL2, 0x00);
240 serigo(GORDON_REG_IMGSET1, 0x01);
241
242 /* Exchange the RGB signal for J510(Softbank mobile) */
243 serigo(GORDON_REG_IMGSET2, 0x12);
244 serigo(GORDON_REG_LCDIFSET1, 0x00);
245 mddi_wait(2);
246
247 /* Pre-charge settings */
248 serigo(GORDON_REG_PCCTL, 0x09);
249 serigo(GORDON_REG_LCDIFCTL2, 0x1B);
250 mddi_wait(1);
251}
252
253void gordon_disp_on(void)
254{
255 /*gordon_dispmode setting */
256 /*VGA settings */
257 serigo(GORDON_REG_TPARAM1, 0x30);
258 serigo(GORDON_REG_TLCDIF1, 0x00);
259 serigo(GORDON_REG_TSSPB_ST1, 0x8B);
260 serigo(GORDON_REG_TSSPB_ED1, 0x93);
261 mddi_wait(2);
262 serigo(GORDON_REG_TSCK_ST1, 0x88);
263 serigo(GORDON_REG_TSCK_WD1, 0x00);
264 serigo(GORDON_REG_TGSPB_VST1, 0x01);
265 serigo(GORDON_REG_TGSPB_VED1, 0x02);
266 mddi_wait(2);
267 serigo(GORDON_REG_TGSPB_CH1, 0x5E);
268 serigo(GORDON_REG_TGCK_ST1, 0x80);
269 serigo(GORDON_REG_TGCK_ED1, 0x3C);
270 serigo(GORDON_REG_TPCTL_ST1, 0x50);
271 mddi_wait(2);
272 serigo(GORDON_REG_TPCTL_ED1, 0x74);
273 serigo(GORDON_REG_TPCHG_ED1, 0x78);
274 serigo(GORDON_REG_TCOM_CH1, 0x50);
275 serigo(GORDON_REG_THBP1, 0x84);
276 mddi_wait(2);
277 serigo(GORDON_REG_TPHCTL1, 0x00);
278 serigo(GORDON_REG_EVPH1, 0x70);
279 serigo(GORDON_REG_EVPL1, 0x64);
280 serigo(GORDON_REG_EVNH1, 0x56);
281 mddi_wait(2);
282 serigo(GORDON_REG_EVNL1, 0x48);
283 serigo(GORDON_REG_TBIAS1, 0x88);
284 mddi_wait(2);
285 serigo(GORDON_REG_TPARAM2, 0x28);
286 serigo(GORDON_REG_TLCDIF2, 0x14);
287 serigo(GORDON_REG_TSSPB_ST2, 0x49);
288 serigo(GORDON_REG_TSSPB_ED2, 0x4B);
289 mddi_wait(2);
290 serigo(GORDON_REG_TSCK_ST2, 0x4A);
291 serigo(GORDON_REG_TSCK_WD2, 0x02);
292 serigo(GORDON_REG_TGSPB_VST2, 0x02);
293 serigo(GORDON_REG_TGSPB_VED2, 0x03);
294 mddi_wait(2);
295 serigo(GORDON_REG_TGSPB_CH2, 0x2F);
296 serigo(GORDON_REG_TGCK_ST2, 0x40);
297 serigo(GORDON_REG_TGCK_ED2, 0x1E);
298 serigo(GORDON_REG_TPCTL_ST2, 0x2C);
299 mddi_wait(2);
300 serigo(GORDON_REG_TPCTL_ED2, 0x3A);
301 serigo(GORDON_REG_TPCHG_ED2, 0x3C);
302 serigo(GORDON_REG_TCOM_CH2, 0x28);
303 serigo(GORDON_REG_THBP2, 0x4D);
304 mddi_wait(2);
305 serigo(GORDON_REG_TPHCTL2, 0x1A);
306 mddi_wait(2);
307 serigo(GORDON_REG_IVBP1, 0x02);
308 serigo(GORDON_REG_IHBP1, 0x90);
309 serigo(GORDON_REG_IVNUM1, 0xA0);
310 serigo(GORDON_REG_IHNUM1, 0x78);
311 mddi_wait(2);
312 serigo(GORDON_REG_IVBP2, 0x02);
313 serigo(GORDON_REG_IHBP2, 0x48);
314 serigo(GORDON_REG_IVNUM2, 0x50);
315 serigo(GORDON_REG_IHNUM2, 0x3C);
316 mddi_wait(2);
317 serigo(GORDON_REG_POWCTL, 0x03);
318 mddi_wait(15);
319 serigo(GORDON_REG_POWCTL, 0x07);
320 mddi_wait(15);
321 serigo(GORDON_REG_POWCTL, 0x0F);
322 mddi_wait(15);
323 serigo(GORDON_REG_AVCTL, 0x03);
324 mddi_wait(15);
325 serigo(GORDON_REG_POWCTL, 0x1F);
326 mddi_wait(15);
327 serigo(GORDON_REG_POWCTL, 0x5F);
328 mddi_wait(15);
329 serigo(GORDON_REG_POWCTL, 0x7F);
330 mddi_wait(15);
331 serigo(GORDON_REG_LCDIFCTL1, 0x02);
332 mddi_wait(15);
333 serigo(GORDON_REG_IMGCTL1, 0x00);
334 mddi_wait(15);
335 serigo(GORDON_REG_LCDIFCTL3, 0x00);
336 mddi_wait(15);
337 serigo(GORDON_REG_VALTRAN, 0x01);
338 mddi_wait(15);
339 serigo(GORDON_REG_LCDIFCTL1, 0x03);
340 serigo(GORDON_REG_LCDIFCTL1, 0x03);
341 mddi_wait(1);
342}
343
344void gordon_disp_off(void)
345{
346 serigo(GORDON_REG_LCDIFCTL2, 0x7B);
347 serigo(GORDON_REG_VALTRAN, 0x01);
348 serigo(GORDON_REG_LCDIFCTL1, 0x02);
349 serigo(GORDON_REG_LCDIFCTL3, 0x01);
350 mddi_wait(20);
351 serigo(GORDON_REG_VALTRAN, 0x01);
352 serigo(GORDON_REG_IMGCTL1, 0x01);
353 serigo(GORDON_REG_LCDIFCTL1, 0x00);
354 mddi_wait(20);
355 serigo(GORDON_REG_POWCTL, 0x1F);
356 mddi_wait(40);
357 serigo(GORDON_REG_POWCTL, 0x07);
358 mddi_wait(40);
359 serigo(GORDON_REG_POWCTL, 0x03);
360 mddi_wait(40);
361 serigo(GORDON_REG_POWCTL, 0x00);
362 mddi_wait(40);
363}
364
365void gordon_disp_init(void)
366{
367 gordon_init();
368 mddi_wait(20);
369 gordon_disp_on();
370}
371
372static void toshiba_common_initial_setup(struct msm_fb_data_type *mfd)
373{
374 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) {
375 write_client_reg(DPSET0 , 0x4bec0066, TRUE);
376 write_client_reg(DPSET1 , 0x00000113, TRUE);
377 write_client_reg(DPSUS , 0x00000000, TRUE);
378 write_client_reg(DPRUN , 0x00000001, TRUE);
379 mddi_wait(5);
380 write_client_reg(SYSCKENA , 0x00000001, TRUE);
381 write_client_reg(CLKENB , 0x0000a0e9, TRUE);
382
383 write_client_reg(GPIODATA , 0x03FF0000, TRUE);
384 write_client_reg(GPIODIR , 0x0000024D, TRUE);
385 write_client_reg(GPIOSEL , 0x00000173, TRUE);
386 write_client_reg(GPIOPC , 0x03C300C0, TRUE);
387 write_client_reg(WKREQ , 0x00000000, TRUE);
388 write_client_reg(GPIOIS , 0x00000000, TRUE);
389 write_client_reg(GPIOIEV , 0x00000001, TRUE);
390 write_client_reg(GPIOIC , 0x000003FF, TRUE);
391 write_client_reg(GPIODATA , 0x00040004, TRUE);
392
393 write_client_reg(GPIODATA , 0x00080008, TRUE);
394 write_client_reg(DRAMPWR , 0x00000001, TRUE);
395 write_client_reg(CLKENB , 0x0000a0eb, TRUE);
396 write_client_reg(PWMCR , 0x00000000, TRUE);
397 mddi_wait(1);
398
399 write_client_reg(SSICTL , 0x00060399, TRUE);
400 write_client_reg(SSITIME , 0x00000100, TRUE);
401 write_client_reg(CNT_DIS , 0x00000002, TRUE);
402 write_client_reg(SSICTL , 0x0006039b, TRUE);
403
404 write_client_reg(SSITX , 0x00000000, TRUE);
405 mddi_wait(7);
406 write_client_reg(SSITX , 0x00000000, TRUE);
407 mddi_wait(7);
408 write_client_reg(SSITX , 0x00000000, TRUE);
409 mddi_wait(7);
410
411 write_client_reg(SSITX , 0x000800BA, TRUE);
412 write_client_reg(SSITX , 0x00000111, TRUE);
413 write_client_reg(SSITX , 0x00080036, TRUE);
414 write_client_reg(SSITX , 0x00000100, TRUE);
415 mddi_wait(1);
416 write_client_reg(SSITX , 0x0008003A, TRUE);
417 write_client_reg(SSITX , 0x00000160, TRUE);
418 write_client_reg(SSITX , 0x000800B1, TRUE);
419 write_client_reg(SSITX , 0x0000015D, TRUE);
420 mddi_wait(1);
421 write_client_reg(SSITX , 0x000800B2, TRUE);
422 write_client_reg(SSITX , 0x00000133, TRUE);
423 write_client_reg(SSITX , 0x000800B3, TRUE);
424 write_client_reg(SSITX , 0x00000122, TRUE);
425 mddi_wait(1);
426 write_client_reg(SSITX , 0x000800B4, TRUE);
427 write_client_reg(SSITX , 0x00000102, TRUE);
428 write_client_reg(SSITX , 0x000800B5, TRUE);
429 write_client_reg(SSITX , 0x0000011E, TRUE);
430 mddi_wait(1);
431 write_client_reg(SSITX , 0x000800B6, TRUE);
432 write_client_reg(SSITX , 0x00000127, TRUE);
433 write_client_reg(SSITX , 0x000800B7, TRUE);
434 write_client_reg(SSITX , 0x00000103, TRUE);
435 mddi_wait(1);
436 write_client_reg(SSITX , 0x000800B9, TRUE);
437 write_client_reg(SSITX , 0x00000124, TRUE);
438 write_client_reg(SSITX , 0x000800BD, TRUE);
439 write_client_reg(SSITX , 0x000001A1, TRUE);
440 mddi_wait(1);
441 write_client_reg(SSITX , 0x000800BB, TRUE);
442 write_client_reg(SSITX , 0x00000100, TRUE);
443 write_client_reg(SSITX , 0x000800BF, TRUE);
444 write_client_reg(SSITX , 0x00000101, TRUE);
445 mddi_wait(1);
446 write_client_reg(SSITX , 0x000800BE, TRUE);
447 write_client_reg(SSITX , 0x00000100, TRUE);
448 write_client_reg(SSITX , 0x000800C0, TRUE);
449 write_client_reg(SSITX , 0x00000111, TRUE);
450 mddi_wait(1);
451 write_client_reg(SSITX , 0x000800C1, TRUE);
452 write_client_reg(SSITX , 0x00000111, TRUE);
453 write_client_reg(SSITX , 0x000800C2, TRUE);
454 write_client_reg(SSITX , 0x00000111, TRUE);
455 mddi_wait(1);
456 write_client_reg(SSITX , 0x000800C3, TRUE);
457 write_client_reg(SSITX , 0x00080132, TRUE);
458 write_client_reg(SSITX , 0x00000132, TRUE);
459 mddi_wait(1);
460 write_client_reg(SSITX , 0x000800C4, TRUE);
461 write_client_reg(SSITX , 0x00080132, TRUE);
462 write_client_reg(SSITX , 0x00000132, TRUE);
463 mddi_wait(1);
464 write_client_reg(SSITX , 0x000800C5, TRUE);
465 write_client_reg(SSITX , 0x00080132, TRUE);
466 write_client_reg(SSITX , 0x00000132, TRUE);
467 mddi_wait(1);
468 write_client_reg(SSITX , 0x000800C6, TRUE);
469 write_client_reg(SSITX , 0x00080132, TRUE);
470 write_client_reg(SSITX , 0x00000132, TRUE);
471 mddi_wait(1);
472 write_client_reg(SSITX , 0x000800C7, TRUE);
473 write_client_reg(SSITX , 0x00080164, TRUE);
474 write_client_reg(SSITX , 0x00000145, TRUE);
475 mddi_wait(1);
476 write_client_reg(SSITX , 0x000800C8, TRUE);
477 write_client_reg(SSITX , 0x00000144, TRUE);
478 write_client_reg(SSITX , 0x000800C9, TRUE);
479 write_client_reg(SSITX , 0x00000152, TRUE);
480 mddi_wait(1);
481 write_client_reg(SSITX , 0x000800CA, TRUE);
482 write_client_reg(SSITX , 0x00000100, TRUE);
483 mddi_wait(1);
484 write_client_reg(SSITX , 0x000800EC, TRUE);
485 write_client_reg(SSITX , 0x00080101, TRUE);
486 write_client_reg(SSITX , 0x000001FC, TRUE);
487 mddi_wait(1);
488 write_client_reg(SSITX , 0x000800CF, TRUE);
489 write_client_reg(SSITX , 0x00000101, TRUE);
490 mddi_wait(1);
491 write_client_reg(SSITX , 0x000800D0, TRUE);
492 write_client_reg(SSITX , 0x00080110, TRUE);
493 write_client_reg(SSITX , 0x00000104, TRUE);
494 mddi_wait(1);
495 write_client_reg(SSITX , 0x000800D1, TRUE);
496 write_client_reg(SSITX , 0x00000101, TRUE);
497 mddi_wait(1);
498 write_client_reg(SSITX , 0x000800D2, TRUE);
499 write_client_reg(SSITX , 0x00080100, TRUE);
500 write_client_reg(SSITX , 0x00000128, TRUE);
501 mddi_wait(1);
502 write_client_reg(SSITX , 0x000800D3, TRUE);
503 write_client_reg(SSITX , 0x00080100, TRUE);
504 write_client_reg(SSITX , 0x00000128, TRUE);
505 mddi_wait(1);
506 write_client_reg(SSITX , 0x000800D4, TRUE);
507 write_client_reg(SSITX , 0x00080126, TRUE);
508 write_client_reg(SSITX , 0x000001A4, TRUE);
509 mddi_wait(1);
510 write_client_reg(SSITX , 0x000800D5, TRUE);
511 write_client_reg(SSITX , 0x00000120, TRUE);
512 mddi_wait(1);
513 write_client_reg(SSITX , 0x000800EF, TRUE);
514 write_client_reg(SSITX , 0x00080132, TRUE);
515 write_client_reg(SSITX , 0x00000100, TRUE);
516 mddi_wait(1);
517
518 write_client_reg(BITMAP0 , 0x032001E0, TRUE);
519 write_client_reg(BITMAP1 , 0x032001E0, TRUE);
520 write_client_reg(BITMAP2 , 0x014000F0, TRUE);
521 write_client_reg(BITMAP3 , 0x014000F0, TRUE);
522 write_client_reg(BITMAP4 , 0x014000F0, TRUE);
523 write_client_reg(CLKENB , 0x0000A1EB, TRUE);
524 write_client_reg(PORT_ENB , 0x00000001, TRUE);
525 write_client_reg(PORT , 0x00000004, TRUE);
526 write_client_reg(PXL , 0x00000002, TRUE);
527 write_client_reg(MPLFBUF , 0x00000000, TRUE);
528 write_client_reg(HCYCLE , 0x000000FD, TRUE);
529 write_client_reg(HSW , 0x00000003, TRUE);
530 write_client_reg(HDE_START , 0x00000007, TRUE);
531 write_client_reg(HDE_SIZE , 0x000000EF, TRUE);
532 write_client_reg(VCYCLE , 0x00000325, TRUE);
533 write_client_reg(VSW , 0x00000001, TRUE);
534 write_client_reg(VDE_START , 0x00000003, TRUE);
535 write_client_reg(VDE_SIZE , 0x0000031F, TRUE);
536 write_client_reg(START , 0x00000001, TRUE);
537 mddi_wait(32);
538 write_client_reg(SSITX , 0x000800BC, TRUE);
539 write_client_reg(SSITX , 0x00000180, TRUE);
540 write_client_reg(SSITX , 0x0008003B, TRUE);
541 write_client_reg(SSITX , 0x00000100, TRUE);
542 mddi_wait(1);
543 write_client_reg(SSITX , 0x000800B0, TRUE);
544 write_client_reg(SSITX , 0x00000116, TRUE);
545 mddi_wait(1);
546 write_client_reg(SSITX , 0x000800B8, TRUE);
547 write_client_reg(SSITX , 0x000801FF, TRUE);
548 write_client_reg(SSITX , 0x000001F5, TRUE);
549 mddi_wait(1);
550 write_client_reg(SSITX , 0x00000011, TRUE);
551 mddi_wait(5);
552 write_client_reg(SSITX , 0x00000029, TRUE);
553 return;
554 }
555
556 if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) {
557 write_client_reg(DPSET0, 0x4BEC0066, TRUE);
558 write_client_reg(DPSET1, 0x00000113, TRUE);
559 write_client_reg(DPSUS, 0x00000000, TRUE);
560 write_client_reg(DPRUN, 0x00000001, TRUE);
561 mddi_wait(14);
562 write_client_reg(SYSCKENA, 0x00000001, TRUE);
563 write_client_reg(CLKENB, 0x000000EF, TRUE);
564 write_client_reg(GPIO_BLOCK_BASE, 0x03FF0000, TRUE);
565 write_client_reg(GPIODIR, 0x0000024D, TRUE);
566 write_client_reg(SYSTEM_BLOCK2_BASE, 0x00000173, TRUE);
567 write_client_reg(GPIOPC, 0x03C300C0, TRUE);
568 write_client_reg(SYSTEM_BLOCK1_BASE, 0x00000000, TRUE);
569 write_client_reg(GPIOIS, 0x00000000, TRUE);
570 write_client_reg(GPIOIEV, 0x00000001, TRUE);
571 write_client_reg(GPIOIC, 0x000003FF, TRUE);
572 write_client_reg(GPIO_BLOCK_BASE, 0x00060006, TRUE);
573 write_client_reg(GPIO_BLOCK_BASE, 0x00080008, TRUE);
574 write_client_reg(GPIO_BLOCK_BASE, 0x02000200, TRUE);
575 write_client_reg(DRAMPWR, 0x00000001, TRUE);
576 write_client_reg(TIMER0CTRL, 0x00000060, TRUE);
577 write_client_reg(PWM_BLOCK_BASE, 0x00001388, TRUE);
578 write_client_reg(PWM0OFF, 0x00001387, TRUE);
579 write_client_reg(TIMER1CTRL, 0x00000060, TRUE);
580 write_client_reg(TIMER1LOAD, 0x00001388, TRUE);
581 write_client_reg(PWM1OFF, 0x00001387, TRUE);
582 write_client_reg(TIMER0CTRL, 0x000000E0, TRUE);
583 write_client_reg(TIMER1CTRL, 0x000000E0, TRUE);
584 write_client_reg(PWMCR, 0x00000003, TRUE);
585 mddi_wait(1);
586 write_client_reg(SPI_BLOCK_BASE, 0x00063111, TRUE);
587 write_client_reg(SSITIME, 0x00000100, TRUE);
588 write_client_reg(SPI_BLOCK_BASE, 0x00063113, TRUE);
589 mddi_wait(1);
590 write_client_reg(SSITX, 0x00000000, TRUE);
591 mddi_wait(1);
592 write_client_reg(SSITX, 0x00000000, TRUE);
593 mddi_wait(1);
594 write_client_reg(SSITX, 0x00000000, TRUE);
595 mddi_wait(1);
596 write_client_reg(CLKENB, 0x0000A1EF, TRUE);
597 write_client_reg(START, 0x00000000, TRUE);
598 write_client_reg(WRSTB, 0x0000003F, TRUE);
599 write_client_reg(RDSTB, 0x00000432, TRUE);
600 write_client_reg(PORT_ENB, 0x00000002, TRUE);
601 write_client_reg(VSYNIF, 0x00000000, TRUE);
602 write_client_reg(ASY_DATA, 0x80000000, TRUE);
603 write_client_reg(ASY_DATB, 0x00000001, TRUE);
604 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
605 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
606 mddi_wait(10);
607 write_client_reg(ASY_DATA, 0x80000000, TRUE);
608 write_client_reg(ASY_DATB, 0x80000000, TRUE);
609 write_client_reg(ASY_DATC, 0x80000000, TRUE);
610 write_client_reg(ASY_DATD, 0x80000000, TRUE);
611 write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
612 write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
613 write_client_reg(ASY_DATA, 0x80000007, TRUE);
614 write_client_reg(ASY_DATB, 0x00004005, TRUE);
615 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
616 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
617 mddi_wait(20);
618 write_client_reg(ASY_DATA, 0x80000059, TRUE);
619 write_client_reg(ASY_DATB, 0x00000000, TRUE);
620 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
621 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
622
623 write_client_reg(VSYNIF, 0x00000001, TRUE);
624 write_client_reg(PORT_ENB, 0x00000001, TRUE);
625 } else {
626 write_client_reg(DPSET0, 0x4BEC0066, TRUE);
627 write_client_reg(DPSET1, 0x00000113, TRUE);
628 write_client_reg(DPSUS, 0x00000000, TRUE);
629 write_client_reg(DPRUN, 0x00000001, TRUE);
630 mddi_wait(14);
631 write_client_reg(SYSCKENA, 0x00000001, TRUE);
632 write_client_reg(CLKENB, 0x000000EF, TRUE);
633 write_client_reg(GPIODATA, 0x03FF0000, TRUE);
634 write_client_reg(GPIODIR, 0x0000024D, TRUE);
635 write_client_reg(GPIOSEL, 0x00000173, TRUE);
636 write_client_reg(GPIOPC, 0x03C300C0, TRUE);
637 write_client_reg(WKREQ, 0x00000000, TRUE);
638 write_client_reg(GPIOIS, 0x00000000, TRUE);
639 write_client_reg(GPIOIEV, 0x00000001, TRUE);
640 write_client_reg(GPIOIC, 0x000003FF, TRUE);
641 write_client_reg(GPIODATA, 0x00060006, TRUE);
642 write_client_reg(GPIODATA, 0x00080008, TRUE);
643 write_client_reg(GPIODATA, 0x02000200, TRUE);
644
645 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA) {
646 mddi_wait(400);
647 write_client_reg(DRAMPWR, 0x00000001, TRUE);
648
649 write_client_reg(CNT_DIS, 0x00000002, TRUE);
650 write_client_reg(BITMAP0, 0x01E00320, TRUE);
651 write_client_reg(PORT_ENB, 0x00000001, TRUE);
652 write_client_reg(PORT, 0x00000004, TRUE);
653 write_client_reg(PXL, 0x0000003A, TRUE);
654 write_client_reg(MPLFBUF, 0x00000000, TRUE);
655 write_client_reg(HCYCLE, 0x00000253, TRUE);
656 write_client_reg(HSW, 0x00000003, TRUE);
657 write_client_reg(HDE_START, 0x00000017, TRUE);
658 write_client_reg(HDE_SIZE, 0x0000018F, TRUE);
659 write_client_reg(VCYCLE, 0x000001FF, TRUE);
660 write_client_reg(VSW, 0x00000001, TRUE);
661 write_client_reg(VDE_START, 0x00000003, TRUE);
662 write_client_reg(VDE_SIZE, 0x000001DF, TRUE);
663 write_client_reg(START, 0x00000001, TRUE);
664 mddi_wait(1);
665 write_client_reg(TIMER0CTRL, 0x00000060, TRUE);
666 write_client_reg(TIMER0LOAD, 0x00001388, TRUE);
667 write_client_reg(TIMER1CTRL, 0x00000060, TRUE);
668 write_client_reg(TIMER1LOAD, 0x00001388, TRUE);
669 write_client_reg(PWM1OFF, 0x00000087, TRUE);
670 } else {
671 write_client_reg(DRAMPWR, 0x00000001, TRUE);
672 write_client_reg(TIMER0CTRL, 0x00000060, TRUE);
673 write_client_reg(TIMER0LOAD, 0x00001388, TRUE);
674 write_client_reg(TIMER1CTRL, 0x00000060, TRUE);
675 write_client_reg(TIMER1LOAD, 0x00001388, TRUE);
676 write_client_reg(PWM1OFF, 0x00001387, TRUE);
677 }
678
679 write_client_reg(TIMER0CTRL, 0x000000E0, TRUE);
680 write_client_reg(TIMER1CTRL, 0x000000E0, TRUE);
681 write_client_reg(PWMCR, 0x00000003, TRUE);
682 mddi_wait(1);
683 write_client_reg(SSICTL, 0x00000799, TRUE);
684 write_client_reg(SSITIME, 0x00000100, TRUE);
685 write_client_reg(SSICTL, 0x0000079b, TRUE);
686 write_client_reg(SSITX, 0x00000000, TRUE);
687 mddi_wait(1);
688 write_client_reg(SSITX, 0x00000000, TRUE);
689 mddi_wait(1);
690 write_client_reg(SSITX, 0x00000000, TRUE);
691 mddi_wait(1);
692 write_client_reg(SSITX, 0x000800BA, TRUE);
693 write_client_reg(SSITX, 0x00000111, TRUE);
694 write_client_reg(SSITX, 0x00080036, TRUE);
695 write_client_reg(SSITX, 0x00000100, TRUE);
696 mddi_wait(2);
697 write_client_reg(SSITX, 0x000800BB, TRUE);
698 write_client_reg(SSITX, 0x00000100, TRUE);
699 write_client_reg(SSITX, 0x0008003A, TRUE);
700 write_client_reg(SSITX, 0x00000160, TRUE);
701 mddi_wait(2);
702 write_client_reg(SSITX, 0x000800BF, TRUE);
703 write_client_reg(SSITX, 0x00000100, TRUE);
704 write_client_reg(SSITX, 0x000800B1, TRUE);
705 write_client_reg(SSITX, 0x0000015D, TRUE);
706 mddi_wait(2);
707 write_client_reg(SSITX, 0x000800B2, TRUE);
708 write_client_reg(SSITX, 0x00000133, TRUE);
709 write_client_reg(SSITX, 0x000800B3, TRUE);
710 write_client_reg(SSITX, 0x00000122, TRUE);
711 mddi_wait(2);
712 write_client_reg(SSITX, 0x000800B4, TRUE);
713 write_client_reg(SSITX, 0x00000102, TRUE);
714 write_client_reg(SSITX, 0x000800B5, TRUE);
715 write_client_reg(SSITX, 0x0000011F, TRUE);
716 mddi_wait(2);
717 write_client_reg(SSITX, 0x000800B6, TRUE);
718 write_client_reg(SSITX, 0x00000128, TRUE);
719 write_client_reg(SSITX, 0x000800B7, TRUE);
720 write_client_reg(SSITX, 0x00000103, TRUE);
721 mddi_wait(2);
722 write_client_reg(SSITX, 0x000800B9, TRUE);
723 write_client_reg(SSITX, 0x00000120, TRUE);
724 write_client_reg(SSITX, 0x000800BD, TRUE);
725 write_client_reg(SSITX, 0x00000102, TRUE);
726 mddi_wait(2);
727 write_client_reg(SSITX, 0x000800BE, TRUE);
728 write_client_reg(SSITX, 0x00000100, TRUE);
729 write_client_reg(SSITX, 0x000800C0, TRUE);
730 write_client_reg(SSITX, 0x00000111, TRUE);
731 mddi_wait(2);
732 write_client_reg(SSITX, 0x000800C1, TRUE);
733 write_client_reg(SSITX, 0x00000111, TRUE);
734 write_client_reg(SSITX, 0x000800C2, TRUE);
735 write_client_reg(SSITX, 0x00000111, TRUE);
736 mddi_wait(2);
737 write_client_reg(SSITX, 0x000800C3, TRUE);
738 write_client_reg(SSITX, 0x0008010A, TRUE);
739 write_client_reg(SSITX, 0x0000010A, TRUE);
740 mddi_wait(2);
741 write_client_reg(SSITX, 0x000800C4, TRUE);
742 write_client_reg(SSITX, 0x00080160, TRUE);
743 write_client_reg(SSITX, 0x00000160, TRUE);
744 mddi_wait(2);
745 write_client_reg(SSITX, 0x000800C5, TRUE);
746 write_client_reg(SSITX, 0x00080160, TRUE);
747 write_client_reg(SSITX, 0x00000160, TRUE);
748 mddi_wait(2);
749 write_client_reg(SSITX, 0x000800C6, TRUE);
750 write_client_reg(SSITX, 0x00080160, TRUE);
751 write_client_reg(SSITX, 0x00000160, TRUE);
752 mddi_wait(2);
753 write_client_reg(SSITX, 0x000800C7, TRUE);
754 write_client_reg(SSITX, 0x00080133, TRUE);
755 write_client_reg(SSITX, 0x00000143, TRUE);
756 mddi_wait(2);
757 write_client_reg(SSITX, 0x000800C8, TRUE);
758 write_client_reg(SSITX, 0x00000144, TRUE);
759 write_client_reg(SSITX, 0x000800C9, TRUE);
760 write_client_reg(SSITX, 0x00000133, TRUE);
761 mddi_wait(2);
762 write_client_reg(SSITX, 0x000800CA, TRUE);
763 write_client_reg(SSITX, 0x00000100, TRUE);
764 mddi_wait(2);
765 write_client_reg(SSITX, 0x000800EC, TRUE);
766 write_client_reg(SSITX, 0x00080102, TRUE);
767 write_client_reg(SSITX, 0x00000118, TRUE);
768 mddi_wait(2);
769 write_client_reg(SSITX, 0x000800CF, TRUE);
770 write_client_reg(SSITX, 0x00000101, TRUE);
771 mddi_wait(2);
772 write_client_reg(SSITX, 0x000800D0, TRUE);
773 write_client_reg(SSITX, 0x00080110, TRUE);
774 write_client_reg(SSITX, 0x00000104, TRUE);
775 mddi_wait(2);
776 write_client_reg(SSITX, 0x000800D1, TRUE);
777 write_client_reg(SSITX, 0x00000101, TRUE);
778 mddi_wait(2);
779 write_client_reg(SSITX, 0x000800D2, TRUE);
780 write_client_reg(SSITX, 0x00080100, TRUE);
781 write_client_reg(SSITX, 0x0000013A, TRUE);
782 mddi_wait(2);
783 write_client_reg(SSITX, 0x000800D3, TRUE);
784 write_client_reg(SSITX, 0x00080100, TRUE);
785 write_client_reg(SSITX, 0x0000013A, TRUE);
786 mddi_wait(2);
787 write_client_reg(SSITX, 0x000800D4, TRUE);
788 write_client_reg(SSITX, 0x00080124, TRUE);
789 write_client_reg(SSITX, 0x0000016E, TRUE);
790 mddi_wait(1);
791 write_client_reg(SSITX, 0x000800D5, TRUE);
792 write_client_reg(SSITX, 0x00000124, TRUE);
793 mddi_wait(2);
794 write_client_reg(SSITX, 0x000800ED, TRUE);
795 write_client_reg(SSITX, 0x00080101, TRUE);
796 write_client_reg(SSITX, 0x0000010A, TRUE);
797 mddi_wait(2);
798 write_client_reg(SSITX, 0x000800D6, TRUE);
799 write_client_reg(SSITX, 0x00000101, TRUE);
800 mddi_wait(2);
801 write_client_reg(SSITX, 0x000800D7, TRUE);
802 write_client_reg(SSITX, 0x00080110, TRUE);
803 write_client_reg(SSITX, 0x0000010A, TRUE);
804 mddi_wait(2);
805 write_client_reg(SSITX, 0x000800D8, TRUE);
806 write_client_reg(SSITX, 0x00000101, TRUE);
807 mddi_wait(2);
808 write_client_reg(SSITX, 0x000800D9, TRUE);
809 write_client_reg(SSITX, 0x00080100, TRUE);
810 write_client_reg(SSITX, 0x00000114, TRUE);
811 mddi_wait(2);
812 write_client_reg(SSITX, 0x000800DE, TRUE);
813 write_client_reg(SSITX, 0x00080100, TRUE);
814 write_client_reg(SSITX, 0x00000114, TRUE);
815 mddi_wait(2);
816 write_client_reg(SSITX, 0x000800DF, TRUE);
817 write_client_reg(SSITX, 0x00080112, TRUE);
818 write_client_reg(SSITX, 0x0000013F, TRUE);
819 mddi_wait(2);
820 write_client_reg(SSITX, 0x000800E0, TRUE);
821 write_client_reg(SSITX, 0x0000010B, TRUE);
822 write_client_reg(SSITX, 0x000800E2, TRUE);
823 write_client_reg(SSITX, 0x00000101, TRUE);
824 mddi_wait(2);
825 write_client_reg(SSITX, 0x000800E3, TRUE);
826 write_client_reg(SSITX, 0x00000136, TRUE);
827 mddi_wait(2);
828 write_client_reg(SSITX, 0x000800E4, TRUE);
829 write_client_reg(SSITX, 0x00080100, TRUE);
830 write_client_reg(SSITX, 0x00000103, TRUE);
831 mddi_wait(2);
832 write_client_reg(SSITX, 0x000800E5, TRUE);
833 write_client_reg(SSITX, 0x00080102, TRUE);
834 write_client_reg(SSITX, 0x00000104, TRUE);
835 mddi_wait(2);
836 write_client_reg(SSITX, 0x000800E6, TRUE);
837 write_client_reg(SSITX, 0x00000103, TRUE);
838 mddi_wait(2);
839 write_client_reg(SSITX, 0x000800E7, TRUE);
840 write_client_reg(SSITX, 0x00080104, TRUE);
841 write_client_reg(SSITX, 0x0000010A, TRUE);
842 mddi_wait(2);
843 write_client_reg(SSITX, 0x000800E8, TRUE);
844 write_client_reg(SSITX, 0x00000104, TRUE);
845 write_client_reg(CLKENB, 0x000001EF, TRUE);
846 write_client_reg(START, 0x00000000, TRUE);
847 write_client_reg(WRSTB, 0x0000003F, TRUE);
848 write_client_reg(RDSTB, 0x00000432, TRUE);
849 write_client_reg(PORT_ENB, 0x00000002, TRUE);
850 write_client_reg(VSYNIF, 0x00000000, TRUE);
851 write_client_reg(ASY_DATA, 0x80000000, TRUE);
852 write_client_reg(ASY_DATB, 0x00000001, TRUE);
853 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
854 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
855 mddi_wait(10);
856 write_client_reg(ASY_DATA, 0x80000000, TRUE);
857 write_client_reg(ASY_DATB, 0x80000000, TRUE);
858 write_client_reg(ASY_DATC, 0x80000000, TRUE);
859 write_client_reg(ASY_DATD, 0x80000000, TRUE);
860 write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
861 write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
862 write_client_reg(ASY_DATA, 0x80000007, TRUE);
863 write_client_reg(ASY_DATB, 0x00004005, TRUE);
864 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
865 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
866 mddi_wait(20);
867 write_client_reg(ASY_DATA, 0x80000059, TRUE);
868 write_client_reg(ASY_DATB, 0x00000000, TRUE);
869 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
870 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
871 write_client_reg(VSYNIF, 0x00000001, TRUE);
872 write_client_reg(PORT_ENB, 0x00000001, TRUE);
873 }
874
875 mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_STANDBY,
876 TOSHIBA_STATE_PRIM_SEC_READY);
877}
878
879static void toshiba_prim_start(struct msm_fb_data_type *mfd)
880{
881 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
882 return;
883
884 if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) {
885 write_client_reg(BITMAP1, 0x01E000F0, TRUE);
886 write_client_reg(BITMAP2, 0x01E000F0, TRUE);
887 write_client_reg(BITMAP3, 0x01E000F0, TRUE);
888 write_client_reg(BITMAP4, 0x00DC00B0, TRUE);
889 write_client_reg(CLKENB, 0x000001EF, TRUE);
890 write_client_reg(PORT_ENB, 0x00000001, TRUE);
891 write_client_reg(PORT, 0x00000016, TRUE);
892 write_client_reg(PXL, 0x00000002, TRUE);
893 write_client_reg(MPLFBUF, 0x00000000, TRUE);
894 write_client_reg(HCYCLE, 0x00000185, TRUE);
895 write_client_reg(HSW, 0x00000018, TRUE);
896 write_client_reg(HDE_START, 0x0000004A, TRUE);
897 write_client_reg(HDE_SIZE, 0x000000EF, TRUE);
898 write_client_reg(VCYCLE, 0x0000028E, TRUE);
899 write_client_reg(VSW, 0x00000004, TRUE);
900 write_client_reg(VDE_START, 0x00000009, TRUE);
901 write_client_reg(VDE_SIZE, 0x0000027F, TRUE);
902 write_client_reg(START, 0x00000001, TRUE);
903 write_client_reg(SYSTEM_BLOCK1_BASE, 0x00000002, TRUE);
904 } else{
905
906 write_client_reg(VSYNIF, 0x00000001, TRUE);
907 write_client_reg(PORT_ENB, 0x00000001, TRUE);
908 write_client_reg(BITMAP1, 0x01E000F0, TRUE);
909 write_client_reg(BITMAP2, 0x01E000F0, TRUE);
910 write_client_reg(BITMAP3, 0x01E000F0, TRUE);
911 write_client_reg(BITMAP4, 0x00DC00B0, TRUE);
912 write_client_reg(CLKENB, 0x000001EF, TRUE);
913 write_client_reg(PORT_ENB, 0x00000001, TRUE);
914 write_client_reg(PORT, 0x00000004, TRUE);
915 write_client_reg(PXL, 0x00000002, TRUE);
916 write_client_reg(MPLFBUF, 0x00000000, TRUE);
917
918 if (mddi_toshiba_61Hz_refresh) {
919 write_client_reg(HCYCLE, 0x000000FC, TRUE);
920 mddi_toshiba_rows_per_second = 39526;
921 mddi_toshiba_rows_per_refresh = 646;
922 mddi_toshiba_usecs_per_refresh = 16344;
923 } else {
924 write_client_reg(HCYCLE, 0x0000010b, TRUE);
925 mddi_toshiba_rows_per_second = 37313;
926 mddi_toshiba_rows_per_refresh = 646;
927 mddi_toshiba_usecs_per_refresh = 17313;
928 }
929
930 write_client_reg(HSW, 0x00000003, TRUE);
931 write_client_reg(HDE_START, 0x00000007, TRUE);
932 write_client_reg(HDE_SIZE, 0x000000EF, TRUE);
933 write_client_reg(VCYCLE, 0x00000285, TRUE);
934 write_client_reg(VSW, 0x00000001, TRUE);
935 write_client_reg(VDE_START, 0x00000003, TRUE);
936 write_client_reg(VDE_SIZE, 0x0000027F, TRUE);
937 write_client_reg(START, 0x00000001, TRUE);
938 mddi_wait(10);
939 write_client_reg(SSITX, 0x000800BC, TRUE);
940 write_client_reg(SSITX, 0x00000180, TRUE);
941 write_client_reg(SSITX, 0x0008003B, TRUE);
942 write_client_reg(SSITX, 0x00000100, TRUE);
943 mddi_wait(1);
944 write_client_reg(SSITX, 0x000800B0, TRUE);
945 write_client_reg(SSITX, 0x00000116, TRUE);
946 mddi_wait(1);
947 write_client_reg(SSITX, 0x000800B8, TRUE);
948 write_client_reg(SSITX, 0x000801FF, TRUE);
949 write_client_reg(SSITX, 0x000001F5, TRUE);
950 mddi_wait(1);
951 write_client_reg(SSITX, 0x00000011, TRUE);
952 write_client_reg(SSITX, 0x00000029, TRUE);
953 write_client_reg(WKREQ, 0x00000000, TRUE);
954 write_client_reg(WAKEUP, 0x00000000, TRUE);
955 write_client_reg(INTMSK, 0x00000001, TRUE);
956 }
957
958 mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_READY,
959 TOSHIBA_STATE_PRIM_NORMAL_MODE);
960}
961
962static void toshiba_sec_start(struct msm_fb_data_type *mfd)
963{
964 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
965 return;
966
967 write_client_reg(VSYNIF, 0x00000000, TRUE);
968 write_client_reg(PORT_ENB, 0x00000002, TRUE);
969 write_client_reg(CLKENB, 0x000011EF, TRUE);
970 write_client_reg(BITMAP0, 0x028001E0, TRUE);
971 write_client_reg(BITMAP1, 0x00000000, TRUE);
972 write_client_reg(BITMAP2, 0x00000000, TRUE);
973 write_client_reg(BITMAP3, 0x00000000, TRUE);
974 write_client_reg(BITMAP4, 0x00DC00B0, TRUE);
975 write_client_reg(PORT, 0x00000000, TRUE);
976 write_client_reg(PXL, 0x00000000, TRUE);
977 write_client_reg(MPLFBUF, 0x00000004, TRUE);
978 write_client_reg(HCYCLE, 0x0000006B, TRUE);
979 write_client_reg(HSW, 0x00000003, TRUE);
980 write_client_reg(HDE_START, 0x00000007, TRUE);
981 write_client_reg(HDE_SIZE, 0x00000057, TRUE);
982 write_client_reg(VCYCLE, 0x000000E6, TRUE);
983 write_client_reg(VSW, 0x00000001, TRUE);
984 write_client_reg(VDE_START, 0x00000003, TRUE);
985 write_client_reg(VDE_SIZE, 0x000000DB, TRUE);
986 write_client_reg(ASY_DATA, 0x80000001, TRUE);
987 write_client_reg(ASY_DATB, 0x0000011B, TRUE);
988 write_client_reg(ASY_DATC, 0x80000002, TRUE);
989 write_client_reg(ASY_DATD, 0x00000700, TRUE);
990 write_client_reg(ASY_DATE, 0x80000003, TRUE);
991 write_client_reg(ASY_DATF, 0x00000230, TRUE);
992 write_client_reg(ASY_DATG, 0x80000008, TRUE);
993 write_client_reg(ASY_DATH, 0x00000402, TRUE);
994 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
995 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
996 write_client_reg(ASY_DATA, 0x80000009, TRUE);
997 write_client_reg(ASY_DATB, 0x00000000, TRUE);
998 write_client_reg(ASY_DATC, 0x8000000B, TRUE);
999 write_client_reg(ASY_DATD, 0x00000000, TRUE);
1000 write_client_reg(ASY_DATE, 0x8000000C, TRUE);
1001 write_client_reg(ASY_DATF, 0x00000000, TRUE);
1002 write_client_reg(ASY_DATG, 0x8000000D, TRUE);
1003 write_client_reg(ASY_DATH, 0x00000409, TRUE);
1004 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
1005 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1006 write_client_reg(ASY_DATA, 0x8000000E, TRUE);
1007 write_client_reg(ASY_DATB, 0x00000409, TRUE);
1008 write_client_reg(ASY_DATC, 0x80000030, TRUE);
1009 write_client_reg(ASY_DATD, 0x00000000, TRUE);
1010 write_client_reg(ASY_DATE, 0x80000031, TRUE);
1011 write_client_reg(ASY_DATF, 0x00000100, TRUE);
1012 write_client_reg(ASY_DATG, 0x80000032, TRUE);
1013 write_client_reg(ASY_DATH, 0x00000104, TRUE);
1014 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
1015 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1016 write_client_reg(ASY_DATA, 0x80000033, TRUE);
1017 write_client_reg(ASY_DATB, 0x00000400, TRUE);
1018 write_client_reg(ASY_DATC, 0x80000034, TRUE);
1019 write_client_reg(ASY_DATD, 0x00000306, TRUE);
1020 write_client_reg(ASY_DATE, 0x80000035, TRUE);
1021 write_client_reg(ASY_DATF, 0x00000706, TRUE);
1022 write_client_reg(ASY_DATG, 0x80000036, TRUE);
1023 write_client_reg(ASY_DATH, 0x00000707, TRUE);
1024 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
1025 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1026 write_client_reg(ASY_DATA, 0x80000037, TRUE);
1027 write_client_reg(ASY_DATB, 0x00000004, TRUE);
1028 write_client_reg(ASY_DATC, 0x80000038, TRUE);
1029 write_client_reg(ASY_DATD, 0x00000000, TRUE);
1030 write_client_reg(ASY_DATE, 0x80000039, TRUE);
1031 write_client_reg(ASY_DATF, 0x00000000, TRUE);
1032 write_client_reg(ASY_DATG, 0x8000003A, TRUE);
1033 write_client_reg(ASY_DATH, 0x00000001, TRUE);
1034 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
1035 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1036 write_client_reg(ASY_DATA, 0x80000044, TRUE);
1037 write_client_reg(ASY_DATB, 0x0000AF00, TRUE);
1038 write_client_reg(ASY_DATC, 0x80000045, TRUE);
1039 write_client_reg(ASY_DATD, 0x0000DB00, TRUE);
1040 write_client_reg(ASY_DATE, 0x08000042, TRUE);
1041 write_client_reg(ASY_DATF, 0x0000DB00, TRUE);
1042 write_client_reg(ASY_DATG, 0x80000021, TRUE);
1043 write_client_reg(ASY_DATH, 0x00000000, TRUE);
1044 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
1045 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1046 write_client_reg(PXL, 0x0000000C, TRUE);
1047 write_client_reg(VSYNIF, 0x00000001, TRUE);
1048 write_client_reg(ASY_DATA, 0x80000022, TRUE);
1049 write_client_reg(ASY_CMDSET, 0x00000003, TRUE);
1050 write_client_reg(START, 0x00000001, TRUE);
1051 mddi_wait(60);
1052 write_client_reg(PXL, 0x00000000, TRUE);
1053 write_client_reg(VSYNIF, 0x00000000, TRUE);
1054 write_client_reg(START, 0x00000000, TRUE);
1055 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1056 write_client_reg(ASY_DATA, 0x80000050, TRUE);
1057 write_client_reg(ASY_DATB, 0x00000000, TRUE);
1058 write_client_reg(ASY_DATC, 0x80000051, TRUE);
1059 write_client_reg(ASY_DATD, 0x00000E00, TRUE);
1060 write_client_reg(ASY_DATE, 0x80000052, TRUE);
1061 write_client_reg(ASY_DATF, 0x00000D01, TRUE);
1062 write_client_reg(ASY_DATG, 0x80000053, TRUE);
1063 write_client_reg(ASY_DATH, 0x00000000, TRUE);
1064 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
1065 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1066 write_client_reg(ASY_DATA, 0x80000058, TRUE);
1067 write_client_reg(ASY_DATB, 0x00000000, TRUE);
1068 write_client_reg(ASY_DATC, 0x8000005A, TRUE);
1069 write_client_reg(ASY_DATD, 0x00000E01, TRUE);
1070 write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
1071 write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
1072 write_client_reg(ASY_DATA, 0x80000011, TRUE);
1073 write_client_reg(ASY_DATB, 0x00000812, TRUE);
1074 write_client_reg(ASY_DATC, 0x80000012, TRUE);
1075 write_client_reg(ASY_DATD, 0x00000003, TRUE);
1076 write_client_reg(ASY_DATE, 0x80000013, TRUE);
1077 write_client_reg(ASY_DATF, 0x00000909, TRUE);
1078 write_client_reg(ASY_DATG, 0x80000010, TRUE);
1079 write_client_reg(ASY_DATH, 0x00000040, TRUE);
1080 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
1081 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1082 mddi_wait(40);
1083 write_client_reg(ASY_DATA, 0x80000010, TRUE);
1084 write_client_reg(ASY_DATB, 0x00000340, TRUE);
1085 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1086 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1087 mddi_wait(60);
1088 write_client_reg(ASY_DATA, 0x80000010, TRUE);
1089 write_client_reg(ASY_DATB, 0x00003340, TRUE);
1090 write_client_reg(ASY_DATC, 0x80000007, TRUE);
1091 write_client_reg(ASY_DATD, 0x00004007, TRUE);
1092 write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
1093 write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
1094 mddi_wait(1);
1095 write_client_reg(ASY_DATA, 0x80000007, TRUE);
1096 write_client_reg(ASY_DATB, 0x00004017, TRUE);
1097 write_client_reg(ASY_DATC, 0x8000005B, TRUE);
1098 write_client_reg(ASY_DATD, 0x00000000, TRUE);
1099 write_client_reg(ASY_DATE, 0x80000059, TRUE);
1100 write_client_reg(ASY_DATF, 0x00000011, TRUE);
1101 write_client_reg(ASY_CMDSET, 0x0000000D, TRUE);
1102 write_client_reg(ASY_CMDSET, 0x0000000C, TRUE);
1103 mddi_wait(20);
1104 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1105 /* LTPS I/F control */
1106 write_client_reg(ASY_DATB, 0x00000019, TRUE);
1107 /* Direct cmd transfer enable */
1108 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1109 /* Direct cmd transfer disable */
1110 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1111 mddi_wait(20);
1112 /* Index setting of SUB LCDD */
1113 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1114 /* LTPS I/F control */
1115 write_client_reg(ASY_DATB, 0x00000079, TRUE);
1116 /* Direct cmd transfer enable */
1117 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1118 /* Direct cmd transfer disable */
1119 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1120 mddi_wait(20);
1121 /* Index setting of SUB LCDD */
1122 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1123 /* LTPS I/F control */
1124 write_client_reg(ASY_DATB, 0x000003FD, TRUE);
1125 /* Direct cmd transfer enable */
1126 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1127 /* Direct cmd transfer disable */
1128 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1129 mddi_wait(20);
1130 mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_READY,
1131 TOSHIBA_STATE_SEC_NORMAL_MODE);
1132}
1133
1134static void toshiba_prim_lcd_off(struct msm_fb_data_type *mfd)
1135{
1136 if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) {
1137 gordon_disp_off();
1138 } else{
1139
1140 /* Main panel power off (Deep standby in) */
1141 write_client_reg(SSITX, 0x000800BC, TRUE);
1142 write_client_reg(SSITX, 0x00000100, TRUE);
1143 write_client_reg(SSITX, 0x00000028, TRUE);
1144 mddi_wait(1);
1145 write_client_reg(SSITX, 0x000800B8, TRUE);
1146 write_client_reg(SSITX, 0x00000180, TRUE);
1147 write_client_reg(SSITX, 0x00000102, TRUE);
1148 write_client_reg(SSITX, 0x00000010, TRUE);
1149 }
1150 write_client_reg(PORT, 0x00000003, TRUE);
1151 write_client_reg(REGENB, 0x00000001, TRUE);
1152 mddi_wait(1);
1153 write_client_reg(PXL, 0x00000000, TRUE);
1154 write_client_reg(START, 0x00000000, TRUE);
1155 write_client_reg(REGENB, 0x00000001, TRUE);
1156 mddi_wait(3);
1157 if (TM_GET_PID(mfd->panel.id) != LCD_SHARP_2P4_VGA) {
1158 write_client_reg(SSITX, 0x000800B0, TRUE);
1159 write_client_reg(SSITX, 0x00000100, TRUE);
1160 }
1161 mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_NORMAL_MODE,
1162 TOSHIBA_STATE_PRIM_SEC_STANDBY);
1163}
1164
1165static void toshiba_sec_lcd_off(struct msm_fb_data_type *mfd)
1166{
1167 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
1168 return;
1169
1170 write_client_reg(VSYNIF, 0x00000000, TRUE);
1171 write_client_reg(PORT_ENB, 0x00000002, TRUE);
1172 write_client_reg(ASY_DATA, 0x80000007, TRUE);
1173 write_client_reg(ASY_DATB, 0x00004016, TRUE);
1174 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1175 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1176 mddi_wait(2);
1177 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1178 write_client_reg(ASY_DATB, 0x00000019, TRUE);
1179 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1180 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1181 mddi_wait(2);
1182 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1183 write_client_reg(ASY_DATB, 0x0000000B, TRUE);
1184 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1185 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1186 mddi_wait(2);
1187 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1188 write_client_reg(ASY_DATB, 0x00000002, TRUE);
1189 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1190 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1191 mddi_wait(4);
1192 write_client_reg(ASY_DATA, 0x80000010, TRUE);
1193 write_client_reg(ASY_DATB, 0x00000300, TRUE);
1194 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1195 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1196 mddi_wait(4);
1197 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1198 write_client_reg(ASY_DATB, 0x00000000, TRUE);
1199 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1200 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1201 mddi_wait(2);
1202 write_client_reg(ASY_DATA, 0x80000007, TRUE);
1203 write_client_reg(ASY_DATB, 0x00004004, TRUE);
1204 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1205 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1206 mddi_wait(2);
1207 write_client_reg(PORT, 0x00000000, TRUE);
1208 write_client_reg(PXL, 0x00000000, TRUE);
1209 write_client_reg(START, 0x00000000, TRUE);
1210 write_client_reg(VSYNIF, 0x00000001, TRUE);
1211 write_client_reg(PORT_ENB, 0x00000001, TRUE);
1212 write_client_reg(REGENB, 0x00000001, TRUE);
1213 mddi_toshiba_state_transition(TOSHIBA_STATE_SEC_NORMAL_MODE,
1214 TOSHIBA_STATE_PRIM_SEC_STANDBY);
1215}
1216
1217static void toshiba_sec_cont_update_start(struct msm_fb_data_type *mfd)
1218{
1219
1220 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
1221 return;
1222
1223 write_client_reg(VSYNIF, 0x00000000, TRUE);
1224 write_client_reg(PORT_ENB, 0x00000002, TRUE);
1225 write_client_reg(INTMASK, 0x00000001, TRUE);
1226 write_client_reg(TTBUSSEL, 0x0000000B, TRUE);
1227 write_client_reg(MONI, 0x00000008, TRUE);
1228 write_client_reg(CLKENB, 0x000000EF, TRUE);
1229 write_client_reg(CLKENB, 0x000010EF, TRUE);
1230 write_client_reg(CLKENB, 0x000011EF, TRUE);
1231 write_client_reg(BITMAP4, 0x00DC00B0, TRUE);
1232 write_client_reg(HCYCLE, 0x0000006B, TRUE);
1233 write_client_reg(HSW, 0x00000003, TRUE);
1234 write_client_reg(HDE_START, 0x00000002, TRUE);
1235 write_client_reg(HDE_SIZE, 0x00000057, TRUE);
1236 write_client_reg(VCYCLE, 0x000000E6, TRUE);
1237 write_client_reg(VSW, 0x00000001, TRUE);
1238 write_client_reg(VDE_START, 0x00000003, TRUE);
1239 write_client_reg(VDE_SIZE, 0x000000DB, TRUE);
1240 write_client_reg(WRSTB, 0x00000015, TRUE);
1241 write_client_reg(MPLFBUF, 0x00000004, TRUE);
1242 write_client_reg(ASY_DATA, 0x80000021, TRUE);
1243 write_client_reg(ASY_DATB, 0x00000000, TRUE);
1244 write_client_reg(ASY_DATC, 0x80000022, TRUE);
1245 write_client_reg(ASY_CMDSET, 0x00000007, TRUE);
1246 write_client_reg(PXL, 0x00000089, TRUE);
1247 write_client_reg(VSYNIF, 0x00000001, TRUE);
1248 mddi_wait(2);
1249}
1250
1251static void toshiba_sec_cont_update_stop(struct msm_fb_data_type *mfd)
1252{
1253 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
1254 return;
1255
1256 write_client_reg(PXL, 0x00000000, TRUE);
1257 write_client_reg(VSYNIF, 0x00000000, TRUE);
1258 write_client_reg(START, 0x00000000, TRUE);
1259 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1260 mddi_wait(3);
1261 write_client_reg(SRST, 0x00000002, TRUE);
1262 mddi_wait(3);
1263 write_client_reg(SRST, 0x00000003, TRUE);
1264}
1265
1266static void toshiba_sec_backlight_on(struct msm_fb_data_type *mfd)
1267{
1268 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
1269 return;
1270
1271 write_client_reg(TIMER0CTRL, 0x00000060, TRUE);
1272 write_client_reg(TIMER0LOAD, 0x00001388, TRUE);
1273 write_client_reg(PWM0OFF, 0x00000001, TRUE);
1274 write_client_reg(TIMER1CTRL, 0x00000060, TRUE);
1275 write_client_reg(TIMER1LOAD, 0x00001388, TRUE);
1276 write_client_reg(PWM1OFF, 0x00001387, TRUE);
1277 write_client_reg(TIMER0CTRL, 0x000000E0, TRUE);
1278 write_client_reg(TIMER1CTRL, 0x000000E0, TRUE);
1279 write_client_reg(PWMCR, 0x00000003, TRUE);
1280}
1281
1282static void toshiba_sec_sleep_in(struct msm_fb_data_type *mfd)
1283{
1284 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
1285 return;
1286
1287 write_client_reg(VSYNIF, 0x00000000, TRUE);
1288 write_client_reg(PORT_ENB, 0x00000002, TRUE);
1289 write_client_reg(ASY_DATA, 0x80000007, TRUE);
1290 write_client_reg(ASY_DATB, 0x00004016, TRUE);
1291 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1292 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1293 mddi_wait(2);
1294 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1295 write_client_reg(ASY_DATB, 0x00000019, TRUE);
1296 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1297 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1298 mddi_wait(2);
1299 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1300 write_client_reg(ASY_DATB, 0x0000000B, TRUE);
1301 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1302 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1303 mddi_wait(2);
1304 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1305 write_client_reg(ASY_DATB, 0x00000002, TRUE);
1306 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1307 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1308 mddi_wait(4);
1309 write_client_reg(ASY_DATA, 0x80000010, TRUE);
1310 write_client_reg(ASY_DATB, 0x00000300, TRUE);
1311 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1312 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1313 mddi_wait(4);
1314 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1315 write_client_reg(ASY_DATB, 0x00000000, TRUE);
1316 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1317 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1318 mddi_wait(2);
1319 write_client_reg(ASY_DATA, 0x80000007, TRUE);
1320 write_client_reg(ASY_DATB, 0x00004004, TRUE);
1321 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1322 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1323 mddi_wait(2);
1324 write_client_reg(PORT, 0x00000000, TRUE);
1325 write_client_reg(PXL, 0x00000000, TRUE);
1326 write_client_reg(START, 0x00000000, TRUE);
1327 write_client_reg(REGENB, 0x00000001, TRUE);
1328 /* Sleep in sequence */
1329 write_client_reg(ASY_DATA, 0x80000010, TRUE);
1330 write_client_reg(ASY_DATB, 0x00000302, TRUE);
1331 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1332 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1333}
1334
1335static void toshiba_sec_sleep_out(struct msm_fb_data_type *mfd)
1336{
1337 if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
1338 return;
1339
1340 write_client_reg(VSYNIF, 0x00000000, TRUE);
1341 write_client_reg(PORT_ENB, 0x00000002, TRUE);
1342 write_client_reg(ASY_DATA, 0x80000010, TRUE);
1343 write_client_reg(ASY_DATB, 0x00000300, TRUE);
1344 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1345 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1346 /* Display ON sequence */
1347 write_client_reg(ASY_DATA, 0x80000011, TRUE);
1348 write_client_reg(ASY_DATB, 0x00000812, TRUE);
1349 write_client_reg(ASY_DATC, 0x80000012, TRUE);
1350 write_client_reg(ASY_DATD, 0x00000003, TRUE);
1351 write_client_reg(ASY_DATE, 0x80000013, TRUE);
1352 write_client_reg(ASY_DATF, 0x00000909, TRUE);
1353 write_client_reg(ASY_DATG, 0x80000010, TRUE);
1354 write_client_reg(ASY_DATH, 0x00000040, TRUE);
1355 write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
1356 write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
1357 mddi_wait(4);
1358 write_client_reg(ASY_DATA, 0x80000010, TRUE);
1359 write_client_reg(ASY_DATB, 0x00000340, TRUE);
1360 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1361 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1362 mddi_wait(6);
1363 write_client_reg(ASY_DATA, 0x80000010, TRUE);
1364 write_client_reg(ASY_DATB, 0x00003340, TRUE);
1365 write_client_reg(ASY_DATC, 0x80000007, TRUE);
1366 write_client_reg(ASY_DATD, 0x00004007, TRUE);
1367 write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
1368 write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
1369 mddi_wait(1);
1370 write_client_reg(ASY_DATA, 0x80000007, TRUE);
1371 write_client_reg(ASY_DATB, 0x00004017, TRUE);
1372 write_client_reg(ASY_DATC, 0x8000005B, TRUE);
1373 write_client_reg(ASY_DATD, 0x00000000, TRUE);
1374 write_client_reg(ASY_DATE, 0x80000059, TRUE);
1375 write_client_reg(ASY_DATF, 0x00000011, TRUE);
1376 write_client_reg(ASY_CMDSET, 0x0000000D, TRUE);
1377 write_client_reg(ASY_CMDSET, 0x0000000C, TRUE);
1378 mddi_wait(2);
1379 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1380 write_client_reg(ASY_DATB, 0x00000019, TRUE);
1381 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1382 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1383 mddi_wait(2);
1384 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1385 write_client_reg(ASY_DATB, 0x00000079, TRUE);
1386 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1387 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1388 mddi_wait(2);
1389 write_client_reg(ASY_DATA, 0x80000059, TRUE);
1390 write_client_reg(ASY_DATB, 0x000003FD, TRUE);
1391 write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
1392 write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
1393 mddi_wait(2);
1394}
1395
1396static void mddi_toshiba_lcd_set_backlight(struct msm_fb_data_type *mfd)
1397{
1398 int32 level;
1399 int ret = -EPERM;
1400 int max = mfd->panel_info.bl_max;
1401 int min = mfd->panel_info.bl_min;
1402
1403 if (mddi_toshiba_pdata && mddi_toshiba_pdata->pmic_backlight) {
1404 ret = mddi_toshiba_pdata->pmic_backlight(mfd->bl_level);
1405 if (!ret)
1406 return;
1407 }
1408
1409 if (ret && mddi_toshiba_pdata && mddi_toshiba_pdata->backlight_level) {
1410 level = mddi_toshiba_pdata->backlight_level(mfd->bl_level,
1411 max, min);
1412
1413 if (level < 0)
1414 return;
1415
1416 if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA)
1417 write_client_reg(TIMER0LOAD, 0x00001388, TRUE);
1418 } else {
1419 if (!max)
1420 level = 0;
1421 else
1422 level = (mfd->bl_level * 4999) / max;
1423 }
1424
1425 write_client_reg(PWM0OFF, level, TRUE);
1426}
1427
1428static void mddi_toshiba_vsync_set_handler(msm_fb_vsync_handler_type handler, /* ISR to be executed */
1429 void *arg)
1430{
1431 boolean error = FALSE;
1432 unsigned long flags;
1433
1434 /* Disable interrupts */
1435 spin_lock_irqsave(&mddi_host_spin_lock, flags);
1436 /* INTLOCK(); */
1437
1438 if (mddi_toshiba_vsync_handler != NULL) {
1439 error = TRUE;
1440 } else {
1441 /* Register the handler for this particular GROUP interrupt source */
1442 mddi_toshiba_vsync_handler = handler;
1443 mddi_toshiba_vsync_handler_arg = arg;
1444 }
1445
1446 /* Restore interrupts */
1447 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
1448 /* MDDI_INTFREE(); */
1449 if (error) {
1450 MDDI_MSG_ERR("MDDI: Previous Vsync handler never called\n");
1451 } else {
1452 /* Enable the vsync wakeup */
1453 mddi_queue_register_write(INTMSK, 0x0000, FALSE, 0);
1454
1455 mddi_toshiba_vsync_attempts = 1;
1456 mddi_vsync_detect_enabled = TRUE;
1457 }
1458} /* mddi_toshiba_vsync_set_handler */
1459
1460static void mddi_toshiba_lcd_vsync_detected(boolean detected)
1461{
1462 /* static timetick_type start_time = 0; */
1463 static struct timeval start_time;
1464 static boolean first_time = TRUE;
1465 /* uint32 mdp_cnt_val = 0; */
1466 /* timetick_type elapsed_us; */
1467 struct timeval now;
1468 uint32 elapsed_us;
1469 uint32 num_vsyncs;
1470
1471 if ((detected) || (mddi_toshiba_vsync_attempts > 5)) {
1472 if ((detected) && (mddi_toshiba_monitor_refresh_value)) {
1473 /* if (start_time != 0) */
1474 if (!first_time) {
1475 jiffies_to_timeval(jiffies, &now);
1476 elapsed_us =
1477 (now.tv_sec - start_time.tv_sec) * 1000000 +
1478 now.tv_usec - start_time.tv_usec;
1479 /*
1480 * LCD is configured for a refresh every usecs,
1481 * so to determine the number of vsyncs that
1482 * have occurred since the last measurement
1483 * add half that to the time difference and
1484 * divide by the refresh rate.
1485 */
1486 num_vsyncs = (elapsed_us +
1487 (mddi_toshiba_usecs_per_refresh >>
1488 1)) /
1489 mddi_toshiba_usecs_per_refresh;
1490 /*
1491 * LCD is configured for * hsyncs (rows) per
1492 * refresh cycle. Calculate new rows_per_second
1493 * value based upon these new measurements.
1494 * MDP can update with this new value.
1495 */
1496 mddi_toshiba_rows_per_second =
1497 (mddi_toshiba_rows_per_refresh * 1000 *
1498 num_vsyncs) / (elapsed_us / 1000);
1499 }
1500 /* start_time = timetick_get(); */
1501 first_time = FALSE;
1502 jiffies_to_timeval(jiffies, &start_time);
1503 if (mddi_toshiba_report_refresh_measurements) {
1504 (void)mddi_queue_register_read_int(VPOS,
1505 &mddi_toshiba_curr_vpos);
1506 /* mdp_cnt_val = MDP_LINE_COUNT; */
1507 }
1508 }
1509 /* if detected = TRUE, client initiated wakeup was detected */
1510 if (mddi_toshiba_vsync_handler != NULL) {
1511 (*mddi_toshiba_vsync_handler)
1512 (mddi_toshiba_vsync_handler_arg);
1513 mddi_toshiba_vsync_handler = NULL;
1514 }
1515 mddi_vsync_detect_enabled = FALSE;
1516 mddi_toshiba_vsync_attempts = 0;
1517 /* need to disable the interrupt wakeup */
1518 if (!mddi_queue_register_write_int(INTMSK, 0x0001))
1519 MDDI_MSG_ERR("Vsync interrupt disable failed!\n");
1520 if (!detected) {
1521 /* give up after 5 failed attempts but show error */
1522 MDDI_MSG_NOTICE("Vsync detection failed!\n");
1523 } else if ((mddi_toshiba_monitor_refresh_value) &&
1524 (mddi_toshiba_report_refresh_measurements)) {
1525 MDDI_MSG_NOTICE(" Last Line Counter=%d!\n",
1526 mddi_toshiba_curr_vpos);
1527 /* MDDI_MSG_NOTICE(" MDP Line Counter=%d!\n",mdp_cnt_val); */
1528 MDDI_MSG_NOTICE(" Lines Per Second=%d!\n",
1529 mddi_toshiba_rows_per_second);
1530 }
1531 /* clear the interrupt */
1532 if (!mddi_queue_register_write_int(INTFLG, 0x0001))
1533 MDDI_MSG_ERR("Vsync interrupt clear failed!\n");
1534 } else {
1535 /* if detected = FALSE, we woke up from hibernation, but did not
1536 * detect client initiated wakeup.
1537 */
1538 mddi_toshiba_vsync_attempts++;
1539 }
1540}
1541
1542static void mddi_toshiba_prim_init(struct msm_fb_data_type *mfd)
1543{
1544
1545 switch (toshiba_state) {
1546 case TOSHIBA_STATE_PRIM_SEC_READY:
1547 break;
1548 case TOSHIBA_STATE_OFF:
1549 toshiba_state = TOSHIBA_STATE_PRIM_SEC_STANDBY;
1550 toshiba_common_initial_setup(mfd);
1551 break;
1552 case TOSHIBA_STATE_PRIM_SEC_STANDBY:
1553 toshiba_common_initial_setup(mfd);
1554 break;
1555 case TOSHIBA_STATE_SEC_NORMAL_MODE:
1556 toshiba_sec_cont_update_stop(mfd);
1557 toshiba_sec_sleep_in(mfd);
1558 toshiba_sec_sleep_out(mfd);
1559 toshiba_sec_lcd_off(mfd);
1560 toshiba_common_initial_setup(mfd);
1561 break;
1562 default:
1563 MDDI_MSG_ERR("mddi_toshiba_prim_init from state %d\n",
1564 toshiba_state);
1565 }
1566
1567 toshiba_prim_start(mfd);
1568 if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA)
1569 gordon_disp_init();
1570 mddi_host_write_pix_attr_reg(0x00C3);
1571}
1572
1573static void mddi_toshiba_sec_init(struct msm_fb_data_type *mfd)
1574{
1575
1576 switch (toshiba_state) {
1577 case TOSHIBA_STATE_PRIM_SEC_READY:
1578 break;
1579 case TOSHIBA_STATE_PRIM_SEC_STANDBY:
1580 toshiba_common_initial_setup(mfd);
1581 break;
1582 case TOSHIBA_STATE_PRIM_NORMAL_MODE:
1583 toshiba_prim_lcd_off(mfd);
1584 toshiba_common_initial_setup(mfd);
1585 break;
1586 default:
1587 MDDI_MSG_ERR("mddi_toshiba_sec_init from state %d\n",
1588 toshiba_state);
1589 }
1590
1591 toshiba_sec_start(mfd);
1592 toshiba_sec_backlight_on(mfd);
1593 toshiba_sec_cont_update_start(mfd);
1594 mddi_host_write_pix_attr_reg(0x0400);
1595}
1596
1597static void mddi_toshiba_lcd_powerdown(struct msm_fb_data_type *mfd)
1598{
1599 switch (toshiba_state) {
1600 case TOSHIBA_STATE_PRIM_SEC_READY:
1601 mddi_toshiba_prim_init(mfd);
1602 mddi_toshiba_lcd_powerdown(mfd);
1603 return;
1604 case TOSHIBA_STATE_PRIM_SEC_STANDBY:
1605 break;
1606 case TOSHIBA_STATE_PRIM_NORMAL_MODE:
1607 toshiba_prim_lcd_off(mfd);
1608 break;
1609 case TOSHIBA_STATE_SEC_NORMAL_MODE:
1610 toshiba_sec_cont_update_stop(mfd);
1611 toshiba_sec_sleep_in(mfd);
1612 toshiba_sec_sleep_out(mfd);
1613 toshiba_sec_lcd_off(mfd);
1614 break;
1615 default:
1616 MDDI_MSG_ERR("mddi_toshiba_lcd_powerdown from state %d\n",
1617 toshiba_state);
1618 }
1619}
1620
1621static int mddi_sharpgordon_firsttime = 1;
1622
1623static int mddi_toshiba_lcd_on(struct platform_device *pdev)
1624{
1625 struct msm_fb_data_type *mfd;
1626 mfd = platform_get_drvdata(pdev);
1627 if (!mfd)
1628 return -ENODEV;
1629 if (mfd->key != MFD_KEY)
1630 return -EINVAL;
1631
1632 if (TM_GET_DID(mfd->panel.id) == TOSHIBA_VGA_PRIM)
1633 mddi_toshiba_prim_init(mfd);
1634 else
1635 mddi_toshiba_sec_init(mfd);
1636 if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) {
1637 if (mddi_sharpgordon_firsttime) {
1638 mddi_sharpgordon_firsttime = 0;
1639 write_client_reg(REGENB, 0x00000001, TRUE);
1640 }
1641 }
1642 return 0;
1643}
1644
1645static int mddi_toshiba_lcd_off(struct platform_device *pdev)
1646{
1647 mddi_toshiba_lcd_powerdown(platform_get_drvdata(pdev));
1648 return 0;
1649}
1650
1651static int __init mddi_toshiba_lcd_probe(struct platform_device *pdev)
1652{
1653 if (pdev->id == 0) {
1654 mddi_toshiba_pdata = pdev->dev.platform_data;
1655 return 0;
1656 }
1657
1658 msm_fb_add_device(pdev);
1659
1660 return 0;
1661}
1662
1663static struct platform_driver this_driver = {
1664 .probe = mddi_toshiba_lcd_probe,
1665 .driver = {
1666 .name = "mddi_toshiba",
1667 },
1668};
1669
1670static struct msm_fb_panel_data toshiba_panel_data = {
1671 .on = mddi_toshiba_lcd_on,
1672 .off = mddi_toshiba_lcd_off,
1673};
1674
1675static int ch_used[3];
1676
1677int mddi_toshiba_device_register(struct msm_panel_info *pinfo,
1678 u32 channel, u32 panel)
1679{
1680 struct platform_device *pdev = NULL;
1681 int ret;
1682
1683 if ((channel >= 3) || ch_used[channel])
1684 return -ENODEV;
1685
1686 if ((channel != TOSHIBA_VGA_PRIM) &&
1687 mddi_toshiba_pdata && mddi_toshiba_pdata->panel_num)
1688 if (mddi_toshiba_pdata->panel_num() < 2)
1689 return -ENODEV;
1690
1691 ch_used[channel] = TRUE;
1692
1693 pdev = platform_device_alloc("mddi_toshiba", (panel << 8)|channel);
1694 if (!pdev)
1695 return -ENOMEM;
1696
1697 if (channel == TOSHIBA_VGA_PRIM) {
1698 toshiba_panel_data.set_backlight =
1699 mddi_toshiba_lcd_set_backlight;
1700
1701 if (pinfo->lcd.vsync_enable) {
1702 toshiba_panel_data.set_vsync_notifier =
1703 mddi_toshiba_vsync_set_handler;
1704 mddi_lcd.vsync_detected =
1705 mddi_toshiba_lcd_vsync_detected;
1706 }
1707 } else {
1708 toshiba_panel_data.set_backlight = NULL;
1709 toshiba_panel_data.set_vsync_notifier = NULL;
1710 }
1711
1712 toshiba_panel_data.panel_info = *pinfo;
1713
1714 ret = platform_device_add_data(pdev, &toshiba_panel_data,
1715 sizeof(toshiba_panel_data));
1716 if (ret) {
1717 printk(KERN_ERR
1718 "%s: platform_device_add_data failed!\n", __func__);
1719 goto err_device_put;
1720 }
1721
1722 ret = platform_device_add(pdev);
1723 if (ret) {
1724 printk(KERN_ERR
1725 "%s: platform_device_register failed!\n", __func__);
1726 goto err_device_put;
1727 }
1728
1729 return 0;
1730
1731err_device_put:
1732 platform_device_put(pdev);
1733 return ret;
1734}
1735
1736static int __init mddi_toshiba_lcd_init(void)
1737{
1738 return platform_driver_register(&this_driver);
1739}
1740
1741module_init(mddi_toshiba_lcd_init);
diff --git a/drivers/staging/msm/mddi_toshiba.h b/drivers/staging/msm/mddi_toshiba.h
new file mode 100644
index 000000000000..2d22b9a2c413
--- /dev/null
+++ b/drivers/staging/msm/mddi_toshiba.h
@@ -0,0 +1,52 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef MDDI_TOSHIBA_H
30#define MDDI_TOSHIBA_H
31
32#define TOSHIBA_VGA_PRIM 1
33#define TOSHIBA_VGA_SECD 2
34
35#define LCD_TOSHIBA_2P4_VGA 0
36#define LCD_TOSHIBA_2P4_WVGA 1
37#define LCD_TOSHIBA_2P4_WVGA_PT 2
38#define LCD_SHARP_2P4_VGA 3
39
40#define GPIO_BLOCK_BASE 0x150000
41#define SYSTEM_BLOCK2_BASE 0x170000
42
43#define GPIODIR (GPIO_BLOCK_BASE|0x04)
44#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
45#define GPIOPC (GPIO_BLOCK_BASE|0x28)
46#define GPIODATA (GPIO_BLOCK_BASE|0x00)
47
48#define write_client_reg(__X, __Y, __Z) {\
49 mddi_queue_register_write(__X, __Y, TRUE, 0);\
50}
51
52#endif /* MDDI_TOSHIBA_H */
diff --git a/drivers/staging/msm/mddi_toshiba_vga.c b/drivers/staging/msm/mddi_toshiba_vga.c
new file mode 100644
index 000000000000..7e61d3a5b8f1
--- /dev/null
+++ b/drivers/staging/msm/mddi_toshiba_vga.c
@@ -0,0 +1,136 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19#include "mddihost.h"
20#include "mddihosti.h"
21#include "mddi_toshiba.h"
22
23static uint32 read_client_reg(uint32 addr)
24{
25 uint32 val;
26 mddi_queue_register_read(addr, &val, TRUE, 0);
27 return val;
28}
29
30static uint32 toshiba_lcd_gpio_read(void)
31{
32 uint32 val;
33
34 write_client_reg(GPIODIR, 0x0000000C, TRUE);
35 write_client_reg(GPIOSEL, 0x00000000, TRUE);
36 write_client_reg(GPIOSEL, 0x00000000, TRUE);
37 write_client_reg(GPIOPC, 0x03CF00C0, TRUE);
38 val = read_client_reg(GPIODATA) & 0x2C0;
39
40 return val;
41}
42
43static u32 mddi_toshiba_panel_detect(void)
44{
45 mddi_host_type host_idx = MDDI_HOST_PRIM;
46 uint32 lcd_gpio;
47 u32 mddi_toshiba_lcd = LCD_TOSHIBA_2P4_VGA;
48
49 /* Toshiba display requires larger drive_lo value */
50 mddi_host_reg_out(DRIVE_LO, 0x0050);
51
52 lcd_gpio = toshiba_lcd_gpio_read();
53 switch (lcd_gpio) {
54 case 0x0080:
55 mddi_toshiba_lcd = LCD_SHARP_2P4_VGA;
56 break;
57
58 case 0x00C0:
59 default:
60 mddi_toshiba_lcd = LCD_TOSHIBA_2P4_VGA;
61 break;
62 }
63
64 return mddi_toshiba_lcd;
65}
66
67static int __init mddi_toshiba_vga_init(void)
68{
69 int ret;
70 struct msm_panel_info pinfo;
71 u32 panel;
72
73#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
74 u32 id;
75
76 ret = msm_fb_detect_client("mddi_toshiba_vga");
77 if (ret == -ENODEV)
78 return 0;
79
80 if (ret) {
81 id = mddi_get_client_id();
82 if ((id >> 16) != 0xD263)
83 return 0;
84 }
85#endif
86
87 panel = mddi_toshiba_panel_detect();
88
89 pinfo.xres = 480;
90 pinfo.yres = 640;
91 pinfo.type = MDDI_PANEL;
92 pinfo.pdest = DISPLAY_1;
93 pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
94 pinfo.wait_cycle = 0;
95 pinfo.bpp = 18;
96 pinfo.lcd.vsync_enable = TRUE;
97 pinfo.lcd.refx100 = 6118;
98 pinfo.lcd.v_back_porch = 6;
99 pinfo.lcd.v_front_porch = 0;
100 pinfo.lcd.v_pulse_width = 0;
101 pinfo.lcd.hw_vsync_mode = FALSE;
102 pinfo.lcd.vsync_notifier_period = (1 * HZ);
103 pinfo.bl_max = 99;
104 pinfo.bl_min = 1;
105 pinfo.clk_rate = 122880000;
106 pinfo.clk_min = 120000000;
107 pinfo.clk_max = 200000000;
108 pinfo.fb_num = 2;
109
110 ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM, panel);
111 if (ret) {
112 printk(KERN_ERR "%s: failed to register device!\n", __func__);
113 return ret;
114 }
115
116 pinfo.xres = 176;
117 pinfo.yres = 220;
118 pinfo.type = MDDI_PANEL;
119 pinfo.pdest = DISPLAY_2;
120 pinfo.mddi.vdopkt = 0x400;
121 pinfo.wait_cycle = 0;
122 pinfo.bpp = 18;
123 pinfo.clk_rate = 122880000;
124 pinfo.clk_min = 120000000;
125 pinfo.clk_max = 200000000;
126 pinfo.fb_num = 2;
127
128 ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_SECD, panel);
129 if (ret)
130 printk(KERN_WARNING
131 "%s: failed to register device!\n", __func__);
132
133 return ret;
134}
135
136module_init(mddi_toshiba_vga_init);
diff --git a/drivers/staging/msm/mddi_toshiba_wvga.c b/drivers/staging/msm/mddi_toshiba_wvga.c
new file mode 100644
index 000000000000..557b0f08faf8
--- /dev/null
+++ b/drivers/staging/msm/mddi_toshiba_wvga.c
@@ -0,0 +1,63 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19#include "mddihost.h"
20#include "mddi_toshiba.h"
21
22static int __init mddi_toshiba_wvga_init(void)
23{
24 int ret;
25 struct msm_panel_info pinfo;
26
27#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
28 if (msm_fb_detect_client("mddi_toshiba_wvga"))
29 return 0;
30#endif
31
32 pinfo.xres = 800;
33 pinfo.yres = 480;
34 pinfo.pdest = DISPLAY_2;
35 pinfo.type = MDDI_PANEL;
36 pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
37 pinfo.wait_cycle = 0;
38 pinfo.bpp = 18;
39 pinfo.lcd.vsync_enable = TRUE;
40 pinfo.lcd.refx100 = 6118;
41 pinfo.lcd.v_back_porch = 6;
42 pinfo.lcd.v_front_porch = 0;
43 pinfo.lcd.v_pulse_width = 0;
44 pinfo.lcd.hw_vsync_mode = FALSE;
45 pinfo.lcd.vsync_notifier_period = (1 * HZ);
46 pinfo.bl_max = 4;
47 pinfo.bl_min = 1;
48 pinfo.clk_rate = 192000000;
49 pinfo.clk_min = 190000000;
50 pinfo.clk_max = 200000000;
51 pinfo.fb_num = 2;
52
53 ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM,
54 LCD_TOSHIBA_2P4_WVGA);
55 if (ret) {
56 printk(KERN_ERR "%s: failed to register device!\n", __func__);
57 return ret;
58 }
59
60 return ret;
61}
62
63module_init(mddi_toshiba_wvga_init);
diff --git a/drivers/staging/msm/mddi_toshiba_wvga_pt.c b/drivers/staging/msm/mddi_toshiba_wvga_pt.c
new file mode 100644
index 000000000000..fc7d4e0d294f
--- /dev/null
+++ b/drivers/staging/msm/mddi_toshiba_wvga_pt.c
@@ -0,0 +1,64 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "msm_fb.h"
19#include "mddihost.h"
20#include "mddihosti.h"
21#include "mddi_toshiba.h"
22
23static int __init mddi_toshiba_wvga_pt_init(void)
24{
25 int ret;
26 struct msm_panel_info pinfo;
27#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
28 uint id;
29
30 ret = msm_fb_detect_client("mddi_toshiba_wvga_pt");
31 if (ret == -ENODEV)
32 return 0;
33
34 if (ret) {
35 id = mddi_get_client_id();
36 if (id != 0xd2638722)
37 return 0;
38 }
39#endif
40
41 pinfo.xres = 480;
42 pinfo.yres = 800;
43 pinfo.type = MDDI_PANEL;
44 pinfo.pdest = DISPLAY_1;
45 pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
46 pinfo.wait_cycle = 0;
47 pinfo.bpp = 18;
48 pinfo.lcd.vsync_enable = FALSE;
49 pinfo.bl_max = 15;
50 pinfo.bl_min = 1;
51 pinfo.clk_rate = 192000000;
52 pinfo.clk_min = 190000000;
53 pinfo.clk_max = 200000000;
54 pinfo.fb_num = 2;
55
56 ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM,
57 LCD_TOSHIBA_2P4_WVGA_PT);
58 if (ret)
59 printk(KERN_ERR "%s: failed to register device!\n", __func__);
60
61 return ret;
62}
63
64module_init(mddi_toshiba_wvga_pt_init);
diff --git a/drivers/staging/msm/mddihost.c b/drivers/staging/msm/mddihost.c
new file mode 100644
index 000000000000..c6c1ee4eda05
--- /dev/null
+++ b/drivers/staging/msm/mddihost.c
@@ -0,0 +1,377 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/slab.h>
21#include <linux/delay.h>
22#include <linux/mm.h>
23#include <linux/fb.h>
24#include <linux/init.h>
25#include <linux/ioport.h>
26#include <linux/device.h>
27#include <linux/dma-mapping.h>
28
29#include "msm_fb.h"
30#include "mddihost.h"
31#include "mddihosti.h"
32
33#include <linux/clk.h>
34#include <mach/clk.h>
35
36struct semaphore mddi_host_mutex;
37
38struct clk *mddi_io_clk;
39static boolean mddi_host_powered = FALSE;
40static boolean mddi_host_initialized = FALSE;
41extern uint32 *mddi_reg_read_value_ptr;
42
43mddi_lcd_func_type mddi_lcd;
44
45extern mddi_client_capability_type mddi_client_capability_pkt;
46
47#ifdef FEATURE_MDDI_HITACHI
48extern void mddi_hitachi_window_adjust(uint16 x1,
49 uint16 x2, uint16 y1, uint16 y2);
50#endif
51
52extern void mddi_toshiba_lcd_init(void);
53
54#ifdef FEATURE_MDDI_S6D0142
55extern void mddi_s6d0142_lcd_init(void);
56extern void mddi_s6d0142_window_adjust(uint16 x1,
57 uint16 x2,
58 uint16 y1,
59 uint16 y2,
60 mddi_llist_done_cb_type done_cb);
61#endif
62
63void mddi_init(void)
64{
65 if (mddi_host_initialized)
66 return;
67
68 mddi_host_initialized = TRUE;
69
70 init_MUTEX(&mddi_host_mutex);
71
72 if (!mddi_host_powered) {
73 down(&mddi_host_mutex);
74 mddi_host_init(MDDI_HOST_PRIM);
75 mddi_host_powered = TRUE;
76 up(&mddi_host_mutex);
77 mdelay(10);
78 }
79}
80
81int mddi_host_register_read(uint32 reg_addr,
82 uint32 *reg_value_ptr, boolean wait, mddi_host_type host) {
83 mddi_linked_list_type *curr_llist_ptr;
84 mddi_register_access_packet_type *regacc_pkt_ptr;
85 uint16 curr_llist_idx;
86 int ret = 0;
87
88 if (in_interrupt())
89 MDDI_MSG_CRIT("Called from ISR context\n");
90
91 if (!mddi_host_powered) {
92 MDDI_MSG_ERR("MDDI powered down!\n");
93 mddi_init();
94 }
95
96 down(&mddi_host_mutex);
97
98 mddi_reg_read_value_ptr = reg_value_ptr;
99 curr_llist_idx = mddi_get_reg_read_llist_item(host, TRUE);
100 if (curr_llist_idx == UNASSIGNED_INDEX) {
101 up(&mddi_host_mutex);
102
103 /* need to change this to some sort of wait */
104 MDDI_MSG_ERR("Attempting to queue up more than 1 reg read\n");
105 return -EINVAL;
106 }
107
108 curr_llist_ptr = &llist_extern[host][curr_llist_idx];
109 curr_llist_ptr->link_controller_flags = 0x11;
110 curr_llist_ptr->packet_header_count = 14;
111 curr_llist_ptr->packet_data_count = 0;
112
113 curr_llist_ptr->next_packet_pointer = NULL;
114 curr_llist_ptr->packet_data_pointer = NULL;
115 curr_llist_ptr->reserved = 0;
116
117 regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
118
119 regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count;
120 regacc_pkt_ptr->packet_type = 146; /* register access packet */
121 regacc_pkt_ptr->bClient_ID = 0;
122 regacc_pkt_ptr->read_write_info = 0x8001;
123 regacc_pkt_ptr->register_address = reg_addr;
124
125 /* now adjust pointers */
126 mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait,
127 NULL, host);
128 /* need to check if we can write the pointer or not */
129
130 up(&mddi_host_mutex);
131
132 if (wait) {
133 int wait_ret;
134
135 mddi_linked_list_notify_type *llist_notify_ptr;
136 llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx];
137 wait_ret = wait_for_completion_timeout(
138 &(llist_notify_ptr->done_comp), 5 * HZ);
139
140 if (wait_ret <= 0)
141 ret = -EBUSY;
142
143 if (wait_ret < 0)
144 printk(KERN_ERR "%s: failed to wait for completion!\n",
145 __func__);
146 else if (!wait_ret)
147 printk(KERN_ERR "%s: Timed out waiting!\n", __func__);
148 }
149
150 MDDI_MSG_DEBUG("Reg Read value=0x%x\n", *reg_value_ptr);
151
152 return ret;
153} /* mddi_host_register_read */
154
155int mddi_host_register_write(uint32 reg_addr,
156 uint32 reg_val, enum mddi_data_packet_size_type packet_size,
157 boolean wait, mddi_llist_done_cb_type done_cb, mddi_host_type host) {
158 mddi_linked_list_type *curr_llist_ptr;
159 mddi_linked_list_type *curr_llist_dma_ptr;
160 mddi_register_access_packet_type *regacc_pkt_ptr;
161 uint16 curr_llist_idx;
162 int ret = 0;
163
164 if (in_interrupt())
165 MDDI_MSG_CRIT("Called from ISR context\n");
166
167 if (!mddi_host_powered) {
168 MDDI_MSG_ERR("MDDI powered down!\n");
169 mddi_init();
170 }
171
172 down(&mddi_host_mutex);
173
174 curr_llist_idx = mddi_get_next_free_llist_item(host, TRUE);
175 curr_llist_ptr = &llist_extern[host][curr_llist_idx];
176 curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx];
177
178 curr_llist_ptr->link_controller_flags = 1;
179 curr_llist_ptr->packet_header_count = 14;
180 curr_llist_ptr->packet_data_count = 4;
181
182 curr_llist_ptr->next_packet_pointer = NULL;
183 curr_llist_ptr->reserved = 0;
184
185 regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
186
187 regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count +
188 (uint16)packet_size;
189 regacc_pkt_ptr->packet_type = 146; /* register access packet */
190 regacc_pkt_ptr->bClient_ID = 0;
191 regacc_pkt_ptr->read_write_info = 0x0001;
192 regacc_pkt_ptr->register_address = reg_addr;
193 regacc_pkt_ptr->register_data_list = reg_val;
194
195 MDDI_MSG_DEBUG("Reg Access write reg=0x%x, value=0x%x\n",
196 regacc_pkt_ptr->register_address,
197 regacc_pkt_ptr->register_data_list);
198
199 regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt;
200 curr_llist_ptr->packet_data_pointer =
201 (void *)(&regacc_pkt_ptr->register_data_list);
202
203 /* now adjust pointers */
204 mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait,
205 done_cb, host);
206
207 up(&mddi_host_mutex);
208
209 if (wait) {
210 int wait_ret;
211
212 mddi_linked_list_notify_type *llist_notify_ptr;
213 llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx];
214 wait_ret = wait_for_completion_timeout(
215 &(llist_notify_ptr->done_comp), 5 * HZ);
216
217 if (wait_ret <= 0)
218 ret = -EBUSY;
219
220 if (wait_ret < 0)
221 printk(KERN_ERR "%s: failed to wait for completion!\n",
222 __func__);
223 else if (!wait_ret)
224 printk(KERN_ERR "%s: Timed out waiting!\n", __func__);
225 }
226
227 return ret;
228} /* mddi_host_register_write */
229
230boolean mddi_host_register_read_int
231 (uint32 reg_addr, uint32 *reg_value_ptr, mddi_host_type host) {
232 mddi_linked_list_type *curr_llist_ptr;
233 mddi_register_access_packet_type *regacc_pkt_ptr;
234 uint16 curr_llist_idx;
235
236 if (!in_interrupt())
237 MDDI_MSG_CRIT("Called from TASK context\n");
238
239 if (!mddi_host_powered) {
240 MDDI_MSG_ERR("MDDI powered down!\n");
241 return FALSE;
242 }
243
244 if (down_trylock(&mddi_host_mutex) != 0)
245 return FALSE;
246
247 mddi_reg_read_value_ptr = reg_value_ptr;
248 curr_llist_idx = mddi_get_reg_read_llist_item(host, FALSE);
249 if (curr_llist_idx == UNASSIGNED_INDEX) {
250 up(&mddi_host_mutex);
251 return FALSE;
252 }
253
254 curr_llist_ptr = &llist_extern[host][curr_llist_idx];
255 curr_llist_ptr->link_controller_flags = 0x11;
256 curr_llist_ptr->packet_header_count = 14;
257 curr_llist_ptr->packet_data_count = 0;
258
259 curr_llist_ptr->next_packet_pointer = NULL;
260 curr_llist_ptr->packet_data_pointer = NULL;
261 curr_llist_ptr->reserved = 0;
262
263 regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
264
265 regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count;
266 regacc_pkt_ptr->packet_type = 146; /* register access packet */
267 regacc_pkt_ptr->bClient_ID = 0;
268 regacc_pkt_ptr->read_write_info = 0x8001;
269 regacc_pkt_ptr->register_address = reg_addr;
270
271 /* now adjust pointers */
272 mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, FALSE,
273 NULL, host);
274 /* need to check if we can write the pointer or not */
275
276 up(&mddi_host_mutex);
277
278 return TRUE;
279
280} /* mddi_host_register_read */
281
282boolean mddi_host_register_write_int
283 (uint32 reg_addr,
284 uint32 reg_val, mddi_llist_done_cb_type done_cb, mddi_host_type host) {
285 mddi_linked_list_type *curr_llist_ptr;
286 mddi_linked_list_type *curr_llist_dma_ptr;
287 mddi_register_access_packet_type *regacc_pkt_ptr;
288 uint16 curr_llist_idx;
289
290 if (!in_interrupt())
291 MDDI_MSG_CRIT("Called from TASK context\n");
292
293 if (!mddi_host_powered) {
294 MDDI_MSG_ERR("MDDI powered down!\n");
295 return FALSE;
296 }
297
298 if (down_trylock(&mddi_host_mutex) != 0)
299 return FALSE;
300
301 curr_llist_idx = mddi_get_next_free_llist_item(host, FALSE);
302 if (curr_llist_idx == UNASSIGNED_INDEX) {
303 up(&mddi_host_mutex);
304 return FALSE;
305 }
306
307 curr_llist_ptr = &llist_extern[host][curr_llist_idx];
308 curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx];
309
310 curr_llist_ptr->link_controller_flags = 1;
311 curr_llist_ptr->packet_header_count = 14;
312 curr_llist_ptr->packet_data_count = 4;
313
314 curr_llist_ptr->next_packet_pointer = NULL;
315 curr_llist_ptr->reserved = 0;
316
317 regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
318
319 regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count + 4;
320 regacc_pkt_ptr->packet_type = 146; /* register access packet */
321 regacc_pkt_ptr->bClient_ID = 0;
322 regacc_pkt_ptr->read_write_info = 0x0001;
323 regacc_pkt_ptr->register_address = reg_addr;
324 regacc_pkt_ptr->register_data_list = reg_val;
325
326 regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt;
327 curr_llist_ptr->packet_data_pointer =
328 (void *)(&(regacc_pkt_ptr->register_data_list));
329
330 /* now adjust pointers */
331 mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, FALSE,
332 done_cb, host);
333 up(&mddi_host_mutex);
334
335 return TRUE;
336
337} /* mddi_host_register_write */
338
339void mddi_wait(uint16 time_ms)
340{
341 mdelay(time_ms);
342}
343
344void mddi_client_lcd_vsync_detected(boolean detected)
345{
346 if (mddi_lcd.vsync_detected)
347 (*mddi_lcd.vsync_detected) (detected);
348}
349
350/* extended version of function includes done callback */
351void mddi_window_adjust_ext(struct msm_fb_data_type *mfd,
352 uint16 x1,
353 uint16 x2,
354 uint16 y1,
355 uint16 y2, mddi_llist_done_cb_type done_cb)
356{
357#ifdef FEATURE_MDDI_HITACHI
358 if (mfd->panel.id == HITACHI)
359 mddi_hitachi_window_adjust(x1, x2, y1, y2);
360#elif defined(FEATURE_MDDI_S6D0142)
361 if (mfd->panel.id == MDDI_LCD_S6D0142)
362 mddi_s6d0142_window_adjust(x1, x2, y1, y2, done_cb);
363#else
364 /* Do nothing then... except avoid lint/compiler warnings */
365 (void)x1;
366 (void)x2;
367 (void)y1;
368 (void)y2;
369 (void)done_cb;
370#endif
371}
372
373void mddi_window_adjust(struct msm_fb_data_type *mfd,
374 uint16 x1, uint16 x2, uint16 y1, uint16 y2)
375{
376 mddi_window_adjust_ext(mfd, x1, x2, y1, y2, NULL);
377}
diff --git a/drivers/staging/msm/mddihost.h b/drivers/staging/msm/mddihost.h
new file mode 100644
index 000000000000..20b817841c4a
--- /dev/null
+++ b/drivers/staging/msm/mddihost.h
@@ -0,0 +1,225 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef MDDIHOST_H
30#define MDDIHOST_H
31
32#include <linux/kernel.h>
33#include <linux/sched.h>
34#include <linux/time.h>
35#include <linux/init.h>
36#include <linux/interrupt.h>
37#include "linux/proc_fs.h"
38#include <linux/types.h>
39#include <linux/dma-mapping.h>
40#include <linux/clk.h>
41
42#include <mach/hardware.h>
43#include <linux/io.h>
44
45#include <asm/system.h>
46#include <asm/mach-types.h>
47#include <linux/types.h>
48#include <linux/dma-mapping.h>
49
50#include "msm_fb_panel.h"
51
52#undef FEATURE_MDDI_MC4
53#undef FEATURE_MDDI_S6D0142
54#undef FEATURE_MDDI_HITACHI
55#define FEATURE_MDDI_SHARP
56#define FEATURE_MDDI_TOSHIBA
57#undef FEATURE_MDDI_E751
58#define FEATURE_MDDI_CORONA
59#define FEATURE_MDDI_PRISM
60
61#define T_MSM7500
62
63typedef enum {
64 format_16bpp,
65 format_18bpp,
66 format_24bpp
67} mddi_video_format;
68
69typedef enum {
70 MDDI_LCD_NONE = 0,
71 MDDI_LCD_MC4,
72 MDDI_LCD_S6D0142,
73 MDDI_LCD_SHARP,
74 MDDI_LCD_E751,
75 MDDI_LCD_CORONA,
76 MDDI_LCD_HITACHI,
77 MDDI_LCD_TOSHIBA,
78 MDDI_LCD_PRISM,
79 MDDI_LCD_TP2,
80 MDDI_NUM_LCD_TYPES,
81 MDDI_LCD_DEFAULT = MDDI_LCD_TOSHIBA
82} mddi_lcd_type;
83
84typedef enum {
85 MDDI_HOST_PRIM = 0,
86 MDDI_HOST_EXT,
87 MDDI_NUM_HOST_CORES
88} mddi_host_type;
89
90typedef enum {
91 MDDI_DRIVER_RESET, /* host core registers have not been written. */
92 MDDI_DRIVER_DISABLED, /* registers written, interrupts disabled. */
93 MDDI_DRIVER_ENABLED /* registers written, interrupts enabled. */
94} mddi_host_driver_state_type;
95
96typedef enum {
97 MDDI_GPIO_INT_0 = 0,
98 MDDI_GPIO_INT_1,
99 MDDI_GPIO_INT_2,
100 MDDI_GPIO_INT_3,
101 MDDI_GPIO_INT_4,
102 MDDI_GPIO_INT_5,
103 MDDI_GPIO_INT_6,
104 MDDI_GPIO_INT_7,
105 MDDI_GPIO_INT_8,
106 MDDI_GPIO_INT_9,
107 MDDI_GPIO_INT_10,
108 MDDI_GPIO_INT_11,
109 MDDI_GPIO_INT_12,
110 MDDI_GPIO_INT_13,
111 MDDI_GPIO_INT_14,
112 MDDI_GPIO_INT_15,
113 MDDI_GPIO_NUM_INTS
114} mddi_gpio_int_type;
115
116enum mddi_data_packet_size_type {
117 MDDI_DATA_PACKET_4_BYTES = 4,
118 MDDI_DATA_PACKET_8_BYTES = 8,
119 MDDI_DATA_PACKET_12_BYTES = 12,
120 MDDI_DATA_PACKET_16_BYTES = 16,
121 MDDI_DATA_PACKET_24_BYTES = 24
122};
123
124typedef struct {
125 uint32 addr;
126 uint32 value;
127} mddi_reg_write_type;
128
129boolean mddi_vsync_set_handler(msm_fb_vsync_handler_type handler, void *arg);
130
131typedef void (*mddi_llist_done_cb_type) (void);
132
133typedef void (*mddi_rev_handler_type) (void *);
134
135boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type);
136
137#define MDDI_DEFAULT_PRIM_PIX_ATTR 0xC3
138#define MDDI_DEFAULT_SECD_PIX_ATTR 0xC0
139
140typedef int gpio_int_polarity_type;
141typedef int gpio_int_handler_type;
142
143typedef struct {
144 void (*vsync_detected) (boolean);
145} mddi_lcd_func_type;
146
147extern mddi_lcd_func_type mddi_lcd;
148void mddi_init(void);
149
150void mddi_powerdown(void);
151
152void mddi_host_start_ext_display(void);
153void mddi_host_stop_ext_display(void);
154
155extern spinlock_t mddi_host_spin_lock;
156#ifdef T_MSM7500
157void mddi_reset(void);
158#ifdef FEATURE_DUAL_PROC_MODEM_DISPLAY
159void mddi_host_switch_proc_control(boolean on);
160#endif
161#endif
162void mddi_host_exit_power_collapse(void);
163
164void mddi_queue_splash_screen
165 (void *buf_ptr,
166 boolean clear_area,
167 int16 src_width,
168 int16 src_starting_row,
169 int16 src_starting_column,
170 int16 num_of_rows,
171 int16 num_of_columns, int16 dst_starting_row, int16 dst_starting_column);
172
173void mddi_queue_image
174 (void *buf_ptr,
175 uint8 stereo_video,
176 boolean clear_area,
177 int16 src_width,
178 int16 src_starting_row,
179 int16 src_starting_column,
180 int16 num_of_rows,
181 int16 num_of_columns, int16 dst_starting_row, int16 dst_starting_column);
182
183int mddi_host_register_read
184 (uint32 reg_addr,
185 uint32 *reg_value_ptr, boolean wait, mddi_host_type host_idx);
186int mddi_host_register_write
187 (uint32 reg_addr, uint32 reg_val,
188 enum mddi_data_packet_size_type packet_size,
189 boolean wait, mddi_llist_done_cb_type done_cb, mddi_host_type host);
190boolean mddi_host_register_write_int
191 (uint32 reg_addr,
192 uint32 reg_val, mddi_llist_done_cb_type done_cb, mddi_host_type host);
193boolean mddi_host_register_read_int
194 (uint32 reg_addr, uint32 *reg_value_ptr, mddi_host_type host_idx);
195void mddi_queue_register_write_static
196 (uint32 reg_addr,
197 uint32 reg_val, boolean wait, mddi_llist_done_cb_type done_cb);
198void mddi_queue_static_window_adjust
199 (const mddi_reg_write_type *reg_write,
200 uint16 num_writes, mddi_llist_done_cb_type done_cb);
201
202#define mddi_queue_register_read(reg, val_ptr, wait, sig) \
203 mddi_host_register_read(reg, val_ptr, wait, MDDI_HOST_PRIM)
204#define mddi_queue_register_write(reg, val, wait, sig) \
205 mddi_host_register_write(reg, val, MDDI_DATA_PACKET_4_BYTES,\
206 wait, NULL, MDDI_HOST_PRIM)
207#define mddi_queue_register_write_extn(reg, val, pkt_size, wait, sig) \
208 mddi_host_register_write(reg, val, pkt_size, \
209 wait, NULL, MDDI_HOST_PRIM)
210#define mddi_queue_register_write_int(reg, val) \
211 mddi_host_register_write_int(reg, val, NULL, MDDI_HOST_PRIM)
212#define mddi_queue_register_read_int(reg, val_ptr) \
213 mddi_host_register_read_int(reg, val_ptr, MDDI_HOST_PRIM)
214#define mddi_queue_register_writes(reg_ptr, val, wait, sig) \
215 mddi_host_register_writes(reg_ptr, val, wait, sig, MDDI_HOST_PRIM)
216
217void mddi_wait(uint16 time_ms);
218void mddi_assign_max_pkt_dimensions(uint16 image_cols,
219 uint16 image_rows,
220 uint16 bpp,
221 uint16 *max_cols, uint16 * max_rows);
222uint16 mddi_assign_pkt_height(uint16 pkt_width, uint16 pkt_height, uint16 bpp);
223void mddi_queue_reverse_encapsulation(boolean wait);
224void mddi_disable(int lock);
225#endif /* MDDIHOST_H */
diff --git a/drivers/staging/msm/mddihost_e.c b/drivers/staging/msm/mddihost_e.c
new file mode 100644
index 000000000000..7de5eda71ce3
--- /dev/null
+++ b/drivers/staging/msm/mddihost_e.c
@@ -0,0 +1,63 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/slab.h>
21#include <linux/delay.h>
22#include <linux/mm.h>
23#include <linux/fb.h>
24#include <linux/init.h>
25#include <linux/ioport.h>
26#include <linux/device.h>
27#include <linux/dma-mapping.h>
28
29#include "msm_fb.h"
30#include "mddihost.h"
31#include "mddihosti.h"
32
33#include <linux/clk.h>
34#include <mach/clk.h>
35
36extern struct semaphore mddi_host_mutex;
37static boolean mddi_host_ext_powered = FALSE;
38
39void mddi_host_start_ext_display(void)
40{
41 down(&mddi_host_mutex);
42
43 if (!mddi_host_ext_powered) {
44 mddi_host_init(MDDI_HOST_EXT);
45
46 mddi_host_ext_powered = TRUE;
47 }
48
49 up(&mddi_host_mutex);
50}
51
52void mddi_host_stop_ext_display(void)
53{
54 down(&mddi_host_mutex);
55
56 if (mddi_host_ext_powered) {
57 mddi_host_powerdown(MDDI_HOST_EXT);
58
59 mddi_host_ext_powered = FALSE;
60 }
61
62 up(&mddi_host_mutex);
63}
diff --git a/drivers/staging/msm/mddihosti.c b/drivers/staging/msm/mddihosti.c
new file mode 100644
index 000000000000..f9d6e91e8d5d
--- /dev/null
+++ b/drivers/staging/msm/mddihosti.c
@@ -0,0 +1,2239 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/slab.h>
21#include <linux/delay.h>
22#include <linux/mm.h>
23#include <linux/fb.h>
24#include <linux/init.h>
25#include <linux/ioport.h>
26#include <linux/device.h>
27#include <linux/dma-mapping.h>
28
29#include "msm_fb_panel.h"
30#include "mddihost.h"
31#include "mddihosti.h"
32
33#define FEATURE_MDDI_UNDERRUN_RECOVERY
34#ifndef FEATURE_MDDI_DISABLE_REVERSE
35static void mddi_read_rev_packet(byte *data_ptr);
36#endif
37
38struct timer_list mddi_host_timer;
39
40#define MDDI_DEFAULT_TIMER_LENGTH 5000 /* 5 seconds */
41uint32 mddi_rtd_frequency = 60000; /* send RTD every 60 seconds */
42uint32 mddi_client_status_frequency = 60000; /* get status pkt every 60 secs */
43
44boolean mddi_vsync_detect_enabled = FALSE;
45mddi_gpio_info_type mddi_gpio;
46
47uint32 mddi_host_core_version;
48boolean mddi_debug_log_statistics = FALSE;
49/* #define FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION */
50/* default to TRUE in case MDP does not vote */
51static boolean mddi_host_mdp_active_flag = TRUE;
52static uint32 mddi_log_stats_counter;
53uint32 mddi_log_stats_frequency = 4000;
54
55#define MDDI_DEFAULT_REV_PKT_SIZE 0x20
56
57#ifndef FEATURE_MDDI_DISABLE_REVERSE
58static boolean mddi_rev_ptr_workaround = TRUE;
59static uint32 mddi_reg_read_retry;
60static uint32 mddi_reg_read_retry_max = 20;
61static boolean mddi_enable_reg_read_retry = TRUE;
62static boolean mddi_enable_reg_read_retry_once = FALSE;
63
64#define MDDI_MAX_REV_PKT_SIZE 0x60
65
66#define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE 0x60
67
68#define MDDI_VIDEO_REV_PKT_SIZE 0x40
69#define MDDI_REV_BUFFER_SIZE MDDI_MAX_REV_PKT_SIZE
70static byte rev_packet_data[MDDI_MAX_REV_PKT_SIZE];
71#endif /* FEATURE_MDDI_DISABLE_REVERSE */
72/* leave these variables so graphics will compile */
73
74#define MDDI_MAX_REV_DATA_SIZE 128
75/*lint -d__align(x) */
76boolean mddi_debug_clear_rev_data = TRUE;
77
78uint32 *mddi_reg_read_value_ptr;
79
80mddi_client_capability_type mddi_client_capability_pkt;
81static boolean mddi_client_capability_request = FALSE;
82
83#ifndef FEATURE_MDDI_DISABLE_REVERSE
84
85#define MAX_MDDI_REV_HANDLERS 2
86#define INVALID_PKT_TYPE 0xFFFF
87
88typedef struct {
89 mddi_rev_handler_type handler; /* ISR to be executed */
90 uint16 pkt_type;
91} mddi_rev_pkt_handler_type;
92static mddi_rev_pkt_handler_type mddi_rev_pkt_handler[MAX_MDDI_REV_HANDLERS] =
93 { {NULL, INVALID_PKT_TYPE}, {NULL, INVALID_PKT_TYPE} };
94
95static boolean mddi_rev_encap_user_request = FALSE;
96static mddi_linked_list_notify_type mddi_rev_user;
97
98spinlock_t mddi_host_spin_lock;
99extern uint32 mdp_in_processing;
100#endif
101
102typedef enum {
103 MDDI_REV_IDLE
104#ifndef FEATURE_MDDI_DISABLE_REVERSE
105 , MDDI_REV_REG_READ_ISSUED,
106 MDDI_REV_REG_READ_SENT,
107 MDDI_REV_ENCAP_ISSUED,
108 MDDI_REV_STATUS_REQ_ISSUED,
109 MDDI_REV_CLIENT_CAP_ISSUED
110#endif
111} mddi_rev_link_state_type;
112
113typedef enum {
114 MDDI_LINK_DISABLED,
115 MDDI_LINK_HIBERNATING,
116 MDDI_LINK_ACTIVATING,
117 MDDI_LINK_ACTIVE
118} mddi_host_link_state_type;
119
120typedef struct {
121 uint32 count;
122 uint32 in_count;
123 uint32 disp_req_count;
124 uint32 state_change_count;
125 uint32 ll_done_count;
126 uint32 rev_avail_count;
127 uint32 error_count;
128 uint32 rev_encap_count;
129 uint32 llist_ptr_write_1;
130 uint32 llist_ptr_write_2;
131} mddi_host_int_type;
132
133typedef struct {
134 uint32 fwd_crc_count;
135 uint32 rev_crc_count;
136 uint32 pri_underflow;
137 uint32 sec_underflow;
138 uint32 rev_overflow;
139 uint32 pri_overwrite;
140 uint32 sec_overwrite;
141 uint32 rev_overwrite;
142 uint32 dma_failure;
143 uint32 rtd_failure;
144 uint32 reg_read_failure;
145#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
146 uint32 pri_underrun_detected;
147#endif
148} mddi_host_stat_type;
149
150typedef struct {
151 uint32 rtd_cnt;
152 uint32 rev_enc_cnt;
153 uint32 vid_cnt;
154 uint32 reg_acc_cnt;
155 uint32 cli_stat_cnt;
156 uint32 cli_cap_cnt;
157 uint32 reg_read_cnt;
158 uint32 link_active_cnt;
159 uint32 link_hibernate_cnt;
160 uint32 vsync_response_cnt;
161 uint32 fwd_crc_cnt;
162 uint32 rev_crc_cnt;
163} mddi_log_params_struct_type;
164
165typedef struct {
166 uint32 rtd_value;
167 uint32 rtd_counter;
168 uint32 client_status_cnt;
169 boolean rev_ptr_written;
170 uint8 *rev_ptr_start;
171 uint8 *rev_ptr_curr;
172 uint32 mddi_rev_ptr_write_val;
173 dma_addr_t rev_data_dma_addr;
174 uint16 rev_pkt_size;
175 mddi_rev_link_state_type rev_state;
176 mddi_host_link_state_type link_state;
177 mddi_host_driver_state_type driver_state;
178 boolean disable_hibernation;
179 uint32 saved_int_reg;
180 uint32 saved_int_en;
181 mddi_linked_list_type *llist_ptr;
182 dma_addr_t llist_dma_addr;
183 mddi_linked_list_type *llist_dma_ptr;
184 uint32 *rev_data_buf;
185 struct completion mddi_llist_avail_comp;
186 boolean mddi_waiting_for_llist_avail;
187 mddi_host_int_type int_type;
188 mddi_host_stat_type stats;
189 mddi_log_params_struct_type log_parms;
190 mddi_llist_info_type llist_info;
191 mddi_linked_list_notify_type llist_notify[MDDI_MAX_NUM_LLIST_ITEMS];
192} mddi_host_cntl_type;
193
194static mddi_host_type mddi_curr_host = MDDI_HOST_PRIM;
195static mddi_host_cntl_type mhctl[MDDI_NUM_HOST_CORES];
196mddi_linked_list_type *llist_extern[MDDI_NUM_HOST_CORES];
197mddi_linked_list_type *llist_dma_extern[MDDI_NUM_HOST_CORES];
198mddi_linked_list_notify_type *llist_extern_notify[MDDI_NUM_HOST_CORES];
199static mddi_log_params_struct_type prev_parms[MDDI_NUM_HOST_CORES];
200
201extern uint32 mdp_total_vdopkts;
202
203static boolean mddi_host_io_clock_on = FALSE;
204static boolean mddi_host_hclk_on = FALSE;
205
206int int_mddi_pri_flag = FALSE;
207int int_mddi_ext_flag = FALSE;
208
209static void mddi_report_errors(uint32 int_reg)
210{
211 mddi_host_type host_idx = mddi_curr_host;
212 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
213
214 if (int_reg & MDDI_INT_PRI_UNDERFLOW) {
215 pmhctl->stats.pri_underflow++;
216 MDDI_MSG_ERR("!!! MDDI Primary Underflow !!!\n");
217 }
218 if (int_reg & MDDI_INT_SEC_UNDERFLOW) {
219 pmhctl->stats.sec_underflow++;
220 MDDI_MSG_ERR("!!! MDDI Secondary Underflow !!!\n");
221 }
222#ifndef FEATURE_MDDI_DISABLE_REVERSE
223 if (int_reg & MDDI_INT_REV_OVERFLOW) {
224 pmhctl->stats.rev_overflow++;
225 MDDI_MSG_ERR("!!! MDDI Reverse Overflow !!!\n");
226 pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
227 mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val);
228
229 }
230 if (int_reg & MDDI_INT_CRC_ERROR)
231 MDDI_MSG_ERR("!!! MDDI Reverse CRC Error !!!\n");
232#endif
233 if (int_reg & MDDI_INT_PRI_OVERWRITE) {
234 pmhctl->stats.pri_overwrite++;
235 MDDI_MSG_ERR("!!! MDDI Primary Overwrite !!!\n");
236 }
237 if (int_reg & MDDI_INT_SEC_OVERWRITE) {
238 pmhctl->stats.sec_overwrite++;
239 MDDI_MSG_ERR("!!! MDDI Secondary Overwrite !!!\n");
240 }
241#ifndef FEATURE_MDDI_DISABLE_REVERSE
242 if (int_reg & MDDI_INT_REV_OVERWRITE) {
243 pmhctl->stats.rev_overwrite++;
244 /* This will show up normally and is not a problem */
245 MDDI_MSG_DEBUG("MDDI Reverse Overwrite!\n");
246 }
247 if (int_reg & MDDI_INT_RTD_FAILURE) {
248 mddi_host_reg_outm(INTEN, MDDI_INT_RTD_FAILURE, 0);
249 pmhctl->stats.rtd_failure++;
250 MDDI_MSG_ERR("!!! MDDI RTD Failure !!!\n");
251 }
252#endif
253 if (int_reg & MDDI_INT_DMA_FAILURE) {
254 pmhctl->stats.dma_failure++;
255 MDDI_MSG_ERR("!!! MDDI DMA Abort !!!\n");
256 }
257}
258
259static void mddi_host_enable_io_clock(void)
260{
261 if (!MDDI_HOST_IS_IO_CLOCK_ON)
262 MDDI_HOST_ENABLE_IO_CLOCK;
263}
264
265static void mddi_host_enable_hclk(void)
266{
267
268 if (!MDDI_HOST_IS_HCLK_ON)
269 MDDI_HOST_ENABLE_HCLK;
270}
271
272static void mddi_host_disable_io_clock(void)
273{
274#ifndef FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE
275 if (MDDI_HOST_IS_IO_CLOCK_ON)
276 MDDI_HOST_DISABLE_IO_CLOCK;
277#endif
278}
279
280static void mddi_host_disable_hclk(void)
281{
282#ifndef FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE
283 if (MDDI_HOST_IS_HCLK_ON)
284 MDDI_HOST_DISABLE_HCLK;
285#endif
286}
287
288static void mddi_vote_to_sleep(mddi_host_type host_idx, boolean sleep)
289{
290 uint16 vote_mask;
291
292 if (host_idx == MDDI_HOST_PRIM)
293 vote_mask = 0x01;
294 else
295 vote_mask = 0x02;
296}
297
298static void mddi_report_state_change(uint32 int_reg)
299{
300 mddi_host_type host_idx = mddi_curr_host;
301 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
302
303 if ((pmhctl->saved_int_reg & MDDI_INT_IN_HIBERNATION) &&
304 (pmhctl->saved_int_reg & MDDI_INT_LINK_ACTIVE)) {
305 /* recover from condition where the io_clock was turned off by the
306 clock driver during a transition to hibernation. The io_clock
307 disable is to prevent MDP/MDDI underruns when changing ARM
308 clock speeds. In the process of halting the ARM, the hclk
309 divider needs to be set to 1. When it is set to 1, there is
310 a small time (usecs) when hclk is off or slow, and this can
311 cause an underrun. To prevent the underrun, clock driver turns
312 off the MDDI io_clock before making the change. */
313 mddi_host_reg_out(CMD, MDDI_CMD_POWERUP);
314 }
315
316 if (int_reg & MDDI_INT_LINK_ACTIVE) {
317 pmhctl->link_state = MDDI_LINK_ACTIVE;
318 pmhctl->log_parms.link_active_cnt++;
319 pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL);
320 MDDI_MSG_DEBUG("!!! MDDI Active RTD:0x%x!!!\n",
321 pmhctl->rtd_value);
322 /* now interrupt on hibernation */
323 mddi_host_reg_outm(INTEN,
324 (MDDI_INT_IN_HIBERNATION |
325 MDDI_INT_LINK_ACTIVE),
326 MDDI_INT_IN_HIBERNATION);
327
328#ifdef DEBUG_MDDIHOSTI
329 /* if gpio interrupt is enabled, start polling at fastest
330 * registered rate
331 */
332 if (mddi_gpio.polling_enabled) {
333 timer_reg(&mddi_gpio_poll_timer,
334 mddi_gpio_poll_timer_cb, 0, mddi_gpio.polling_interval, 0);
335 }
336#endif
337#ifndef FEATURE_MDDI_DISABLE_REVERSE
338 if (mddi_rev_ptr_workaround) {
339 /* HW CR: need to reset reverse register stuff */
340 pmhctl->rev_ptr_written = FALSE;
341 pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
342 }
343#endif
344 /* vote on sleep */
345 mddi_vote_to_sleep(host_idx, FALSE);
346
347 if (host_idx == MDDI_HOST_PRIM) {
348 if (mddi_vsync_detect_enabled) {
349 /*
350 * Indicate to client specific code that vsync
351 * was enabled, but we did not detect a client
352 * intiated wakeup. The client specific
353 * handler can either reassert vsync detection,
354 * or treat this as a valid vsync.
355 */
356 mddi_client_lcd_vsync_detected(FALSE);
357 pmhctl->log_parms.vsync_response_cnt++;
358 }
359 }
360 }
361 if (int_reg & MDDI_INT_IN_HIBERNATION) {
362 pmhctl->link_state = MDDI_LINK_HIBERNATING;
363 pmhctl->log_parms.link_hibernate_cnt++;
364 MDDI_MSG_DEBUG("!!! MDDI Hibernating !!!\n");
365 /* now interrupt on link_active */
366#ifdef FEATURE_MDDI_DISABLE_REVERSE
367 mddi_host_reg_outm(INTEN,
368 (MDDI_INT_MDDI_IN |
369 MDDI_INT_IN_HIBERNATION |
370 MDDI_INT_LINK_ACTIVE),
371 MDDI_INT_LINK_ACTIVE);
372#else
373 mddi_host_reg_outm(INTEN,
374 (MDDI_INT_MDDI_IN |
375 MDDI_INT_IN_HIBERNATION |
376 MDDI_INT_LINK_ACTIVE),
377 (MDDI_INT_MDDI_IN | MDDI_INT_LINK_ACTIVE));
378
379 pmhctl->rtd_counter = mddi_rtd_frequency;
380
381 if (pmhctl->rev_state != MDDI_REV_IDLE) {
382 /* a rev_encap will not wake up the link, so we do that here */
383 pmhctl->link_state = MDDI_LINK_ACTIVATING;
384 mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
385 }
386#endif
387
388 if (pmhctl->disable_hibernation) {
389 mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
390 mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
391 pmhctl->link_state = MDDI_LINK_ACTIVATING;
392 }
393#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
394 if ((pmhctl->llist_info.transmitting_start_idx !=
395 UNASSIGNED_INDEX)
396 &&
397 ((pmhctl->
398 saved_int_reg & (MDDI_INT_PRI_LINK_LIST_DONE |
399 MDDI_INT_PRI_PTR_READ)) ==
400 MDDI_INT_PRI_PTR_READ)) {
401 mddi_linked_list_type *llist_dma;
402 llist_dma = pmhctl->llist_dma_ptr;
403 /*
404 * All indications are that we have not received a
405 * linked list done interrupt, due to an underrun
406 * condition. Recovery attempt is to send again.
407 */
408 dma_coherent_pre_ops();
409 /* Write to primary pointer register again */
410 mddi_host_reg_out(PRI_PTR,
411 &llist_dma[pmhctl->llist_info.
412 transmitting_start_idx]);
413 pmhctl->stats.pri_underrun_detected++;
414 }
415#endif
416
417 /* vote on sleep */
418 if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
419 mddi_vote_to_sleep(host_idx, TRUE);
420 }
421
422#ifdef DEBUG_MDDIHOSTI
423 /* need to stop polling timer */
424 if (mddi_gpio.polling_enabled) {
425 (void) timer_clr(&mddi_gpio_poll_timer, T_NONE);
426 }
427#endif
428 }
429}
430
431void mddi_host_timer_service(unsigned long data)
432{
433#ifndef FEATURE_MDDI_DISABLE_REVERSE
434 unsigned long flags;
435#endif
436 mddi_host_type host_idx;
437 mddi_host_cntl_type *pmhctl;
438
439 unsigned long time_ms = MDDI_DEFAULT_TIMER_LENGTH;
440 init_timer(&mddi_host_timer);
441 mddi_host_timer.function = mddi_host_timer_service;
442 mddi_host_timer.data = 0;
443
444 mddi_host_timer.expires = jiffies + ((time_ms * HZ) / 1000);
445 add_timer(&mddi_host_timer);
446
447 for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES;
448 host_idx++) {
449 pmhctl = &(mhctl[host_idx]);
450 mddi_log_stats_counter += (uint32) time_ms;
451#ifndef FEATURE_MDDI_DISABLE_REVERSE
452 pmhctl->rtd_counter += (uint32) time_ms;
453 pmhctl->client_status_cnt += (uint32) time_ms;
454
455 if (host_idx == MDDI_HOST_PRIM) {
456 if (pmhctl->client_status_cnt >=
457 mddi_client_status_frequency) {
458 if ((pmhctl->link_state ==
459 MDDI_LINK_HIBERNATING)
460 && (pmhctl->client_status_cnt >
461 mddi_client_status_frequency)) {
462 /*
463 * special case where we are hibernating
464 * and mddi_host_isr is not firing, so
465 * kick the link so that the status can
466 * be retrieved
467 */
468
469 /* need to wake up link before issuing
470 * rev encap command
471 */
472 MDDI_MSG_INFO("wake up link!\n");
473 spin_lock_irqsave(&mddi_host_spin_lock,
474 flags);
475 mddi_host_enable_hclk();
476 mddi_host_enable_io_clock();
477 pmhctl->link_state =
478 MDDI_LINK_ACTIVATING;
479 mddi_host_reg_out(CMD,
480 MDDI_CMD_LINK_ACTIVE);
481 spin_unlock_irqrestore
482 (&mddi_host_spin_lock, flags);
483 } else
484 if ((pmhctl->link_state == MDDI_LINK_ACTIVE)
485 && pmhctl->disable_hibernation) {
486 /*
487 * special case where we have disabled
488 * hibernation and mddi_host_isr
489 * is not firing, so enable interrupt
490 * for no pkts pending, which will
491 * generate an interrupt
492 */
493 MDDI_MSG_INFO("kick isr!\n");
494 spin_lock_irqsave(&mddi_host_spin_lock,
495 flags);
496 mddi_host_enable_hclk();
497 mddi_host_reg_outm(INTEN,
498 MDDI_INT_NO_CMD_PKTS_PEND,
499 MDDI_INT_NO_CMD_PKTS_PEND);
500 spin_unlock_irqrestore
501 (&mddi_host_spin_lock, flags);
502 }
503 }
504 }
505#endif /* #ifndef FEATURE_MDDI_DISABLE_REVERSE */
506 }
507
508 /* Check if logging is turned on */
509 for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES;
510 host_idx++) {
511 mddi_log_params_struct_type *prev_ptr = &(prev_parms[host_idx]);
512 pmhctl = &(mhctl[host_idx]);
513
514 if (mddi_debug_log_statistics) {
515
516 /* get video pkt count from MDP, since MDDI sw cannot know this */
517 pmhctl->log_parms.vid_cnt = mdp_total_vdopkts;
518
519 if (mddi_log_stats_counter >= mddi_log_stats_frequency) {
520 /* mddi_log_stats_counter = 0; */
521 if (mddi_debug_log_statistics) {
522 MDDI_MSG_NOTICE
523 ("MDDI Statistics since last report:\n");
524 MDDI_MSG_NOTICE(" Packets sent:\n");
525 MDDI_MSG_NOTICE
526 (" %d RTD packet(s)\n",
527 pmhctl->log_parms.rtd_cnt -
528 prev_ptr->rtd_cnt);
529 if (prev_ptr->rtd_cnt !=
530 pmhctl->log_parms.rtd_cnt) {
531 unsigned long flags;
532 spin_lock_irqsave
533 (&mddi_host_spin_lock,
534 flags);
535 mddi_host_enable_hclk();
536 pmhctl->rtd_value =
537 mddi_host_reg_in(RTD_VAL);
538 spin_unlock_irqrestore
539 (&mddi_host_spin_lock,
540 flags);
541 MDDI_MSG_NOTICE
542 (" RTD value=%d\n",
543 pmhctl->rtd_value);
544 }
545 MDDI_MSG_NOTICE
546 (" %d VIDEO packets\n",
547 pmhctl->log_parms.vid_cnt -
548 prev_ptr->vid_cnt);
549 MDDI_MSG_NOTICE
550 (" %d Register Access packets\n",
551 pmhctl->log_parms.reg_acc_cnt -
552 prev_ptr->reg_acc_cnt);
553 MDDI_MSG_NOTICE
554 (" %d Reverse Encapsulation packet(s)\n",
555 pmhctl->log_parms.rev_enc_cnt -
556 prev_ptr->rev_enc_cnt);
557 if (prev_ptr->rev_enc_cnt !=
558 pmhctl->log_parms.rev_enc_cnt) {
559 /* report # of reverse CRC errors */
560 MDDI_MSG_NOTICE
561 (" %d reverse CRC errors detected\n",
562 pmhctl->log_parms.
563 rev_crc_cnt -
564 prev_ptr->rev_crc_cnt);
565 }
566 MDDI_MSG_NOTICE
567 (" Packets received:\n");
568 MDDI_MSG_NOTICE
569 (" %d Client Status packets",
570 pmhctl->log_parms.cli_stat_cnt -
571 prev_ptr->cli_stat_cnt);
572 if (prev_ptr->cli_stat_cnt !=
573 pmhctl->log_parms.cli_stat_cnt) {
574 MDDI_MSG_NOTICE
575 (" %d forward CRC errors reported\n",
576 pmhctl->log_parms.
577 fwd_crc_cnt -
578 prev_ptr->fwd_crc_cnt);
579 }
580 MDDI_MSG_NOTICE
581 (" %d Register Access Read packets\n",
582 pmhctl->log_parms.reg_read_cnt -
583 prev_ptr->reg_read_cnt);
584
585 if (pmhctl->link_state ==
586 MDDI_LINK_ACTIVE) {
587 MDDI_MSG_NOTICE
588 (" Current Link Status: Active\n");
589 } else
590 if ((pmhctl->link_state ==
591 MDDI_LINK_HIBERNATING)
592 || (pmhctl->link_state ==
593 MDDI_LINK_ACTIVATING)) {
594 MDDI_MSG_NOTICE
595 (" Current Link Status: Hibernation\n");
596 } else {
597 MDDI_MSG_NOTICE
598 (" Current Link Status: Inactive\n");
599 }
600 MDDI_MSG_NOTICE
601 (" Active state entered %d times\n",
602 pmhctl->log_parms.link_active_cnt -
603 prev_ptr->link_active_cnt);
604 MDDI_MSG_NOTICE
605 (" Hibernation state entered %d times\n",
606 pmhctl->log_parms.
607 link_hibernate_cnt -
608 prev_ptr->link_hibernate_cnt);
609 }
610 }
611 prev_parms[host_idx] = pmhctl->log_parms;
612 }
613 }
614 if (mddi_log_stats_counter >= mddi_log_stats_frequency)
615 mddi_log_stats_counter = 0;
616
617 return;
618} /* mddi_host_timer_cb */
619
620static void mddi_process_link_list_done(void)
621{
622 mddi_host_type host_idx = mddi_curr_host;
623 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
624
625 /* normal forward linked list packet(s) were sent */
626 if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) {
627 MDDI_MSG_ERR("**** getting LL done, but no list ****\n");
628 } else {
629 uint16 idx;
630
631#ifndef FEATURE_MDDI_DISABLE_REVERSE
632 if (pmhctl->rev_state == MDDI_REV_REG_READ_ISSUED) {
633 /* special case where a register read packet was sent */
634 pmhctl->rev_state = MDDI_REV_REG_READ_SENT;
635 if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) {
636 MDDI_MSG_ERR
637 ("**** getting LL done, but no list ****\n");
638 }
639 }
640#endif
641 for (idx = pmhctl->llist_info.transmitting_start_idx;;) {
642 uint16 next_idx = pmhctl->llist_notify[idx].next_idx;
643 /* with reg read we don't release the waiting tcb until after
644 * the reverse encapsulation has completed.
645 */
646 if (idx != pmhctl->llist_info.reg_read_idx) {
647 /* notify task that may be waiting on this completion */
648 if (pmhctl->llist_notify[idx].waiting) {
649 complete(&
650 (pmhctl->llist_notify[idx].
651 done_comp));
652 }
653 if (pmhctl->llist_notify[idx].done_cb != NULL) {
654 (*(pmhctl->llist_notify[idx].done_cb))
655 ();
656 }
657
658 pmhctl->llist_notify[idx].in_use = FALSE;
659 pmhctl->llist_notify[idx].waiting = FALSE;
660 pmhctl->llist_notify[idx].done_cb = NULL;
661 if (idx < MDDI_NUM_DYNAMIC_LLIST_ITEMS) {
662 /* static LLIST items are configured only once */
663 pmhctl->llist_notify[idx].next_idx =
664 UNASSIGNED_INDEX;
665 }
666 /*
667 * currently, all linked list packets are
668 * register access, so we can increment the
669 * counter for that packet type here.
670 */
671 pmhctl->log_parms.reg_acc_cnt++;
672 }
673 if (idx == pmhctl->llist_info.transmitting_end_idx)
674 break;
675 idx = next_idx;
676 if (idx == UNASSIGNED_INDEX)
677 MDDI_MSG_CRIT("MDDI linked list corruption!\n");
678 }
679
680 pmhctl->llist_info.transmitting_start_idx = UNASSIGNED_INDEX;
681 pmhctl->llist_info.transmitting_end_idx = UNASSIGNED_INDEX;
682
683 if (pmhctl->mddi_waiting_for_llist_avail) {
684 if (!
685 (pmhctl->
686 llist_notify[pmhctl->llist_info.next_free_idx].
687 in_use)) {
688 pmhctl->mddi_waiting_for_llist_avail = FALSE;
689 complete(&(pmhctl->mddi_llist_avail_comp));
690 }
691 }
692 }
693
694 /* Turn off MDDI_INT_PRI_LINK_LIST_DONE interrupt */
695 mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, 0);
696
697}
698
699static void mddi_queue_forward_linked_list(void)
700{
701 uint16 first_pkt_index;
702 mddi_linked_list_type *llist_dma;
703 mddi_host_type host_idx = mddi_curr_host;
704 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
705 llist_dma = pmhctl->llist_dma_ptr;
706
707 first_pkt_index = UNASSIGNED_INDEX;
708
709 if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) {
710#ifndef FEATURE_MDDI_DISABLE_REVERSE
711 if (pmhctl->llist_info.reg_read_waiting) {
712 if (pmhctl->rev_state == MDDI_REV_IDLE) {
713 /*
714 * we have a register read to send and
715 * can send it now
716 */
717 pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED;
718 mddi_reg_read_retry = 0;
719 first_pkt_index =
720 pmhctl->llist_info.waiting_start_idx;
721 pmhctl->llist_info.reg_read_waiting = FALSE;
722 }
723 } else
724#endif
725 {
726 /*
727 * not register read to worry about, go ahead and write
728 * anything that may be on the waiting list.
729 */
730 first_pkt_index = pmhctl->llist_info.waiting_start_idx;
731 }
732 }
733
734 if (first_pkt_index != UNASSIGNED_INDEX) {
735 pmhctl->llist_info.transmitting_start_idx =
736 pmhctl->llist_info.waiting_start_idx;
737 pmhctl->llist_info.transmitting_end_idx =
738 pmhctl->llist_info.waiting_end_idx;
739 pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX;
740 pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX;
741
742 /* write to the primary pointer register */
743 MDDI_MSG_DEBUG("MDDI writing primary ptr with idx=%d\n",
744 first_pkt_index);
745
746 pmhctl->int_type.llist_ptr_write_2++;
747
748 dma_coherent_pre_ops();
749 mddi_host_reg_out(PRI_PTR, &llist_dma[first_pkt_index]);
750
751 /* enable interrupt when complete */
752 mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE,
753 MDDI_INT_PRI_LINK_LIST_DONE);
754
755 }
756
757}
758
759#ifndef FEATURE_MDDI_DISABLE_REVERSE
760static void mddi_read_rev_packet(byte *data_ptr)
761{
762 uint16 i, length;
763 mddi_host_type host_idx = mddi_curr_host;
764 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
765
766 uint8 *rev_ptr_overflow =
767 (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE);
768
769 /* first determine the length and handle invalid lengths */
770 length = *pmhctl->rev_ptr_curr++;
771 if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
772 pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
773 length |= ((*pmhctl->rev_ptr_curr++) << 8);
774 if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
775 pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
776 if (length > (pmhctl->rev_pkt_size - 2)) {
777 MDDI_MSG_ERR("Invalid rev pkt length %d\n", length);
778 /* rev_pkt_size should always be <= rev_ptr_size so limit to packet size */
779 length = pmhctl->rev_pkt_size - 2;
780 }
781
782 /* If the data pointer is NULL, just increment the pmhctl->rev_ptr_curr.
783 * Loop around if necessary. Don't bother reading the data.
784 */
785 if (data_ptr == NULL) {
786 pmhctl->rev_ptr_curr += length;
787 if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
788 pmhctl->rev_ptr_curr -= MDDI_REV_BUFFER_SIZE;
789 return;
790 }
791
792 data_ptr[0] = length & 0x0ff;
793 data_ptr[1] = length >> 8;
794 data_ptr += 2;
795 /* copy the data to data_ptr byte-at-a-time */
796 for (i = 0; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow);
797 i++)
798 *data_ptr++ = *pmhctl->rev_ptr_curr++;
799 if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
800 pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
801 for (; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow); i++)
802 *data_ptr++ = *pmhctl->rev_ptr_curr++;
803}
804
805static void mddi_process_rev_packets(void)
806{
807 uint32 rev_packet_count;
808 word i;
809 uint32 crc_errors;
810 boolean mddi_reg_read_successful = FALSE;
811 mddi_host_type host_idx = mddi_curr_host;
812 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
813
814 pmhctl->log_parms.rev_enc_cnt++;
815 if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) &&
816 (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED) &&
817 (pmhctl->rev_state != MDDI_REV_CLIENT_CAP_ISSUED)) {
818 MDDI_MSG_ERR("Wrong state %d for reverse int\n",
819 pmhctl->rev_state);
820 }
821 /* Turn off MDDI_INT_REV_AVAIL interrupt */
822 mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL, 0);
823
824 /* Clear rev data avail int */
825 mddi_host_reg_out(INT, MDDI_INT_REV_DATA_AVAIL);
826
827 /* Get Number of packets */
828 rev_packet_count = mddi_host_reg_in(REV_PKT_CNT);
829
830#ifndef T_MSM7500
831 /* Clear out rev packet counter */
832 mddi_host_reg_out(REV_PKT_CNT, 0x0000);
833#endif
834
835#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
836 if ((pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) &&
837 (rev_packet_count > 0) &&
838 (mddi_host_core_version == 0x28 ||
839 mddi_host_core_version == 0x30)) {
840
841 uint32 int_reg;
842 uint32 max_count = 0;
843
844 mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val);
845 int_reg = mddi_host_reg_in(INT);
846 while ((int_reg & 0x100000) == 0) {
847 udelay(3);
848 int_reg = mddi_host_reg_in(INT);
849 if (++max_count > 100)
850 break;
851 }
852 }
853#endif
854
855 /* Get CRC error count */
856 crc_errors = mddi_host_reg_in(REV_CRC_ERR);
857 if (crc_errors != 0) {
858 pmhctl->log_parms.rev_crc_cnt += crc_errors;
859 pmhctl->stats.rev_crc_count += crc_errors;
860 MDDI_MSG_ERR("!!! MDDI %d Reverse CRC Error(s) !!!\n",
861 crc_errors);
862#ifndef T_MSM7500
863 /* Clear CRC error count */
864 mddi_host_reg_out(REV_CRC_ERR, 0x0000);
865#endif
866 /* also issue an RTD to attempt recovery */
867 pmhctl->rtd_counter = mddi_rtd_frequency;
868 }
869
870 pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL);
871
872 MDDI_MSG_DEBUG("MDDI rev pkt cnt=%d, ptr=0x%x, RTD:0x%x\n",
873 rev_packet_count,
874 pmhctl->rev_ptr_curr - pmhctl->rev_ptr_start,
875 pmhctl->rtd_value);
876
877 if (rev_packet_count >= 1) {
878 mddi_invalidate_cache_lines((uint32 *) pmhctl->rev_ptr_start,
879 MDDI_REV_BUFFER_SIZE);
880 }
881 /* order the reads */
882 dma_coherent_post_ops();
883 for (i = 0; i < rev_packet_count; i++) {
884 mddi_rev_packet_type *rev_pkt_ptr;
885
886 mddi_read_rev_packet(rev_packet_data);
887
888 rev_pkt_ptr = (mddi_rev_packet_type *) rev_packet_data;
889
890 if (rev_pkt_ptr->packet_length > pmhctl->rev_pkt_size) {
891 MDDI_MSG_ERR("!!!invalid packet size: %d\n",
892 rev_pkt_ptr->packet_length);
893 }
894
895 MDDI_MSG_DEBUG("MDDI rev pkt 0x%x size 0x%x\n",
896 rev_pkt_ptr->packet_type,
897 rev_pkt_ptr->packet_length);
898
899 /* Do whatever you want to do with the data based on the packet type */
900 switch (rev_pkt_ptr->packet_type) {
901 case 66: /* Client Capability */
902 {
903 mddi_client_capability_type
904 *client_capability_pkt_ptr;
905
906 client_capability_pkt_ptr =
907 (mddi_client_capability_type *)
908 rev_packet_data;
909 MDDI_MSG_NOTICE
910 ("Client Capability: Week=%d, Year=%d\n",
911 client_capability_pkt_ptr->
912 Week_of_Manufacture,
913 client_capability_pkt_ptr->
914 Year_of_Manufacture);
915 memcpy((void *)&mddi_client_capability_pkt,
916 (void *)rev_packet_data,
917 sizeof(mddi_client_capability_type));
918 pmhctl->log_parms.cli_cap_cnt++;
919 }
920 break;
921
922 case 70: /* Display Status */
923 {
924 mddi_client_status_type *client_status_pkt_ptr;
925
926 client_status_pkt_ptr =
927 (mddi_client_status_type *) rev_packet_data;
928 if ((client_status_pkt_ptr->crc_error_count !=
929 0)
930 || (client_status_pkt_ptr->
931 reverse_link_request != 0)) {
932 MDDI_MSG_ERR
933 ("Client Status: RevReq=%d, CrcErr=%d\n",
934 client_status_pkt_ptr->
935 reverse_link_request,
936 client_status_pkt_ptr->
937 crc_error_count);
938 } else {
939 MDDI_MSG_DEBUG
940 ("Client Status: RevReq=%d, CrcErr=%d\n",
941 client_status_pkt_ptr->
942 reverse_link_request,
943 client_status_pkt_ptr->
944 crc_error_count);
945 }
946 pmhctl->log_parms.fwd_crc_cnt +=
947 client_status_pkt_ptr->crc_error_count;
948 pmhctl->stats.fwd_crc_count +=
949 client_status_pkt_ptr->crc_error_count;
950 pmhctl->log_parms.cli_stat_cnt++;
951 }
952 break;
953
954 case 146: /* register access packet */
955 {
956 mddi_register_access_packet_type
957 * regacc_pkt_ptr;
958
959 regacc_pkt_ptr =
960 (mddi_register_access_packet_type *)
961 rev_packet_data;
962
963 MDDI_MSG_DEBUG
964 ("Reg Acc parse reg=0x%x, value=0x%x\n",
965 regacc_pkt_ptr->register_address,
966 regacc_pkt_ptr->register_data_list);
967
968 /* Copy register value to location passed in */
969 if (mddi_reg_read_value_ptr) {
970#if defined(T_MSM6280) && !defined(T_MSM7200)
971 /* only least significant 16 bits are valid with 6280 */
972 *mddi_reg_read_value_ptr =
973 regacc_pkt_ptr->
974 register_data_list & 0x0000ffff;
975#else
976 *mddi_reg_read_value_ptr =
977 regacc_pkt_ptr->register_data_list;
978#endif
979 mddi_reg_read_successful = TRUE;
980 mddi_reg_read_value_ptr = NULL;
981 }
982
983#ifdef DEBUG_MDDIHOSTI
984 if ((mddi_gpio.polling_enabled) &&
985 (regacc_pkt_ptr->register_address ==
986 mddi_gpio.polling_reg)) {
987 /*
988 * ToDo: need to call Linux GPIO call
989 * here...
990 */
991 mddi_client_lcd_gpio_poll(
992 regacc_pkt_ptr->register_data_list);
993 }
994#endif
995 pmhctl->log_parms.reg_read_cnt++;
996 }
997 break;
998
999 default: /* any other packet */
1000 {
1001 uint16 hdlr;
1002
1003 for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS;
1004 hdlr++) {
1005 if (mddi_rev_pkt_handler[hdlr].
1006 pkt_type ==
1007 rev_pkt_ptr->packet_type) {
1008 (*
1009 (mddi_rev_pkt_handler[hdlr].
1010 handler)) (rev_pkt_ptr);
1011 /* pmhctl->rev_state = MDDI_REV_IDLE; */
1012 break;
1013 }
1014 }
1015 if (hdlr >= MAX_MDDI_REV_HANDLERS)
1016 MDDI_MSG_ERR("MDDI unknown rev pkt\n");
1017 }
1018 break;
1019 }
1020 }
1021 if ((pmhctl->rev_ptr_curr + pmhctl->rev_pkt_size) >=
1022 (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE)) {
1023 pmhctl->rev_ptr_written = FALSE;
1024 }
1025
1026 if (pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) {
1027 pmhctl->rev_state = MDDI_REV_IDLE;
1028 if (mddi_rev_user.waiting) {
1029 mddi_rev_user.waiting = FALSE;
1030 complete(&(mddi_rev_user.done_comp));
1031 } else if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) {
1032 MDDI_MSG_ERR
1033 ("Reverse Encap state, but no reg read in progress\n");
1034 } else {
1035 if ((!mddi_reg_read_successful) &&
1036 (mddi_reg_read_retry < mddi_reg_read_retry_max) &&
1037 (mddi_enable_reg_read_retry)) {
1038 /*
1039 * There is a race condition that can happen
1040 * where the reverse encapsulation message is
1041 * sent out by the MDDI host before the register
1042 * read packet is sent. As a work-around for
1043 * that problem we issue the reverse
1044 * encapsulation one more time before giving up.
1045 */
1046 if (mddi_enable_reg_read_retry_once)
1047 mddi_reg_read_retry =
1048 mddi_reg_read_retry_max;
1049 pmhctl->rev_state = MDDI_REV_REG_READ_SENT;
1050 pmhctl->stats.reg_read_failure++;
1051 } else {
1052 uint16 reg_read_idx =
1053 pmhctl->llist_info.reg_read_idx;
1054
1055 mddi_reg_read_retry = 0;
1056 if (pmhctl->llist_notify[reg_read_idx].waiting) {
1057 complete(&
1058 (pmhctl->
1059 llist_notify[reg_read_idx].
1060 done_comp));
1061 }
1062 pmhctl->llist_info.reg_read_idx =
1063 UNASSIGNED_INDEX;
1064 if (pmhctl->llist_notify[reg_read_idx].
1065 done_cb != NULL) {
1066 (*
1067 (pmhctl->llist_notify[reg_read_idx].
1068 done_cb)) ();
1069 }
1070 pmhctl->llist_notify[reg_read_idx].next_idx =
1071 UNASSIGNED_INDEX;
1072 pmhctl->llist_notify[reg_read_idx].in_use =
1073 FALSE;
1074 pmhctl->llist_notify[reg_read_idx].waiting =
1075 FALSE;
1076 pmhctl->llist_notify[reg_read_idx].done_cb =
1077 NULL;
1078 if (!mddi_reg_read_successful)
1079 pmhctl->stats.reg_read_failure++;
1080 }
1081 }
1082 } else if (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) {
1083#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
1084 if (mddi_host_core_version == 0x28 ||
1085 mddi_host_core_version == 0x30) {
1086 mddi_host_reg_out(FIFO_ALLOC, 0x00);
1087 pmhctl->rev_ptr_written = TRUE;
1088 mddi_host_reg_out(REV_PTR,
1089 pmhctl->mddi_rev_ptr_write_val);
1090 pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
1091 mddi_host_reg_out(CMD, 0xC00);
1092 }
1093#endif
1094
1095 if (mddi_rev_user.waiting) {
1096 mddi_rev_user.waiting = FALSE;
1097 complete(&(mddi_rev_user.done_comp));
1098 }
1099 pmhctl->rev_state = MDDI_REV_IDLE;
1100 } else {
1101 pmhctl->rev_state = MDDI_REV_IDLE;
1102 }
1103
1104 /* pmhctl->rev_state = MDDI_REV_IDLE; */
1105
1106 /* Re-enable interrupt */
1107 mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL,
1108 MDDI_INT_REV_DATA_AVAIL);
1109
1110}
1111
1112static void mddi_issue_reverse_encapsulation(void)
1113{
1114 mddi_host_type host_idx = mddi_curr_host;
1115 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1116 /* Only issue a reverse encapsulation packet if:
1117 * 1) another reverse is not in progress (MDDI_REV_IDLE).
1118 * 2) a register read has been sent (MDDI_REV_REG_READ_SENT).
1119 * 3) forward is not in progress, because of a hw bug in client that
1120 * causes forward crc errors on packet immediately after rev encap.
1121 */
1122 if (((pmhctl->rev_state == MDDI_REV_IDLE) ||
1123 (pmhctl->rev_state == MDDI_REV_REG_READ_SENT)) &&
1124 (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
1125 (!mdp_in_processing)) {
1126 uint32 mddi_command = MDDI_CMD_SEND_REV_ENCAP;
1127
1128 if ((pmhctl->rev_state == MDDI_REV_REG_READ_SENT) ||
1129 (mddi_rev_encap_user_request == TRUE)) {
1130 mddi_host_enable_io_clock();
1131 if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
1132 /* need to wake up link before issuing rev encap command */
1133 MDDI_MSG_DEBUG("wake up link!\n");
1134 pmhctl->link_state = MDDI_LINK_ACTIVATING;
1135 mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
1136 } else {
1137 if (pmhctl->rtd_counter >= mddi_rtd_frequency) {
1138 MDDI_MSG_DEBUG
1139 ("mddi sending RTD command!\n");
1140 mddi_host_reg_out(CMD,
1141 MDDI_CMD_SEND_RTD);
1142 pmhctl->rtd_counter = 0;
1143 pmhctl->log_parms.rtd_cnt++;
1144 }
1145 if (pmhctl->rev_state != MDDI_REV_REG_READ_SENT) {
1146 /* this is generic reverse request by user, so
1147 * reset the waiting flag. */
1148 mddi_rev_encap_user_request = FALSE;
1149 }
1150 /* link is active so send reverse encap to get register read results */
1151 pmhctl->rev_state = MDDI_REV_ENCAP_ISSUED;
1152 mddi_command = MDDI_CMD_SEND_REV_ENCAP;
1153 MDDI_MSG_DEBUG("sending rev encap!\n");
1154 }
1155 } else
1156 if ((pmhctl->client_status_cnt >=
1157 mddi_client_status_frequency)
1158 || mddi_client_capability_request) {
1159 mddi_host_enable_io_clock();
1160 if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
1161 /* only wake up the link if it client status is overdue */
1162 if ((pmhctl->client_status_cnt >=
1163 (mddi_client_status_frequency * 2))
1164 || mddi_client_capability_request) {
1165 /* need to wake up link before issuing rev encap command */
1166 MDDI_MSG_DEBUG("wake up link!\n");
1167 pmhctl->link_state =
1168 MDDI_LINK_ACTIVATING;
1169 mddi_host_reg_out(CMD,
1170 MDDI_CMD_LINK_ACTIVE);
1171 }
1172 } else {
1173 if (pmhctl->rtd_counter >= mddi_rtd_frequency) {
1174 MDDI_MSG_DEBUG
1175 ("mddi sending RTD command!\n");
1176 mddi_host_reg_out(CMD,
1177 MDDI_CMD_SEND_RTD);
1178 pmhctl->rtd_counter = 0;
1179 pmhctl->log_parms.rtd_cnt++;
1180 }
1181 /* periodically get client status */
1182 MDDI_MSG_DEBUG
1183 ("mddi sending rev enc! (get status)\n");
1184 if (mddi_client_capability_request) {
1185 pmhctl->rev_state =
1186 MDDI_REV_CLIENT_CAP_ISSUED;
1187 mddi_command = MDDI_CMD_GET_CLIENT_CAP;
1188 mddi_client_capability_request = FALSE;
1189 } else {
1190 pmhctl->rev_state =
1191 MDDI_REV_STATUS_REQ_ISSUED;
1192 pmhctl->client_status_cnt = 0;
1193 mddi_command =
1194 MDDI_CMD_GET_CLIENT_STATUS;
1195 }
1196 }
1197 }
1198 if ((pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) ||
1199 (pmhctl->rev_state == MDDI_REV_STATUS_REQ_ISSUED) ||
1200 (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED)) {
1201 pmhctl->int_type.rev_encap_count++;
1202#if defined(T_MSM6280) && !defined(T_MSM7200)
1203 mddi_rev_pointer_written = TRUE;
1204 mddi_host_reg_out(REV_PTR, mddi_rev_ptr_write_val);
1205 mddi_rev_ptr_curr = mddi_rev_ptr_start;
1206 /* force new rev ptr command */
1207 mddi_host_reg_out(CMD, 0xC00);
1208#else
1209 if (!pmhctl->rev_ptr_written) {
1210 MDDI_MSG_DEBUG("writing reverse pointer!\n");
1211 pmhctl->rev_ptr_written = TRUE;
1212#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
1213 if ((pmhctl->rev_state ==
1214 MDDI_REV_CLIENT_CAP_ISSUED) &&
1215 (mddi_host_core_version == 0x28 ||
1216 mddi_host_core_version == 0x30)) {
1217 pmhctl->rev_ptr_written = FALSE;
1218 mddi_host_reg_out(FIFO_ALLOC, 0x02);
1219 } else
1220 mddi_host_reg_out(REV_PTR,
1221 pmhctl->
1222 mddi_rev_ptr_write_val);
1223#else
1224 mddi_host_reg_out(REV_PTR,
1225 pmhctl->
1226 mddi_rev_ptr_write_val);
1227#endif
1228 }
1229#endif
1230 if (mddi_debug_clear_rev_data) {
1231 uint16 i;
1232 for (i = 0; i < MDDI_MAX_REV_DATA_SIZE / 4; i++)
1233 pmhctl->rev_data_buf[i] = 0xdddddddd;
1234 /* clean cache */
1235 mddi_flush_cache_lines(pmhctl->rev_data_buf,
1236 MDDI_MAX_REV_DATA_SIZE);
1237 }
1238
1239 /* send reverse encapsulation to get needed data */
1240 mddi_host_reg_out(CMD, mddi_command);
1241 }
1242 }
1243
1244}
1245
1246static void mddi_process_client_initiated_wakeup(void)
1247{
1248 mddi_host_type host_idx = mddi_curr_host;
1249 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1250
1251 /* Disable MDDI_INT Interrupt, we detect client initiated wakeup one
1252 * time for each entry into hibernation */
1253 mddi_host_reg_outm(INTEN, MDDI_INT_MDDI_IN, 0);
1254
1255 if (host_idx == MDDI_HOST_PRIM) {
1256 if (mddi_vsync_detect_enabled) {
1257 mddi_host_enable_io_clock();
1258#ifndef MDDI_HOST_DISP_LISTEN
1259 /* issue command to bring up link */
1260 /* need to do this to clear the vsync condition */
1261 if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
1262 pmhctl->link_state = MDDI_LINK_ACTIVATING;
1263 mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
1264 }
1265#endif
1266 /*
1267 * Indicate to client specific code that vsync was
1268 * enabled, and we did not detect a client initiated
1269 * wakeup. The client specific handler can clear the
1270 * condition if necessary to prevent subsequent
1271 * client initiated wakeups.
1272 */
1273 mddi_client_lcd_vsync_detected(TRUE);
1274 pmhctl->log_parms.vsync_response_cnt++;
1275 MDDI_MSG_NOTICE("MDDI_INT_IN condition\n");
1276
1277 }
1278 }
1279
1280 if (mddi_gpio.polling_enabled) {
1281 mddi_host_enable_io_clock();
1282 /* check interrupt status now */
1283 (void)mddi_queue_register_read_int(mddi_gpio.polling_reg,
1284 &mddi_gpio.polling_val);
1285 }
1286}
1287#endif /* FEATURE_MDDI_DISABLE_REVERSE */
1288
1289static void mddi_host_isr(void)
1290{
1291 uint32 int_reg, int_en;
1292#ifndef FEATURE_MDDI_DISABLE_REVERSE
1293 uint32 status_reg;
1294#endif
1295 mddi_host_type host_idx = mddi_curr_host;
1296 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1297
1298 if (!MDDI_HOST_IS_HCLK_ON) {
1299 MDDI_HOST_ENABLE_HCLK;
1300 MDDI_MSG_DEBUG("HCLK disabled, but isr is firing\n");
1301 }
1302 int_reg = mddi_host_reg_in(INT);
1303 int_en = mddi_host_reg_in(INTEN);
1304 pmhctl->saved_int_reg = int_reg;
1305 pmhctl->saved_int_en = int_en;
1306 int_reg = int_reg & int_en;
1307 pmhctl->int_type.count++;
1308
1309
1310#ifndef FEATURE_MDDI_DISABLE_REVERSE
1311 status_reg = mddi_host_reg_in(STAT);
1312
1313 if ((int_reg & MDDI_INT_MDDI_IN) ||
1314 ((int_en & MDDI_INT_MDDI_IN) &&
1315 ((int_reg == 0) || (status_reg & MDDI_STAT_CLIENT_WAKEUP_REQ)))) {
1316 /*
1317 * The MDDI_IN condition will clear itself, and so it is
1318 * possible that MDDI_IN was the reason for the isr firing,
1319 * even though the interrupt register does not have the
1320 * MDDI_IN bit set. To check if this was the case we need to
1321 * look at the status register bit that signifies a client
1322 * initiated wakeup. If the status register bit is set, as well
1323 * as the MDDI_IN interrupt enabled, then we treat this as a
1324 * client initiated wakeup.
1325 */
1326 if (int_reg & MDDI_INT_MDDI_IN)
1327 pmhctl->int_type.in_count++;
1328 mddi_process_client_initiated_wakeup();
1329 }
1330#endif
1331
1332 if (int_reg & MDDI_INT_LINK_STATE_CHANGES) {
1333 pmhctl->int_type.state_change_count++;
1334 mddi_report_state_change(int_reg);
1335 }
1336
1337 if (int_reg & MDDI_INT_PRI_LINK_LIST_DONE) {
1338 pmhctl->int_type.ll_done_count++;
1339 mddi_process_link_list_done();
1340 }
1341#ifndef FEATURE_MDDI_DISABLE_REVERSE
1342 if (int_reg & MDDI_INT_REV_DATA_AVAIL) {
1343 pmhctl->int_type.rev_avail_count++;
1344 mddi_process_rev_packets();
1345 }
1346#endif
1347
1348 if (int_reg & MDDI_INT_ERROR_CONDITIONS) {
1349 pmhctl->int_type.error_count++;
1350 mddi_report_errors(int_reg);
1351
1352 mddi_host_reg_out(INT, int_reg & MDDI_INT_ERROR_CONDITIONS);
1353 }
1354#ifndef FEATURE_MDDI_DISABLE_REVERSE
1355 mddi_issue_reverse_encapsulation();
1356
1357 if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) &&
1358 (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED))
1359#endif
1360 /* don't want simultaneous reverse and forward with Eagle */
1361 mddi_queue_forward_linked_list();
1362
1363 if (int_reg & MDDI_INT_NO_CMD_PKTS_PEND) {
1364 /* this interrupt is used to kick the isr when hibernation is disabled */
1365 mddi_host_reg_outm(INTEN, MDDI_INT_NO_CMD_PKTS_PEND, 0);
1366 }
1367
1368 if ((!mddi_host_mdp_active_flag) &&
1369 (!mddi_vsync_detect_enabled) &&
1370 (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
1371 (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) &&
1372 (pmhctl->rev_state == MDDI_REV_IDLE)) {
1373 if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
1374 mddi_host_disable_io_clock();
1375 mddi_host_disable_hclk();
1376 }
1377#ifdef FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION
1378 else if ((pmhctl->link_state == MDDI_LINK_ACTIVE) &&
1379 (!pmhctl->disable_hibernation)) {
1380 mddi_host_reg_out(CMD, MDDI_CMD_POWERDOWN);
1381 }
1382#endif
1383 }
1384}
1385
1386static void mddi_host_isr_primary(void)
1387{
1388 mddi_curr_host = MDDI_HOST_PRIM;
1389 mddi_host_isr();
1390}
1391
1392irqreturn_t mddi_pmdh_isr_proxy(int irq, void *ptr)
1393{
1394 mddi_host_isr_primary();
1395 return IRQ_HANDLED;
1396}
1397
1398static void mddi_host_isr_external(void)
1399{
1400 mddi_curr_host = MDDI_HOST_EXT;
1401 mddi_host_isr();
1402 mddi_curr_host = MDDI_HOST_PRIM;
1403}
1404
1405irqreturn_t mddi_emdh_isr_proxy(int irq, void *ptr)
1406{
1407 mddi_host_isr_external();
1408 return IRQ_HANDLED;
1409}
1410
1411static void mddi_host_initialize_registers(mddi_host_type host_idx)
1412{
1413 uint32 pad_reg_val;
1414 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1415
1416 if (pmhctl->driver_state == MDDI_DRIVER_ENABLED)
1417 return;
1418
1419 /* turn on HCLK to MDDI host core */
1420 mddi_host_enable_hclk();
1421
1422 /* MDDI Reset command */
1423 mddi_host_reg_out(CMD, MDDI_CMD_RESET);
1424
1425 /* Version register (= 0x01) */
1426 mddi_host_reg_out(VERSION, 0x0001);
1427
1428 /* Bytes per subframe register */
1429 mddi_host_reg_out(BPS, MDDI_HOST_BYTES_PER_SUBFRAME);
1430
1431 /* Subframes per media frames register (= 0x03) */
1432 mddi_host_reg_out(SPM, 0x0003);
1433
1434 /* Turn Around 1 register (= 0x05) */
1435 mddi_host_reg_out(TA1_LEN, 0x0005);
1436
1437 /* Turn Around 2 register (= 0x0C) */
1438 mddi_host_reg_out(TA2_LEN, MDDI_HOST_TA2_LEN);
1439
1440 /* Drive hi register (= 0x96) */
1441 mddi_host_reg_out(DRIVE_HI, 0x0096);
1442
1443 /* Drive lo register (= 0x32) */
1444 mddi_host_reg_out(DRIVE_LO, 0x0032);
1445
1446 /* Display wakeup count register (= 0x3c) */
1447 mddi_host_reg_out(DISP_WAKE, 0x003c);
1448
1449 /* Reverse Rate Divisor register (= 0x2) */
1450 mddi_host_reg_out(REV_RATE_DIV, MDDI_HOST_REV_RATE_DIV);
1451
1452#ifndef FEATURE_MDDI_DISABLE_REVERSE
1453 /* Reverse Pointer Size */
1454 mddi_host_reg_out(REV_SIZE, MDDI_REV_BUFFER_SIZE);
1455
1456 /* Rev Encap Size */
1457 mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
1458#endif
1459
1460 /* Periodic Rev Encap */
1461 /* don't send periodically */
1462 mddi_host_reg_out(CMD, MDDI_CMD_PERIODIC_REV_ENCAP);
1463
1464 pad_reg_val = mddi_host_reg_in(PAD_CTL);
1465 if (pad_reg_val == 0) {
1466 /* If we are turning on band gap, need to wait 5us before turning
1467 * on the rest of the PAD */
1468 mddi_host_reg_out(PAD_CTL, 0x08000);
1469 udelay(5);
1470 }
1471#ifdef T_MSM7200
1472 /* Recommendation from PAD hw team */
1473 mddi_host_reg_out(PAD_CTL, 0xa850a);
1474#else
1475 /* Recommendation from PAD hw team */
1476 mddi_host_reg_out(PAD_CTL, 0xa850f);
1477#endif
1478
1479#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
1480 mddi_host_reg_out(PAD_IO_CTL, 0x00320000);
1481 mddi_host_reg_out(PAD_CAL, 0x00220020);
1482#endif
1483
1484 mddi_host_core_version = mddi_host_reg_inm(CORE_VER, 0xffff);
1485
1486#ifndef FEATURE_MDDI_DISABLE_REVERSE
1487 if (mddi_host_core_version >= 8)
1488 mddi_rev_ptr_workaround = FALSE;
1489 pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
1490#endif
1491
1492 if ((mddi_host_core_version > 8) && (mddi_host_core_version < 0x19))
1493 mddi_host_reg_out(TEST, 0x2);
1494
1495 /* Need an even number for counts */
1496 mddi_host_reg_out(DRIVER_START_CNT, 0x60006);
1497
1498#ifndef T_MSM7500
1499 /* Setup defaults for MDP related register */
1500 mddi_host_reg_out(MDP_VID_FMT_DES, 0x5666);
1501 mddi_host_reg_out(MDP_VID_PIX_ATTR, 0x00C3);
1502 mddi_host_reg_out(MDP_VID_CLIENTID, 0);
1503#endif
1504
1505 /* automatically hibernate after 1 empty subframe */
1506 if (pmhctl->disable_hibernation)
1507 mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
1508 else
1509 mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
1510
1511 /* Bring up link if display (client) requests it */
1512#ifdef MDDI_HOST_DISP_LISTEN
1513 mddi_host_reg_out(CMD, MDDI_CMD_DISP_LISTEN);
1514#else
1515 mddi_host_reg_out(CMD, MDDI_CMD_DISP_IGNORE);
1516#endif
1517
1518}
1519
1520void mddi_host_configure_interrupts(mddi_host_type host_idx, boolean enable)
1521{
1522 unsigned long flags;
1523 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1524
1525 spin_lock_irqsave(&mddi_host_spin_lock, flags);
1526
1527 /* turn on HCLK to MDDI host core if it has been disabled */
1528 mddi_host_enable_hclk();
1529 /* Clear MDDI Interrupt enable reg */
1530 mddi_host_reg_out(INTEN, 0);
1531
1532 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
1533
1534 if (enable) {
1535 pmhctl->driver_state = MDDI_DRIVER_ENABLED;
1536
1537 if (host_idx == MDDI_HOST_PRIM) {
1538 if (request_irq
1539 (INT_MDDI_PRI, mddi_pmdh_isr_proxy, IRQF_DISABLED,
1540 "PMDH", 0) != 0)
1541 printk(KERN_ERR
1542 "a mddi: unable to request_irq\n");
1543 else
1544 int_mddi_pri_flag = TRUE;
1545 } else {
1546 if (request_irq
1547 (INT_MDDI_EXT, mddi_emdh_isr_proxy, IRQF_DISABLED,
1548 "EMDH", 0) != 0)
1549 printk(KERN_ERR
1550 "b mddi: unable to request_irq\n");
1551 else
1552 int_mddi_ext_flag = TRUE;
1553 }
1554
1555 /* Set MDDI Interrupt enable reg -- Enable Reverse data avail */
1556#ifdef FEATURE_MDDI_DISABLE_REVERSE
1557 mddi_host_reg_out(INTEN,
1558 MDDI_INT_ERROR_CONDITIONS |
1559 MDDI_INT_LINK_STATE_CHANGES);
1560#else
1561 /* Reverse Pointer register */
1562 pmhctl->rev_ptr_written = FALSE;
1563
1564 mddi_host_reg_out(INTEN,
1565 MDDI_INT_REV_DATA_AVAIL |
1566 MDDI_INT_ERROR_CONDITIONS |
1567 MDDI_INT_LINK_STATE_CHANGES);
1568 pmhctl->rtd_counter = mddi_rtd_frequency;
1569 pmhctl->client_status_cnt = 0;
1570#endif
1571 } else {
1572 if (pmhctl->driver_state == MDDI_DRIVER_ENABLED)
1573 pmhctl->driver_state = MDDI_DRIVER_DISABLED;
1574 }
1575
1576}
1577
1578static void mddi_host_powerup(mddi_host_type host_idx)
1579{
1580 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1581
1582 if (pmhctl->link_state != MDDI_LINK_DISABLED)
1583 return;
1584
1585 /* enable IO_CLK and hclk to MDDI host core */
1586 mddi_host_enable_io_clock();
1587
1588 mddi_host_initialize_registers(host_idx);
1589 mddi_host_configure_interrupts(host_idx, TRUE);
1590
1591 pmhctl->link_state = MDDI_LINK_ACTIVATING;
1592
1593 /* Link activate command */
1594 mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
1595
1596#ifdef CLKRGM_MDDI_IO_CLOCK_IN_MHZ
1597 MDDI_MSG_NOTICE("MDDI Host: Activating Link %d Mbps\n",
1598 CLKRGM_MDDI_IO_CLOCK_IN_MHZ * 2);
1599#else
1600 MDDI_MSG_NOTICE("MDDI Host: Activating Link\n");
1601#endif
1602
1603 /* Initialize the timer */
1604 if (host_idx == MDDI_HOST_PRIM)
1605 mddi_host_timer_service(0);
1606}
1607
1608void mddi_host_init(mddi_host_type host_idx)
1609/* Write out the MDDI configuration registers */
1610{
1611 static boolean initialized = FALSE;
1612 mddi_host_cntl_type *pmhctl;
1613
1614 if (host_idx >= MDDI_NUM_HOST_CORES) {
1615 MDDI_MSG_ERR("Invalid host core index\n");
1616 return;
1617 }
1618
1619 if (!initialized) {
1620 uint16 idx;
1621 mddi_host_type host;
1622 for (host = MDDI_HOST_PRIM; host < MDDI_NUM_HOST_CORES; host++) {
1623 pmhctl = &(mhctl[host]);
1624 initialized = TRUE;
1625
1626 pmhctl->llist_ptr =
1627 dma_alloc_coherent(NULL, MDDI_LLIST_POOL_SIZE,
1628 &(pmhctl->llist_dma_addr),
1629 GFP_KERNEL);
1630 pmhctl->llist_dma_ptr =
1631 (mddi_linked_list_type *) (void *)pmhctl->
1632 llist_dma_addr;
1633#ifdef FEATURE_MDDI_DISABLE_REVERSE
1634 pmhctl->rev_data_buf = NULL;
1635 if (pmhctl->llist_ptr == NULL)
1636#else
1637 mddi_rev_user.waiting = FALSE;
1638 init_completion(&(mddi_rev_user.done_comp));
1639 pmhctl->rev_data_buf =
1640 dma_alloc_coherent(NULL, MDDI_MAX_REV_DATA_SIZE,
1641 &(pmhctl->rev_data_dma_addr),
1642 GFP_KERNEL);
1643 if ((pmhctl->llist_ptr == NULL)
1644 || (pmhctl->rev_data_buf == NULL))
1645#endif
1646 {
1647 MDDI_MSG_CRIT
1648 ("unable to alloc non-cached memory\n");
1649 }
1650 llist_extern[host] = pmhctl->llist_ptr;
1651 llist_dma_extern[host] = pmhctl->llist_dma_ptr;
1652 llist_extern_notify[host] = pmhctl->llist_notify;
1653
1654 for (idx = 0; idx < UNASSIGNED_INDEX; idx++) {
1655 init_completion(&
1656 (pmhctl->llist_notify[idx].
1657 done_comp));
1658 }
1659 init_completion(&(pmhctl->mddi_llist_avail_comp));
1660 spin_lock_init(&mddi_host_spin_lock);
1661 pmhctl->mddi_waiting_for_llist_avail = FALSE;
1662 pmhctl->mddi_rev_ptr_write_val =
1663 (uint32) (void *)(pmhctl->rev_data_dma_addr);
1664 pmhctl->rev_ptr_start = (void *)pmhctl->rev_data_buf;
1665
1666 pmhctl->rev_pkt_size = MDDI_DEFAULT_REV_PKT_SIZE;
1667 pmhctl->rev_state = MDDI_REV_IDLE;
1668#ifdef IMAGE_MODEM_PROC
1669 /* assume hibernation state is last state from APPS proc, so that
1670 * we don't reinitialize the host core */
1671 pmhctl->link_state = MDDI_LINK_HIBERNATING;
1672#else
1673 pmhctl->link_state = MDDI_LINK_DISABLED;
1674#endif
1675 pmhctl->driver_state = MDDI_DRIVER_DISABLED;
1676 pmhctl->disable_hibernation = FALSE;
1677
1678 /* initialize llist variables */
1679 pmhctl->llist_info.transmitting_start_idx =
1680 UNASSIGNED_INDEX;
1681 pmhctl->llist_info.transmitting_end_idx =
1682 UNASSIGNED_INDEX;
1683 pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX;
1684 pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX;
1685 pmhctl->llist_info.reg_read_idx = UNASSIGNED_INDEX;
1686 pmhctl->llist_info.next_free_idx =
1687 MDDI_FIRST_DYNAMIC_LLIST_IDX;
1688 pmhctl->llist_info.reg_read_waiting = FALSE;
1689
1690 mddi_vsync_detect_enabled = FALSE;
1691 mddi_gpio.polling_enabled = FALSE;
1692
1693 pmhctl->int_type.count = 0;
1694 pmhctl->int_type.in_count = 0;
1695 pmhctl->int_type.disp_req_count = 0;
1696 pmhctl->int_type.state_change_count = 0;
1697 pmhctl->int_type.ll_done_count = 0;
1698 pmhctl->int_type.rev_avail_count = 0;
1699 pmhctl->int_type.error_count = 0;
1700 pmhctl->int_type.rev_encap_count = 0;
1701 pmhctl->int_type.llist_ptr_write_1 = 0;
1702 pmhctl->int_type.llist_ptr_write_2 = 0;
1703
1704 pmhctl->stats.fwd_crc_count = 0;
1705 pmhctl->stats.rev_crc_count = 0;
1706 pmhctl->stats.pri_underflow = 0;
1707 pmhctl->stats.sec_underflow = 0;
1708 pmhctl->stats.rev_overflow = 0;
1709 pmhctl->stats.pri_overwrite = 0;
1710 pmhctl->stats.sec_overwrite = 0;
1711 pmhctl->stats.rev_overwrite = 0;
1712 pmhctl->stats.dma_failure = 0;
1713 pmhctl->stats.rtd_failure = 0;
1714 pmhctl->stats.reg_read_failure = 0;
1715#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
1716 pmhctl->stats.pri_underrun_detected = 0;
1717#endif
1718
1719 pmhctl->log_parms.rtd_cnt = 0;
1720 pmhctl->log_parms.rev_enc_cnt = 0;
1721 pmhctl->log_parms.vid_cnt = 0;
1722 pmhctl->log_parms.reg_acc_cnt = 0;
1723 pmhctl->log_parms.cli_stat_cnt = 0;
1724 pmhctl->log_parms.cli_cap_cnt = 0;
1725 pmhctl->log_parms.reg_read_cnt = 0;
1726 pmhctl->log_parms.link_active_cnt = 0;
1727 pmhctl->log_parms.link_hibernate_cnt = 0;
1728 pmhctl->log_parms.fwd_crc_cnt = 0;
1729 pmhctl->log_parms.rev_crc_cnt = 0;
1730 pmhctl->log_parms.vsync_response_cnt = 0;
1731
1732 prev_parms[host_idx] = pmhctl->log_parms;
1733 mddi_client_capability_pkt.packet_length = 0;
1734 }
1735
1736#ifndef T_MSM7500
1737 /* tell clock driver we are user of this PLL */
1738 MDDI_HOST_ENABLE_IO_CLOCK;
1739#endif
1740 }
1741
1742 mddi_host_powerup(host_idx);
1743 pmhctl = &(mhctl[host_idx]);
1744}
1745
1746#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
1747static uint32 mddi_client_id;
1748
1749uint32 mddi_get_client_id(void)
1750{
1751
1752#ifndef FEATURE_MDDI_DISABLE_REVERSE
1753 mddi_host_type host_idx = MDDI_HOST_PRIM;
1754 static boolean client_detection_try = FALSE;
1755 mddi_host_cntl_type *pmhctl;
1756 unsigned long flags;
1757 uint16 saved_rev_pkt_size;
1758
1759 if (!client_detection_try) {
1760 /* Toshiba display requires larger drive_lo value */
1761 mddi_host_reg_out(DRIVE_LO, 0x0050);
1762
1763 pmhctl = &(mhctl[MDDI_HOST_PRIM]);
1764
1765 saved_rev_pkt_size = pmhctl->rev_pkt_size;
1766
1767 /* Increase Rev Encap Size */
1768 pmhctl->rev_pkt_size = MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE;
1769 mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
1770
1771 /* disable hibernation temporarily */
1772 if (!pmhctl->disable_hibernation)
1773 mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
1774
1775 mddi_rev_user.waiting = TRUE;
1776 INIT_COMPLETION(mddi_rev_user.done_comp);
1777
1778 spin_lock_irqsave(&mddi_host_spin_lock, flags);
1779
1780 /* turn on clock(s), if they have been disabled */
1781 mddi_host_enable_hclk();
1782 mddi_host_enable_io_clock();
1783
1784 mddi_client_capability_request = TRUE;
1785
1786 if (pmhctl->rev_state == MDDI_REV_IDLE) {
1787 /* attempt to send the reverse encapsulation now */
1788 mddi_issue_reverse_encapsulation();
1789 }
1790 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
1791
1792 wait_for_completion_killable(&(mddi_rev_user.done_comp));
1793
1794 /* Set Rev Encap Size back to its original value */
1795 pmhctl->rev_pkt_size = saved_rev_pkt_size;
1796 mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
1797
1798 /* reenable auto-hibernate */
1799 if (!pmhctl->disable_hibernation)
1800 mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
1801
1802 mddi_host_reg_out(DRIVE_LO, 0x0032);
1803 client_detection_try = TRUE;
1804
1805 mddi_client_id = (mddi_client_capability_pkt.Mfr_Name<<16) |
1806 mddi_client_capability_pkt.Product_Code;
1807
1808 if (!mddi_client_id)
1809 mddi_disable(1);
1810 }
1811
1812#if 0
1813 switch (mddi_client_capability_pkt.Mfr_Name) {
1814 case 0x4474:
1815 if ((mddi_client_capability_pkt.Product_Code != 0x8960) &&
1816 (target == DISPLAY_1)) {
1817 ret = PRISM_WVGA;
1818 }
1819 break;
1820
1821 case 0xD263:
1822 if (target == DISPLAY_1)
1823 ret = TOSHIBA_VGA_PRIM;
1824 else if (target == DISPLAY_2)
1825 ret = TOSHIBA_QCIF_SECD;
1826 break;
1827
1828 case 0:
1829 if (mddi_client_capability_pkt.Product_Code == 0x8835) {
1830 if (target == DISPLAY_1)
1831 ret = SHARP_QVGA_PRIM;
1832 else if (target == DISPLAY_2)
1833 ret = SHARP_128x128_SECD;
1834 }
1835 break;
1836
1837 default:
1838 break;
1839 }
1840
1841 if ((!client_detection_try) && (ret != TOSHIBA_VGA_PRIM)
1842 && (ret != TOSHIBA_QCIF_SECD)) {
1843 /* Not a Toshiba display, so change drive_lo back to default value */
1844 mddi_host_reg_out(DRIVE_LO, 0x0032);
1845 }
1846#endif
1847
1848#endif
1849
1850 return mddi_client_id;
1851}
1852#endif
1853
1854void mddi_host_powerdown(mddi_host_type host_idx)
1855{
1856 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1857
1858 if (host_idx >= MDDI_NUM_HOST_CORES) {
1859 MDDI_MSG_ERR("Invalid host core index\n");
1860 return;
1861 }
1862
1863 if (pmhctl->driver_state == MDDI_DRIVER_RESET) {
1864 return;
1865 }
1866
1867 if (host_idx == MDDI_HOST_PRIM) {
1868 /* disable timer */
1869 del_timer(&mddi_host_timer);
1870 }
1871
1872 mddi_host_configure_interrupts(host_idx, FALSE);
1873
1874 /* turn on HCLK to MDDI host core if it has been disabled */
1875 mddi_host_enable_hclk();
1876
1877 /* MDDI Reset command */
1878 mddi_host_reg_out(CMD, MDDI_CMD_RESET);
1879
1880 /* Pad Control Register */
1881 mddi_host_reg_out(PAD_CTL, 0x0);
1882
1883 /* disable IO_CLK and hclk to MDDI host core */
1884 mddi_host_disable_io_clock();
1885 mddi_host_disable_hclk();
1886
1887 pmhctl->link_state = MDDI_LINK_DISABLED;
1888 pmhctl->driver_state = MDDI_DRIVER_RESET;
1889
1890 MDDI_MSG_NOTICE("MDDI Host: Disabling Link\n");
1891
1892}
1893
1894uint16 mddi_get_next_free_llist_item(mddi_host_type host_idx, boolean wait)
1895{
1896 unsigned long flags;
1897 uint16 ret_idx;
1898 boolean forced_wait = FALSE;
1899 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1900
1901 ret_idx = pmhctl->llist_info.next_free_idx;
1902
1903 pmhctl->llist_info.next_free_idx++;
1904 if (pmhctl->llist_info.next_free_idx >= MDDI_NUM_DYNAMIC_LLIST_ITEMS)
1905 pmhctl->llist_info.next_free_idx = MDDI_FIRST_DYNAMIC_LLIST_IDX;
1906 spin_lock_irqsave(&mddi_host_spin_lock, flags);
1907 if (pmhctl->llist_notify[ret_idx].in_use) {
1908 if (!wait) {
1909 pmhctl->llist_info.next_free_idx = ret_idx;
1910 ret_idx = UNASSIGNED_INDEX;
1911 } else {
1912 forced_wait = TRUE;
1913 INIT_COMPLETION(pmhctl->mddi_llist_avail_comp);
1914 }
1915 }
1916 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
1917
1918 if (forced_wait) {
1919 wait_for_completion_killable(&
1920 (pmhctl->
1921 mddi_llist_avail_comp));
1922 MDDI_MSG_ERR("task waiting on mddi llist item\n");
1923 }
1924
1925 if (ret_idx != UNASSIGNED_INDEX) {
1926 pmhctl->llist_notify[ret_idx].waiting = FALSE;
1927 pmhctl->llist_notify[ret_idx].done_cb = NULL;
1928 pmhctl->llist_notify[ret_idx].in_use = TRUE;
1929 pmhctl->llist_notify[ret_idx].next_idx = UNASSIGNED_INDEX;
1930 }
1931
1932 return ret_idx;
1933}
1934
1935uint16 mddi_get_reg_read_llist_item(mddi_host_type host_idx, boolean wait)
1936{
1937#ifdef FEATURE_MDDI_DISABLE_REVERSE
1938 MDDI_MSG_CRIT("No reverse link available\n");
1939 (void)wait;
1940 return FALSE;
1941#else
1942 unsigned long flags;
1943 uint16 ret_idx;
1944 boolean error = FALSE;
1945 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1946
1947 spin_lock_irqsave(&mddi_host_spin_lock, flags);
1948 if (pmhctl->llist_info.reg_read_idx != UNASSIGNED_INDEX) {
1949 /* need to block here or is this an error condition? */
1950 error = TRUE;
1951 ret_idx = UNASSIGNED_INDEX;
1952 }
1953 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
1954
1955 if (!error) {
1956 ret_idx = pmhctl->llist_info.reg_read_idx =
1957 mddi_get_next_free_llist_item(host_idx, wait);
1958 /* clear the reg_read_waiting flag */
1959 pmhctl->llist_info.reg_read_waiting = FALSE;
1960 }
1961
1962 if (error)
1963 MDDI_MSG_ERR("***** Reg read still in progress! ****\n");
1964 return ret_idx;
1965#endif
1966
1967}
1968
1969void mddi_queue_forward_packets(uint16 first_llist_idx,
1970 uint16 last_llist_idx,
1971 boolean wait,
1972 mddi_llist_done_cb_type llist_done_cb,
1973 mddi_host_type host_idx)
1974{
1975 unsigned long flags;
1976 mddi_linked_list_type *llist;
1977 mddi_linked_list_type *llist_dma;
1978 mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
1979
1980 if ((first_llist_idx >= UNASSIGNED_INDEX) ||
1981 (last_llist_idx >= UNASSIGNED_INDEX)) {
1982 MDDI_MSG_ERR("MDDI queueing invalid linked list\n");
1983 return;
1984 }
1985
1986 if (pmhctl->link_state == MDDI_LINK_DISABLED)
1987 MDDI_MSG_CRIT("MDDI host powered down!\n");
1988
1989 llist = pmhctl->llist_ptr;
1990 llist_dma = pmhctl->llist_dma_ptr;
1991
1992 /* clean cache so MDDI host can read data */
1993 memory_barrier();
1994
1995 pmhctl->llist_notify[last_llist_idx].waiting = wait;
1996 if (wait)
1997 INIT_COMPLETION(pmhctl->llist_notify[last_llist_idx].done_comp);
1998 pmhctl->llist_notify[last_llist_idx].done_cb = llist_done_cb;
1999
2000 spin_lock_irqsave(&mddi_host_spin_lock, flags);
2001
2002 if ((pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
2003 (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) &&
2004 (pmhctl->rev_state == MDDI_REV_IDLE)) {
2005 /* no packets are currently transmitting */
2006#ifndef FEATURE_MDDI_DISABLE_REVERSE
2007 if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
2008 /* This is the special case where the packet is a register read. */
2009 pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED;
2010 mddi_reg_read_retry = 0;
2011 /* mddi_rev_reg_read_attempt = 1; */
2012 }
2013#endif
2014 /* assign transmitting index values */
2015 pmhctl->llist_info.transmitting_start_idx = first_llist_idx;
2016 pmhctl->llist_info.transmitting_end_idx = last_llist_idx;
2017
2018 /* turn on clock(s), if they have been disabled */
2019 mddi_host_enable_hclk();
2020 mddi_host_enable_io_clock();
2021 pmhctl->int_type.llist_ptr_write_1++;
2022 /* Write to primary pointer register */
2023 dma_coherent_pre_ops();
2024 mddi_host_reg_out(PRI_PTR, &llist_dma[first_llist_idx]);
2025
2026 /* enable interrupt when complete */
2027 mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE,
2028 MDDI_INT_PRI_LINK_LIST_DONE);
2029
2030 } else if (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) {
2031#ifndef FEATURE_MDDI_DISABLE_REVERSE
2032 if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
2033 /*
2034 * we have a register read to send but need to wait
2035 * for current reverse activity to end or there are
2036 * packets currently transmitting
2037 */
2038 /* mddi_rev_reg_read_attempt = 0; */
2039 pmhctl->llist_info.reg_read_waiting = TRUE;
2040 }
2041#endif
2042
2043 /* assign waiting index values */
2044 pmhctl->llist_info.waiting_start_idx = first_llist_idx;
2045 pmhctl->llist_info.waiting_end_idx = last_llist_idx;
2046 } else {
2047 uint16 prev_end_idx = pmhctl->llist_info.waiting_end_idx;
2048#ifndef FEATURE_MDDI_DISABLE_REVERSE
2049 if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
2050 /*
2051 * we have a register read to send but need to wait
2052 * for current reverse activity to end or there are
2053 * packets currently transmitting
2054 */
2055 /* mddi_rev_reg_read_attempt = 0; */
2056 pmhctl->llist_info.reg_read_waiting = TRUE;
2057 }
2058#endif
2059
2060 llist = pmhctl->llist_ptr;
2061
2062 /* clear end flag in previous last packet */
2063 llist[prev_end_idx].link_controller_flags = 0;
2064 pmhctl->llist_notify[prev_end_idx].next_idx = first_llist_idx;
2065
2066 /* set the next_packet_pointer of the previous last packet */
2067 llist[prev_end_idx].next_packet_pointer =
2068 (void *)(&llist_dma[first_llist_idx]);
2069
2070 /* clean cache so MDDI host can read data */
2071 memory_barrier();
2072
2073 /* assign new waiting last index value */
2074 pmhctl->llist_info.waiting_end_idx = last_llist_idx;
2075 }
2076
2077 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
2078
2079}
2080
2081void mddi_host_write_pix_attr_reg(uint32 value)
2082{
2083 (void)value;
2084}
2085
2086void mddi_queue_reverse_encapsulation(boolean wait)
2087{
2088#ifdef FEATURE_MDDI_DISABLE_REVERSE
2089 MDDI_MSG_CRIT("No reverse link available\n");
2090 (void)wait;
2091#else
2092 unsigned long flags;
2093 boolean error = FALSE;
2094 mddi_host_type host_idx = MDDI_HOST_PRIM;
2095 mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
2096
2097 spin_lock_irqsave(&mddi_host_spin_lock, flags);
2098
2099 /* turn on clock(s), if they have been disabled */
2100 mddi_host_enable_hclk();
2101 mddi_host_enable_io_clock();
2102
2103 if (wait) {
2104 if (!mddi_rev_user.waiting) {
2105 mddi_rev_user.waiting = TRUE;
2106 INIT_COMPLETION(mddi_rev_user.done_comp);
2107 } else
2108 error = TRUE;
2109 }
2110 mddi_rev_encap_user_request = TRUE;
2111
2112 if (pmhctl->rev_state == MDDI_REV_IDLE) {
2113 /* attempt to send the reverse encapsulation now */
2114 mddi_host_type orig_host_idx = mddi_curr_host;
2115 mddi_curr_host = host_idx;
2116 mddi_issue_reverse_encapsulation();
2117 mddi_curr_host = orig_host_idx;
2118 }
2119 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
2120
2121 if (error) {
2122 MDDI_MSG_ERR("Reverse Encap request already in progress\n");
2123 } else if (wait)
2124 wait_for_completion_killable(&(mddi_rev_user.done_comp));
2125#endif
2126}
2127
2128/* ISR to be executed */
2129boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type)
2130{
2131#ifdef FEATURE_MDDI_DISABLE_REVERSE
2132 MDDI_MSG_CRIT("No reverse link available\n");
2133 (void)handler;
2134 (void)pkt_type;
2135 return (FALSE);
2136#else
2137 unsigned long flags;
2138 uint16 hdlr;
2139 boolean handler_set = FALSE;
2140 boolean overwrite = FALSE;
2141 mddi_host_type host_idx = MDDI_HOST_PRIM;
2142 mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
2143
2144 /* Disable interrupts */
2145 spin_lock_irqsave(&mddi_host_spin_lock, flags);
2146
2147 for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) {
2148 if (mddi_rev_pkt_handler[hdlr].pkt_type == pkt_type) {
2149 mddi_rev_pkt_handler[hdlr].handler = handler;
2150 if (handler == NULL) {
2151 /* clearing handler from table */
2152 mddi_rev_pkt_handler[hdlr].pkt_type =
2153 INVALID_PKT_TYPE;
2154 handler_set = TRUE;
2155 if (pkt_type == 0x10) { /* video stream packet */
2156 /* ensure HCLK on to MDDI host core before register write */
2157 mddi_host_enable_hclk();
2158 /* No longer getting video, so reset rev encap size to default */
2159 pmhctl->rev_pkt_size =
2160 MDDI_DEFAULT_REV_PKT_SIZE;
2161 mddi_host_reg_out(REV_ENCAP_SZ,
2162 pmhctl->rev_pkt_size);
2163 }
2164 } else {
2165 /* already a handler for this packet */
2166 overwrite = TRUE;
2167 }
2168 break;
2169 }
2170 }
2171 if ((hdlr >= MAX_MDDI_REV_HANDLERS) && (handler != NULL)) {
2172 /* assigning new handler */
2173 for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) {
2174 if (mddi_rev_pkt_handler[hdlr].pkt_type ==
2175 INVALID_PKT_TYPE) {
2176 if ((pkt_type == 0x10) && /* video stream packet */
2177 (pmhctl->rev_pkt_size <
2178 MDDI_VIDEO_REV_PKT_SIZE)) {
2179 /* ensure HCLK on to MDDI host core before register write */
2180 mddi_host_enable_hclk();
2181 /* Increase Rev Encap Size */
2182 pmhctl->rev_pkt_size =
2183 MDDI_VIDEO_REV_PKT_SIZE;
2184 mddi_host_reg_out(REV_ENCAP_SZ,
2185 pmhctl->rev_pkt_size);
2186 }
2187 mddi_rev_pkt_handler[hdlr].handler = handler;
2188 mddi_rev_pkt_handler[hdlr].pkt_type = pkt_type;
2189 handler_set = TRUE;
2190 break;
2191 }
2192 }
2193 }
2194
2195 /* Restore interrupts */
2196 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
2197
2198 if (overwrite)
2199 MDDI_MSG_ERR("Overwriting previous rev packet handler\n");
2200
2201 return handler_set;
2202
2203#endif
2204} /* mddi_set_rev_handler */
2205
2206void mddi_host_disable_hibernation(boolean disable)
2207{
2208 mddi_host_type host_idx = MDDI_HOST_PRIM;
2209 mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
2210
2211 if (disable) {
2212 pmhctl->disable_hibernation = TRUE;
2213 /* hibernation will be turned off by isr next time it is entered */
2214 } else {
2215 if (pmhctl->disable_hibernation) {
2216 unsigned long flags;
2217 spin_lock_irqsave(&mddi_host_spin_lock, flags);
2218 if (!MDDI_HOST_IS_HCLK_ON)
2219 MDDI_HOST_ENABLE_HCLK;
2220 mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
2221 spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
2222 pmhctl->disable_hibernation = FALSE;
2223 }
2224 }
2225}
2226
2227void mddi_mhctl_remove(mddi_host_type host_idx)
2228{
2229 mddi_host_cntl_type *pmhctl;
2230
2231 pmhctl = &(mhctl[host_idx]);
2232
2233 dma_free_coherent(NULL, MDDI_LLIST_POOL_SIZE, (void *)pmhctl->llist_ptr,
2234 pmhctl->llist_dma_addr);
2235
2236 dma_free_coherent(NULL, MDDI_MAX_REV_DATA_SIZE,
2237 (void *)pmhctl->rev_data_buf,
2238 pmhctl->rev_data_dma_addr);
2239}
diff --git a/drivers/staging/msm/mddihosti.h b/drivers/staging/msm/mddihosti.h
new file mode 100644
index 000000000000..7b26a4253896
--- /dev/null
+++ b/drivers/staging/msm/mddihosti.h
@@ -0,0 +1,547 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef MDDIHOSTI_H
30#define MDDIHOSTI_H
31
32#include "msm_fb.h"
33#include "mddihost.h"
34#include <linux/clk.h>
35
36/* Register offsets in MDDI, applies to both msm_pmdh_base and
37 * (u32)msm_emdh_base. */
38#define MDDI_CMD 0x0000
39#define MDDI_VERSION 0x0004
40#define MDDI_PRI_PTR 0x0008
41#define MDDI_BPS 0x0010
42#define MDDI_SPM 0x0014
43#define MDDI_INT 0x0018
44#define MDDI_INTEN 0x001c
45#define MDDI_REV_PTR 0x0020
46#define MDDI_REV_SIZE 0x0024
47#define MDDI_STAT 0x0028
48#define MDDI_REV_RATE_DIV 0x002c
49#define MDDI_REV_CRC_ERR 0x0030
50#define MDDI_TA1_LEN 0x0034
51#define MDDI_TA2_LEN 0x0038
52#define MDDI_TEST 0x0040
53#define MDDI_REV_PKT_CNT 0x0044
54#define MDDI_DRIVE_HI 0x0048
55#define MDDI_DRIVE_LO 0x004c
56#define MDDI_DISP_WAKE 0x0050
57#define MDDI_REV_ENCAP_SZ 0x0054
58#define MDDI_RTD_VAL 0x0058
59#define MDDI_PAD_CTL 0x0068
60#define MDDI_DRIVER_START_CNT 0x006c
61#define MDDI_CORE_VER 0x008c
62#define MDDI_FIFO_ALLOC 0x0090
63#define MDDI_PAD_IO_CTL 0x00a0
64#define MDDI_PAD_CAL 0x00a4
65
66extern u32 mddi_msg_level;
67
68/* No longer need to write to clear these registers */
69#define xxxx_mddi_host_reg_outm(reg, mask, val) \
70do { \
71 if (host_idx == MDDI_HOST_PRIM) \
72 mddi_host_reg_outm_pmdh(reg, mask, val); \
73 else \
74 mddi_host_reg_outm_emdh(reg, mask, val); \
75} while (0)
76
77#define mddi_host_reg_outm(reg, mask, val) \
78do { \
79 unsigned long __addr; \
80 if (host_idx == MDDI_HOST_PRIM) \
81 __addr = (u32)msm_pmdh_base + MDDI_##reg; \
82 else \
83 __addr = (u32)msm_emdh_base + MDDI_##reg; \
84 writel((readl(__addr) & ~(mask)) | ((val) & (mask)), __addr); \
85} while (0)
86
87#define xxxx_mddi_host_reg_out(reg, val) \
88do { \
89 if (host_idx == MDDI_HOST_PRIM) \
90 mddi_host_reg_out_pmdh(reg, val); \
91 else \
92 mddi_host_reg_out_emdh(reg, val); \
93 } while (0)
94
95#define mddi_host_reg_out(reg, val) \
96do { \
97 if (host_idx == MDDI_HOST_PRIM) \
98 writel(val, (u32)msm_pmdh_base + MDDI_##reg); \
99 else \
100 writel(val, (u32)msm_emdh_base + MDDI_##reg); \
101} while (0)
102
103#define xxxx_mddi_host_reg_in(reg) \
104 ((host_idx) ? \
105 mddi_host_reg_in_emdh(reg) : mddi_host_reg_in_pmdh(reg));
106
107#define mddi_host_reg_in(reg) \
108((host_idx) ? \
109 readl((u32)msm_emdh_base + MDDI_##reg) : \
110 readl((u32)msm_pmdh_base + MDDI_##reg)) \
111
112#define xxxx_mddi_host_reg_inm(reg, mask) \
113 ((host_idx) ? \
114 mddi_host_reg_inm_emdh(reg, mask) : \
115 mddi_host_reg_inm_pmdh(reg, mask);)
116
117#define mddi_host_reg_inm(reg, mask) \
118((host_idx) ? \
119 readl((u32)msm_emdh_base + MDDI_##reg) & (mask) : \
120 readl((u32)msm_pmdh_base + MDDI_##reg) & (mask)) \
121
122/* Using non-cacheable pmem, so do nothing */
123#define mddi_invalidate_cache_lines(addr_start, num_bytes)
124/*
125 * Using non-cacheable pmem, so do nothing with cache
126 * but, ensure write goes out to memory
127 */
128#define mddi_flush_cache_lines(addr_start, num_bytes) \
129 (void) addr_start; \
130 (void) num_bytes; \
131 memory_barrier()
132
133/* Since this translates to Remote Procedure Calls to check on clock status
134* just use a local variable to keep track of io_clock */
135#define MDDI_HOST_IS_IO_CLOCK_ON mddi_host_io_clock_on
136#define MDDI_HOST_ENABLE_IO_CLOCK
137#define MDDI_HOST_DISABLE_IO_CLOCK
138#define MDDI_HOST_IS_HCLK_ON mddi_host_hclk_on
139#define MDDI_HOST_ENABLE_HCLK
140#define MDDI_HOST_DISABLE_HCLK
141#define FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE
142#define FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE
143
144#define TRAMP_MDDI_HOST_ISR TRAMP_MDDI_PRI_ISR
145#define TRAMP_MDDI_HOST_EXT_ISR TRAMP_MDDI_EXT_ISR
146#define MDP_LINE_COUNT_BMSK 0x3ff
147#define MDP_SYNC_STATUS 0x000c
148#define MDP_LINE_COUNT \
149(readl(msm_mdp_base + MDP_SYNC_STATUS) & MDP_LINE_COUNT_BMSK)
150
151/* MDP sends 256 pixel packets, so lower value hibernates more without
152* significantly increasing latency of waiting for next subframe */
153#define MDDI_HOST_BYTES_PER_SUBFRAME 0x3C00
154
155#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
156#define MDDI_HOST_TA2_LEN 0x001a
157#define MDDI_HOST_REV_RATE_DIV 0x0004
158#else
159#define MDDI_HOST_TA2_LEN 0x000c
160#define MDDI_HOST_REV_RATE_DIV 0x0002
161#endif
162
163#define MDDI_MSG_EMERG(msg, ...) \
164 if (mddi_msg_level > 0) \
165 printk(KERN_EMERG msg, ## __VA_ARGS__);
166#define MDDI_MSG_ALERT(msg, ...) \
167 if (mddi_msg_level > 1) \
168 printk(KERN_ALERT msg, ## __VA_ARGS__);
169#define MDDI_MSG_CRIT(msg, ...) \
170 if (mddi_msg_level > 2) \
171 printk(KERN_CRIT msg, ## __VA_ARGS__);
172#define MDDI_MSG_ERR(msg, ...) \
173 if (mddi_msg_level > 3) \
174 printk(KERN_ERR msg, ## __VA_ARGS__);
175#define MDDI_MSG_WARNING(msg, ...) \
176 if (mddi_msg_level > 4) \
177 printk(KERN_WARNING msg, ## __VA_ARGS__);
178#define MDDI_MSG_NOTICE(msg, ...) \
179 if (mddi_msg_level > 5) \
180 printk(KERN_NOTICE msg, ## __VA_ARGS__);
181#define MDDI_MSG_INFO(msg, ...) \
182 if (mddi_msg_level > 6) \
183 printk(KERN_INFO msg, ## __VA_ARGS__);
184#define MDDI_MSG_DEBUG(msg, ...) \
185 if (mddi_msg_level > 7) \
186 printk(KERN_DEBUG msg, ## __VA_ARGS__);
187
188#define GCC_PACKED __attribute__((packed))
189typedef struct GCC_PACKED {
190 uint16 packet_length;
191 /* total # of bytes in the packet not including
192 the packet_length field. */
193
194 uint16 packet_type;
195 /* A Packet Type of 70 identifies the packet as
196 a Client status Packet. */
197
198 uint16 bClient_ID;
199 /* This field is reserved for future use and shall
200 be set to zero. */
201
202} mddi_rev_packet_type;
203
204typedef struct GCC_PACKED {
205 uint16 packet_length;
206 /* total # of bytes in the packet not including
207 the packet_length field. */
208
209 uint16 packet_type;
210 /* A Packet Type of 70 identifies the packet as
211 a Client status Packet. */
212
213 uint16 bClient_ID;
214 /* This field is reserved for future use and shall
215 be set to zero. */
216
217 uint16 reverse_link_request;
218 /* 16 bit unsigned integer with number of bytes client
219 needs in the * reverse encapsulation message
220 to transmit data. */
221
222 uint8 crc_error_count;
223 uint8 capability_change;
224 uint16 graphics_busy_flags;
225
226 uint16 parameter_CRC;
227 /* 16-bit CRC of all the bytes in the packet
228 including Packet Length. */
229
230} mddi_client_status_type;
231
232typedef struct GCC_PACKED {
233 uint16 packet_length;
234 /* total # of bytes in the packet not including
235 the packet_length field. */
236
237 uint16 packet_type;
238 /* A Packet Type of 66 identifies the packet as
239 a Client Capability Packet. */
240
241 uint16 bClient_ID;
242 /* This field is reserved for future use and
243 shall be set to zero. */
244
245 uint16 Protocol_Version;
246 uint16 Minimum_Protocol_Version;
247 uint16 Data_Rate_Capability;
248 uint8 Interface_Type_Capability;
249 uint8 Number_of_Alt_Displays;
250 uint16 PostCal_Data_Rate;
251 uint16 Bitmap_Width;
252 uint16 Bitmap_Height;
253 uint16 Display_Window_Width;
254 uint16 Display_Window_Height;
255 uint32 Color_Map_Size;
256 uint16 Color_Map_RGB_Width;
257 uint16 RGB_Capability;
258 uint8 Monochrome_Capability;
259 uint8 Reserved_1;
260 uint16 Y_Cb_Cr_Capability;
261 uint16 Bayer_Capability;
262 uint16 Alpha_Cursor_Image_Planes;
263 uint32 Client_Feature_Capability_Indicators;
264 uint8 Maximum_Video_Frame_Rate_Capability;
265 uint8 Minimum_Video_Frame_Rate_Capability;
266 uint16 Minimum_Sub_frame_Rate;
267 uint16 Audio_Buffer_Depth;
268 uint16 Audio_Channel_Capability;
269 uint16 Audio_Sample_Rate_Capability;
270 uint8 Audio_Sample_Resolution;
271 uint8 Mic_Audio_Sample_Resolution;
272 uint16 Mic_Sample_Rate_Capability;
273 uint8 Keyboard_Data_Format;
274 uint8 pointing_device_data_format;
275 uint16 content_protection_type;
276 uint16 Mfr_Name;
277 uint16 Product_Code;
278 uint16 Reserved_3;
279 uint32 Serial_Number;
280 uint8 Week_of_Manufacture;
281 uint8 Year_of_Manufacture;
282
283 uint16 parameter_CRC;
284 /* 16-bit CRC of all the bytes in the packet including Packet Length. */
285
286} mddi_client_capability_type;
287
288typedef struct GCC_PACKED {
289 uint16 packet_length;
290 /* total # of bytes in the packet not including the packet_length field. */
291
292 uint16 packet_type;
293 /* A Packet Type of 16 identifies the packet as a Video Stream Packet. */
294
295 uint16 bClient_ID;
296 /* This field is reserved for future use and shall be set to zero. */
297
298 uint16 video_data_format_descriptor;
299 /* format of each pixel in the Pixel Data in the present stream in the
300 * present packet.
301 * If bits [15:13] = 000 monochrome
302 * If bits [15:13] = 001 color pixels (palette).
303 * If bits [15:13] = 010 color pixels in raw RGB
304 * If bits [15:13] = 011 data in 4:2:2 Y Cb Cr format
305 * If bits [15:13] = 100 Bayer pixels
306 */
307
308 uint16 pixel_data_attributes;
309 /* interpreted as follows:
310 * Bits [1:0] = 11 pixel data is displayed to both eyes
311 * Bits [1:0] = 10 pixel data is routed to the left eye only.
312 * Bits [1:0] = 01 pixel data is routed to the right eye only.
313 * Bits [1:0] = 00 pixel data is routed to the alternate display.
314 * Bit 2 is 0 Pixel Data is in the standard progressive format.
315 * Bit 2 is 1 Pixel Data is in interlace format.
316 * Bit 3 is 0 Pixel Data is in the standard progressive format.
317 * Bit 3 is 1 Pixel Data is in alternate pixel format.
318 * Bit 4 is 0 Pixel Data is to or from the display frame buffer.
319 * Bit 4 is 1 Pixel Data is to or from the camera.
320 * Bit 5 is 0 pixel data contains the next consecutive row of pixels.
321 * Bit 5 is 1 X Left Edge, Y Top Edge, X Right Edge, Y Bottom Edge,
322 * X Start, and Y Start parameters are not defined and
323 * shall be ignored by the client.
324 * Bits [7:6] = 01 Pixel data is written to the offline image buffer.
325 * Bits [7:6] = 00 Pixel data is written to the buffer to refresh display.
326 * Bits [7:6] = 11 Pixel data is written to all image buffers.
327 * Bits [7:6] = 10 Invalid. Reserved for future use.
328 * Bits 8 through 11 alternate display number.
329 * Bits 12 through 14 are reserved for future use and shall be set to zero.
330 * Bit 15 is 1 the row of pixels is the last row of pixels in a frame.
331 */
332
333 uint16 x_left_edge;
334 uint16 y_top_edge;
335 /* X,Y coordinate of the top left edge of the screen window */
336
337 uint16 x_right_edge;
338 uint16 y_bottom_edge;
339 /* X,Y coordinate of the bottom right edge of the window being updated. */
340
341 uint16 x_start;
342 uint16 y_start;
343 /* (X Start, Y Start) is the first pixel in the Pixel Data field below. */
344
345 uint16 pixel_count;
346 /* number of pixels in the Pixel Data field below. */
347
348 uint16 parameter_CRC;
349 /* 16-bit CRC of all bytes from the Packet Length to the Pixel Count. */
350
351 uint16 reserved;
352 /* 16-bit variable to make structure align on 4 byte boundary */
353
354} mddi_video_stream_packet_type;
355
356typedef struct GCC_PACKED {
357 uint16 packet_length;
358 /* total # of bytes in the packet not including the packet_length field. */
359
360 uint16 packet_type;
361 /* A Packet Type of 146 identifies the packet as a Register Access Packet. */
362
363 uint16 bClient_ID;
364 /* This field is reserved for future use and shall be set to zero. */
365
366 uint16 read_write_info;
367 /* Bits 13:0 a 14-bit unsigned integer that specifies the number of
368 * 32-bit Register Data List items to be transferred in the
369 * Register Data List field.
370 * Bits[15:14] = 00 Write to register(s);
371 * Bits[15:14] = 10 Read from register(s);
372 * Bits[15:14] = 11 Response to a Read.
373 * Bits[15:14] = 01 this value is reserved for future use. */
374
375 uint32 register_address;
376 /* the register address that is to be written to or read from. */
377
378 uint16 parameter_CRC;
379 /* 16-bit CRC of all bytes from the Packet Length to the Register Address. */
380
381 uint32 register_data_list;
382 /* list of 4-byte register data values for/from client registers */
383
384} mddi_register_access_packet_type;
385
386typedef union GCC_PACKED {
387 mddi_video_stream_packet_type video_pkt;
388 mddi_register_access_packet_type register_pkt;
389 /* add 48 byte pad to ensure 64 byte llist struct, that can be
390 * manipulated easily with cache */
391 uint32 alignment_pad[12]; /* 48 bytes */
392} mddi_packet_header_type;
393
394typedef struct GCC_PACKED mddi_host_llist_struct {
395 uint16 link_controller_flags;
396 uint16 packet_header_count;
397 uint16 packet_data_count;
398 void *packet_data_pointer;
399 struct mddi_host_llist_struct *next_packet_pointer;
400 uint16 reserved;
401 mddi_packet_header_type packet_header;
402} mddi_linked_list_type;
403
404typedef struct {
405 struct completion done_comp;
406 mddi_llist_done_cb_type done_cb;
407 uint16 next_idx;
408 boolean waiting;
409 boolean in_use;
410} mddi_linked_list_notify_type;
411
412#define MDDI_LLIST_POOL_SIZE 0x1000
413#define MDDI_MAX_NUM_LLIST_ITEMS (MDDI_LLIST_POOL_SIZE / \
414 sizeof(mddi_linked_list_type))
415#define UNASSIGNED_INDEX MDDI_MAX_NUM_LLIST_ITEMS
416#define MDDI_FIRST_DYNAMIC_LLIST_IDX 0
417
418/* Static llist items can be used for applications that frequently send
419 * the same set of packets using the linked list interface. */
420/* Here we configure for 6 static linked list items:
421 * The 1st is used for a the adaptive backlight setting.
422 * and the remaining 5 are used for sending window adjustments for
423 * MDDI clients that need windowing info sent separate from video
424 * packets. */
425#define MDDI_NUM_STATIC_ABL_ITEMS 1
426#define MDDI_NUM_STATIC_WINDOW_ITEMS 5
427#define MDDI_NUM_STATIC_LLIST_ITEMS (MDDI_NUM_STATIC_ABL_ITEMS + \
428 MDDI_NUM_STATIC_WINDOW_ITEMS)
429#define MDDI_NUM_DYNAMIC_LLIST_ITEMS (MDDI_MAX_NUM_LLIST_ITEMS - \
430 MDDI_NUM_STATIC_LLIST_ITEMS)
431
432#define MDDI_FIRST_STATIC_LLIST_IDX MDDI_NUM_DYNAMIC_LLIST_ITEMS
433#define MDDI_FIRST_STATIC_ABL_IDX MDDI_FIRST_STATIC_LLIST_IDX
434#define MDDI_FIRST_STATIC_WINDOW_IDX (MDDI_FIRST_STATIC_LLIST_IDX + \
435 MDDI_NUM_STATIC_ABL_ITEMS)
436
437/* GPIO registers */
438#define VSYNC_WAKEUP_REG 0x80
439#define GPIO_REG 0x81
440#define GPIO_OUTPUT_REG 0x82
441#define GPIO_INTERRUPT_REG 0x83
442#define GPIO_INTERRUPT_ENABLE_REG 0x84
443#define GPIO_POLARITY_REG 0x85
444
445/* Interrupt Bits */
446#define MDDI_INT_PRI_PTR_READ 0x0001
447#define MDDI_INT_SEC_PTR_READ 0x0002
448#define MDDI_INT_REV_DATA_AVAIL 0x0004
449#define MDDI_INT_DISP_REQ 0x0008
450#define MDDI_INT_PRI_UNDERFLOW 0x0010
451#define MDDI_INT_SEC_UNDERFLOW 0x0020
452#define MDDI_INT_REV_OVERFLOW 0x0040
453#define MDDI_INT_CRC_ERROR 0x0080
454#define MDDI_INT_MDDI_IN 0x0100
455#define MDDI_INT_PRI_OVERWRITE 0x0200
456#define MDDI_INT_SEC_OVERWRITE 0x0400
457#define MDDI_INT_REV_OVERWRITE 0x0800
458#define MDDI_INT_DMA_FAILURE 0x1000
459#define MDDI_INT_LINK_ACTIVE 0x2000
460#define MDDI_INT_IN_HIBERNATION 0x4000
461#define MDDI_INT_PRI_LINK_LIST_DONE 0x8000
462#define MDDI_INT_SEC_LINK_LIST_DONE 0x10000
463#define MDDI_INT_NO_CMD_PKTS_PEND 0x20000
464#define MDDI_INT_RTD_FAILURE 0x40000
465
466#define MDDI_INT_ERROR_CONDITIONS ( \
467 MDDI_INT_PRI_UNDERFLOW | MDDI_INT_SEC_UNDERFLOW | \
468 MDDI_INT_REV_OVERFLOW | MDDI_INT_CRC_ERROR | \
469 MDDI_INT_PRI_OVERWRITE | MDDI_INT_SEC_OVERWRITE | \
470 MDDI_INT_RTD_FAILURE | \
471 MDDI_INT_REV_OVERWRITE | MDDI_INT_DMA_FAILURE)
472
473#define MDDI_INT_LINK_STATE_CHANGES ( \
474 MDDI_INT_LINK_ACTIVE | MDDI_INT_IN_HIBERNATION)
475
476/* Status Bits */
477#define MDDI_STAT_LINK_ACTIVE 0x0001
478#define MDDI_STAT_NEW_REV_PTR 0x0002
479#define MDDI_STAT_NEW_PRI_PTR 0x0004
480#define MDDI_STAT_NEW_SEC_PTR 0x0008
481#define MDDI_STAT_IN_HIBERNATION 0x0010
482#define MDDI_STAT_PRI_LINK_LIST_DONE 0x0020
483#define MDDI_STAT_SEC_LINK_LIST_DONE 0x0040
484#define MDDI_STAT_PENDING_TIMING_PKT 0x0080
485#define MDDI_STAT_PENDING_REV_ENCAP 0x0100
486#define MDDI_STAT_PENDING_POWERDOWN 0x0200
487#define MDDI_STAT_RTD_MEAS_FAIL 0x0800
488#define MDDI_STAT_CLIENT_WAKEUP_REQ 0x1000
489
490/* Command Bits */
491#define MDDI_CMD_POWERDOWN 0x0100
492#define MDDI_CMD_POWERUP 0x0200
493#define MDDI_CMD_HIBERNATE 0x0300
494#define MDDI_CMD_RESET 0x0400
495#define MDDI_CMD_DISP_IGNORE 0x0501
496#define MDDI_CMD_DISP_LISTEN 0x0500
497#define MDDI_CMD_SEND_REV_ENCAP 0x0600
498#define MDDI_CMD_GET_CLIENT_CAP 0x0601
499#define MDDI_CMD_GET_CLIENT_STATUS 0x0602
500#define MDDI_CMD_SEND_RTD 0x0700
501#define MDDI_CMD_LINK_ACTIVE 0x0900
502#define MDDI_CMD_PERIODIC_REV_ENCAP 0x0A00
503
504extern void mddi_host_init(mddi_host_type host);
505extern void mddi_host_powerdown(mddi_host_type host);
506extern uint16 mddi_get_next_free_llist_item(mddi_host_type host, boolean wait);
507extern uint16 mddi_get_reg_read_llist_item(mddi_host_type host, boolean wait);
508extern void mddi_queue_forward_packets(uint16 first_llist_idx,
509 uint16 last_llist_idx,
510 boolean wait,
511 mddi_llist_done_cb_type llist_done_cb,
512 mddi_host_type host);
513
514extern void mddi_host_write_pix_attr_reg(uint32 value);
515extern void mddi_client_lcd_gpio_poll(uint32 poll_reg_val);
516extern void mddi_client_lcd_vsync_detected(boolean detected);
517extern void mddi_host_disable_hibernation(boolean disable);
518
519extern mddi_linked_list_type *llist_extern[];
520extern mddi_linked_list_type *llist_dma_extern[];
521extern mddi_linked_list_notify_type *llist_extern_notify[];
522extern struct timer_list mddi_host_timer;
523
524typedef struct {
525 uint16 transmitting_start_idx;
526 uint16 transmitting_end_idx;
527 uint16 waiting_start_idx;
528 uint16 waiting_end_idx;
529 uint16 reg_read_idx;
530 uint16 next_free_idx;
531 boolean reg_read_waiting;
532} mddi_llist_info_type;
533
534extern mddi_llist_info_type mddi_llist;
535
536#define MDDI_GPIO_DEFAULT_POLLING_INTERVAL 200
537typedef struct {
538 uint32 polling_reg;
539 uint32 polling_val;
540 uint32 polling_interval;
541 boolean polling_enabled;
542} mddi_gpio_info_type;
543
544uint32 mddi_get_client_id(void);
545void mddi_mhctl_remove(mddi_host_type host_idx);
546void mddi_host_timer_service(unsigned long data);
547#endif /* MDDIHOSTI_H */
diff --git a/drivers/staging/msm/mdp.c b/drivers/staging/msm/mdp.c
new file mode 100644
index 000000000000..36053afdebe2
--- /dev/null
+++ b/drivers/staging/msm/mdp.c
@@ -0,0 +1,1113 @@
1/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/hrtimer.h>
26#include <linux/clk.h>
27#include <mach/hardware.h>
28#include <linux/io.h>
29#include <linux/debugfs.h>
30#include <linux/delay.h>
31#include <linux/mutex.h>
32
33#include <asm/system.h>
34#include <asm/mach-types.h>
35#include <linux/semaphore.h>
36#include <linux/uaccess.h>
37
38#include "mdp.h"
39#include "msm_fb.h"
40#ifdef CONFIG_FB_MSM_MDP40
41#include "mdp4.h"
42#endif
43
44static struct clk *mdp_clk;
45static struct clk *mdp_pclk;
46
47struct completion mdp_ppp_comp;
48struct semaphore mdp_ppp_mutex;
49struct semaphore mdp_pipe_ctrl_mutex;
50
51unsigned long mdp_timer_duration = (HZ); /* 1 sec */
52/* unsigned long mdp_mdp_timer_duration=0; */
53
54boolean mdp_ppp_waiting = FALSE;
55uint32 mdp_tv_underflow_cnt;
56uint32 mdp_lcdc_underflow_cnt;
57
58boolean mdp_current_clk_on = FALSE;
59boolean mdp_is_in_isr = FALSE;
60
61/*
62 * legacy mdp_in_processing is only for DMA2-MDDI
63 * this applies to DMA2 block only
64 */
65uint32 mdp_in_processing = FALSE;
66
67#ifdef CONFIG_FB_MSM_MDP40
68uint32 mdp_intr_mask = MDP4_ANY_INTR_MASK;
69#else
70uint32 mdp_intr_mask = MDP_ANY_INTR_MASK;
71#endif
72
73MDP_BLOCK_TYPE mdp_debug[MDP_MAX_BLOCK];
74
75int32 mdp_block_power_cnt[MDP_MAX_BLOCK];
76
77spinlock_t mdp_spin_lock;
78struct workqueue_struct *mdp_dma_wq; /*mdp dma wq */
79struct workqueue_struct *mdp_vsync_wq; /*mdp vsync wq */
80
81static struct workqueue_struct *mdp_pipe_ctrl_wq; /* mdp mdp pipe ctrl wq */
82static struct delayed_work mdp_pipe_ctrl_worker;
83
84#ifdef CONFIG_FB_MSM_MDP40
85struct mdp_dma_data dma2_data;
86struct mdp_dma_data dma_s_data;
87struct mdp_dma_data dma_e_data;
88#else
89static struct mdp_dma_data dma2_data;
90static struct mdp_dma_data dma_s_data;
91static struct mdp_dma_data dma_e_data;
92#endif
93static struct mdp_dma_data dma3_data;
94
95extern ktime_t mdp_dma2_last_update_time;
96
97extern uint32 mdp_dma2_update_time_in_usec;
98extern int mdp_lcd_rd_cnt_offset_slow;
99extern int mdp_lcd_rd_cnt_offset_fast;
100extern int mdp_usec_diff_threshold;
101
102#ifdef CONFIG_FB_MSM_LCDC
103extern int mdp_lcdc_pclk_clk_rate;
104extern int mdp_lcdc_pad_pclk_clk_rate;
105extern int first_pixel_start_x;
106extern int first_pixel_start_y;
107#endif
108
109#ifdef MSM_FB_ENABLE_DBGFS
110struct dentry *mdp_dir;
111#endif
112
113#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
114static int mdp_suspend(struct platform_device *pdev, pm_message_t state);
115#else
116#define mdp_suspend NULL
117#endif
118
119struct timeval mdp_dma2_timeval;
120struct timeval mdp_ppp_timeval;
121
122#ifdef CONFIG_HAS_EARLYSUSPEND
123static struct early_suspend early_suspend;
124#endif
125
126#ifndef CONFIG_FB_MSM_MDP22
127DEFINE_MUTEX(mdp_lut_push_sem);
128static int mdp_lut_i;
129static int mdp_lut_hw_update(struct fb_cmap *cmap)
130{
131 int i;
132 u16 *c[3];
133 u16 r, g, b;
134
135 c[0] = cmap->green;
136 c[1] = cmap->blue;
137 c[2] = cmap->red;
138
139 for (i = 0; i < cmap->len; i++) {
140 if (copy_from_user(&r, cmap->red++, sizeof(r)) ||
141 copy_from_user(&g, cmap->green++, sizeof(g)) ||
142 copy_from_user(&b, cmap->blue++, sizeof(b)))
143 return -EFAULT;
144
145#ifdef CONFIG_FB_MSM_MDP40
146 MDP_OUTP(MDP_BASE + 0x94800 +
147#else
148 MDP_OUTP(MDP_BASE + 0x93800 +
149#endif
150 (0x400*mdp_lut_i) + cmap->start*4 + i*4,
151 ((g & 0xff) |
152 ((b & 0xff) << 8) |
153 ((r & 0xff) << 16)));
154 }
155
156 return 0;
157}
158
159static int mdp_lut_push;
160static int mdp_lut_push_i;
161static int mdp_lut_update_nonlcdc(struct fb_info *info, struct fb_cmap *cmap)
162{
163 int ret;
164
165 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
166 ret = mdp_lut_hw_update(cmap);
167 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
168
169 if (ret)
170 return ret;
171
172 mutex_lock(&mdp_lut_push_sem);
173 mdp_lut_push = 1;
174 mdp_lut_push_i = mdp_lut_i;
175 mutex_unlock(&mdp_lut_push_sem);
176
177 mdp_lut_i = (mdp_lut_i + 1)%2;
178
179 return 0;
180}
181
182static int mdp_lut_update_lcdc(struct fb_info *info, struct fb_cmap *cmap)
183{
184 int ret;
185
186 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
187 ret = mdp_lut_hw_update(cmap);
188
189 if (ret) {
190 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
191 return ret;
192 }
193
194 MDP_OUTP(MDP_BASE + 0x90070, (mdp_lut_i << 10) | 0x17);
195 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
196 mdp_lut_i = (mdp_lut_i + 1)%2;
197
198 return 0;
199}
200
201#define MDP_HIST_MAX_BIN 32
202static __u32 mdp_hist_r[MDP_HIST_MAX_BIN];
203static __u32 mdp_hist_g[MDP_HIST_MAX_BIN];
204static __u32 mdp_hist_b[MDP_HIST_MAX_BIN];
205
206#ifdef CONFIG_FB_MSM_MDP40
207struct mdp_histogram mdp_hist;
208struct completion mdp_hist_comp;
209#else
210static struct mdp_histogram mdp_hist;
211static struct completion mdp_hist_comp;
212#endif
213
214static int mdp_do_histogram(struct fb_info *info, struct mdp_histogram *hist)
215{
216 int ret = 0;
217
218 if (!hist->frame_cnt || (hist->bin_cnt == 0) ||
219 (hist->bin_cnt > MDP_HIST_MAX_BIN))
220 return -EINVAL;
221
222 INIT_COMPLETION(mdp_hist_comp);
223
224 mdp_hist.bin_cnt = hist->bin_cnt;
225 mdp_hist.r = (hist->r) ? mdp_hist_r : 0;
226 mdp_hist.g = (hist->g) ? mdp_hist_g : 0;
227 mdp_hist.b = (hist->b) ? mdp_hist_b : 0;
228
229#ifdef CONFIG_FB_MSM_MDP40
230 MDP_OUTP(MDP_BASE + 0x95004, hist->frame_cnt);
231 MDP_OUTP(MDP_BASE + 0x95000, 1);
232#else
233 MDP_OUTP(MDP_BASE + 0x94004, hist->frame_cnt);
234 MDP_OUTP(MDP_BASE + 0x94000, 1);
235#endif
236 wait_for_completion_killable(&mdp_hist_comp);
237
238 if (hist->r) {
239 ret = copy_to_user(hist->r, mdp_hist.r, hist->bin_cnt*4);
240 if (ret)
241 goto hist_err;
242 }
243 if (hist->g) {
244 ret = copy_to_user(hist->g, mdp_hist.g, hist->bin_cnt*4);
245 if (ret)
246 goto hist_err;
247 }
248 if (hist->b) {
249 ret = copy_to_user(hist->b, mdp_hist.b, hist->bin_cnt*4);
250 if (ret)
251 goto hist_err;
252 }
253 return 0;
254
255hist_err:
256 printk(KERN_ERR "%s: invalid hist buffer\n", __func__);
257 return ret;
258}
259#endif
260
261/* Returns < 0 on error, 0 on timeout, or > 0 on successful wait */
262
263int mdp_ppp_pipe_wait(void)
264{
265 int ret = 1;
266
267 /* wait 5 seconds for the operation to complete before declaring
268 the MDP hung */
269
270 if (mdp_ppp_waiting == TRUE) {
271 ret = wait_for_completion_interruptible_timeout(&mdp_ppp_comp,
272 5 * HZ);
273
274 if (!ret)
275 printk(KERN_ERR "%s: Timed out waiting for the MDP.\n",
276 __func__);
277 }
278
279 return ret;
280}
281
282static DEFINE_SPINLOCK(mdp_lock);
283static int mdp_irq_mask;
284static int mdp_irq_enabled;
285
286void mdp_enable_irq(uint32 term)
287{
288 unsigned long irq_flags;
289
290 spin_lock_irqsave(&mdp_lock, irq_flags);
291 if (mdp_irq_mask & term) {
292 printk(KERN_ERR "MDP IRQ term-0x%x is already set\n", term);
293 } else {
294 mdp_irq_mask |= term;
295 if (mdp_irq_mask && !mdp_irq_enabled) {
296 mdp_irq_enabled = 1;
297 enable_irq(INT_MDP);
298 }
299 }
300 spin_unlock_irqrestore(&mdp_lock, irq_flags);
301}
302
303void mdp_disable_irq(uint32 term)
304{
305 unsigned long irq_flags;
306
307 spin_lock_irqsave(&mdp_lock, irq_flags);
308 if (!(mdp_irq_mask & term)) {
309 printk(KERN_ERR "MDP IRQ term-0x%x is not set\n", term);
310 } else {
311 mdp_irq_mask &= ~term;
312 if (!mdp_irq_mask && mdp_irq_enabled) {
313 mdp_irq_enabled = 0;
314 disable_irq(INT_MDP);
315 }
316 }
317 spin_unlock_irqrestore(&mdp_lock, irq_flags);
318}
319
320void mdp_disable_irq_nolock(uint32 term)
321{
322
323 if (!(mdp_irq_mask & term)) {
324 printk(KERN_ERR "MDP IRQ term-0x%x is not set\n", term);
325 } else {
326 mdp_irq_mask &= ~term;
327 if (!mdp_irq_mask && mdp_irq_enabled) {
328 mdp_irq_enabled = 0;
329 disable_irq(INT_MDP);
330 }
331 }
332}
333
334void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd)
335{
336
337 dmb(); /* memory barrier */
338
339 /* kick off PPP engine */
340 if (term == MDP_PPP_TERM) {
341 if (mdp_debug[MDP_PPP_BLOCK])
342 jiffies_to_timeval(jiffies, &mdp_ppp_timeval);
343
344 /* let's turn on PPP block */
345 mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
346
347 mdp_enable_irq(term);
348 INIT_COMPLETION(mdp_ppp_comp);
349 mdp_ppp_waiting = TRUE;
350 outpdw(MDP_BASE + 0x30, 0x1000);
351 wait_for_completion_killable(&mdp_ppp_comp);
352 mdp_disable_irq(term);
353
354 if (mdp_debug[MDP_PPP_BLOCK]) {
355 struct timeval now;
356
357 jiffies_to_timeval(jiffies, &now);
358 mdp_ppp_timeval.tv_usec =
359 now.tv_usec - mdp_ppp_timeval.tv_usec;
360 MSM_FB_INFO("MDP-PPP: %d\n",
361 (int)mdp_ppp_timeval.tv_usec);
362 }
363 } else if (term == MDP_DMA2_TERM) {
364 if (mdp_debug[MDP_DMA2_BLOCK]) {
365 MSM_FB_INFO("MDP-DMA2: %d\n",
366 (int)mdp_dma2_timeval.tv_usec);
367 jiffies_to_timeval(jiffies, &mdp_dma2_timeval);
368 }
369 /* DMA update timestamp */
370 mdp_dma2_last_update_time = ktime_get_real();
371 /* let's turn on DMA2 block */
372#if 0
373 mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
374#endif
375#ifdef CONFIG_FB_MSM_MDP22
376 outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x0044, 0x0);/* start DMA */
377#else
378 if (mdp_lut_push) {
379 mutex_lock(&mdp_lut_push_sem);
380 mdp_lut_push = 0;
381 MDP_OUTP(MDP_BASE + 0x90070,
382 (mdp_lut_push_i << 10) | 0x17);
383 mutex_unlock(&mdp_lut_push_sem);
384 }
385#ifdef CONFIG_FB_MSM_MDP40
386 outpdw(MDP_BASE + 0x000c, 0x0); /* start DMA */
387#else
388 outpdw(MDP_BASE + 0x0044, 0x0); /* start DMA */
389#endif
390#endif
391#ifdef CONFIG_FB_MSM_MDP40
392 } else if (term == MDP_DMA_S_TERM) {
393 mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
394 outpdw(MDP_BASE + 0x0010, 0x0); /* start DMA */
395 } else if (term == MDP_DMA_E_TERM) {
396 mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
397 outpdw(MDP_BASE + 0x0014, 0x0); /* start DMA */
398 } else if (term == MDP_OVERLAY0_TERM) {
399 mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
400 outpdw(MDP_BASE + 0x0004, 0);
401 } else if (term == MDP_OVERLAY1_TERM) {
402 mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
403 outpdw(MDP_BASE + 0x0008, 0);
404 }
405#else
406 } else if (term == MDP_DMA_S_TERM) {
407 mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
408 outpdw(MDP_BASE + 0x0048, 0x0); /* start DMA */
409 }
410#endif
411}
412
413static void mdp_pipe_ctrl_workqueue_handler(struct work_struct *work)
414{
415 mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
416}
417
418void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
419 boolean isr)
420{
421 boolean mdp_all_blocks_off = TRUE;
422 int i;
423 unsigned long flag;
424
425 spin_lock_irqsave(&mdp_spin_lock, flag);
426 if (MDP_BLOCK_POWER_ON == state) {
427 mdp_block_power_cnt[block]++;
428
429 if (MDP_DMA2_BLOCK == block)
430 mdp_in_processing = TRUE;
431 } else {
432 mdp_block_power_cnt[block]--;
433
434 if (mdp_block_power_cnt[block] < 0) {
435 /*
436 * Master has to serve a request to power off MDP always
437 * It also has a timer to power off. So, in case of
438 * timer expires first and DMA2 finishes later,
439 * master has to power off two times
440 * There shouldn't be multiple power-off request for
441 * other blocks
442 */
443 if (block != MDP_MASTER_BLOCK) {
444 MSM_FB_INFO("mdp_block_power_cnt[block=%d] \
445 multiple power-off request\n", block);
446 }
447 mdp_block_power_cnt[block] = 0;
448 }
449
450 if (MDP_DMA2_BLOCK == block)
451 mdp_in_processing = FALSE;
452 }
453 spin_unlock_irqrestore(&mdp_spin_lock, flag);
454
455 /*
456 * If it's in isr, we send our request to workqueue.
457 * Otherwise, processing happens in the current context
458 */
459 if (isr) {
460 /* checking all blocks power state */
461 for (i = 0; i < MDP_MAX_BLOCK; i++) {
462 if (mdp_block_power_cnt[i] > 0)
463 mdp_all_blocks_off = FALSE;
464 }
465
466 if ((mdp_all_blocks_off) && (mdp_current_clk_on)) {
467 /* send workqueue to turn off mdp power */
468 queue_delayed_work(mdp_pipe_ctrl_wq,
469 &mdp_pipe_ctrl_worker,
470 mdp_timer_duration);
471 }
472 } else {
473 down(&mdp_pipe_ctrl_mutex);
474 /* checking all blocks power state */
475 for (i = 0; i < MDP_MAX_BLOCK; i++) {
476 if (mdp_block_power_cnt[i] > 0)
477 mdp_all_blocks_off = FALSE;
478 }
479
480 /*
481 * find out whether a delayable work item is currently
482 * pending
483 */
484
485 if (delayed_work_pending(&mdp_pipe_ctrl_worker)) {
486 /*
487 * try to cancel the current work if it fails to
488 * stop (which means del_timer can't delete it
489 * from the list, it's about to expire and run),
490 * we have to let it run. queue_delayed_work won't
491 * accept the next job which is same as
492 * queue_delayed_work(mdp_timer_duration = 0)
493 */
494 cancel_delayed_work(&mdp_pipe_ctrl_worker);
495 }
496
497 if ((mdp_all_blocks_off) && (mdp_current_clk_on)) {
498 if (block == MDP_MASTER_BLOCK) {
499 mdp_current_clk_on = FALSE;
500 /* turn off MDP clks */
501 if (mdp_clk != NULL) {
502 clk_disable(mdp_clk);
503 MSM_FB_DEBUG("MDP CLK OFF\n");
504 }
505 if (mdp_pclk != NULL) {
506 clk_disable(mdp_pclk);
507 MSM_FB_DEBUG("MDP PCLK OFF\n");
508 }
509 } else {
510 /* send workqueue to turn off mdp power */
511 queue_delayed_work(mdp_pipe_ctrl_wq,
512 &mdp_pipe_ctrl_worker,
513 mdp_timer_duration);
514 }
515 } else if ((!mdp_all_blocks_off) && (!mdp_current_clk_on)) {
516 mdp_current_clk_on = TRUE;
517 /* turn on MDP clks */
518 if (mdp_clk != NULL) {
519 clk_enable(mdp_clk);
520 MSM_FB_DEBUG("MDP CLK ON\n");
521 }
522 if (mdp_pclk != NULL) {
523 clk_enable(mdp_pclk);
524 MSM_FB_DEBUG("MDP PCLK ON\n");
525 }
526 }
527 up(&mdp_pipe_ctrl_mutex);
528 }
529}
530
531#ifndef CONFIG_FB_MSM_MDP40
532irqreturn_t mdp_isr(int irq, void *ptr)
533{
534 uint32 mdp_interrupt = 0;
535 struct mdp_dma_data *dma;
536
537 mdp_is_in_isr = TRUE;
538 do {
539 mdp_interrupt = inp32(MDP_INTR_STATUS);
540 outp32(MDP_INTR_CLEAR, mdp_interrupt);
541
542 mdp_interrupt &= mdp_intr_mask;
543
544 if (mdp_interrupt & TV_ENC_UNDERRUN) {
545 mdp_interrupt &= ~(TV_ENC_UNDERRUN);
546 mdp_tv_underflow_cnt++;
547 }
548
549 if (!mdp_interrupt)
550 break;
551
552 /* DMA3 TV-Out Start */
553 if (mdp_interrupt & TV_OUT_DMA3_START) {
554 /* let's disable TV out interrupt */
555 mdp_intr_mask &= ~TV_OUT_DMA3_START;
556 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
557
558 dma = &dma3_data;
559 if (dma->waiting) {
560 dma->waiting = FALSE;
561 complete(&dma->comp);
562 }
563 }
564#ifndef CONFIG_FB_MSM_MDP22
565 if (mdp_interrupt & MDP_HIST_DONE) {
566 outp32(MDP_BASE + 0x94018, 0x3);
567 outp32(MDP_INTR_CLEAR, MDP_HIST_DONE);
568 if (mdp_hist.r)
569 memcpy(mdp_hist.r, MDP_BASE + 0x94100,
570 mdp_hist.bin_cnt*4);
571 if (mdp_hist.g)
572 memcpy(mdp_hist.g, MDP_BASE + 0x94200,
573 mdp_hist.bin_cnt*4);
574 if (mdp_hist.b)
575 memcpy(mdp_hist.b, MDP_BASE + 0x94300,
576 mdp_hist.bin_cnt*4);
577 complete(&mdp_hist_comp);
578 }
579
580 /* LCDC UnderFlow */
581 if (mdp_interrupt & LCDC_UNDERFLOW) {
582 mdp_lcdc_underflow_cnt++;
583 }
584 /* LCDC Frame Start */
585 if (mdp_interrupt & LCDC_FRAME_START) {
586 /* let's disable LCDC interrupt */
587 mdp_intr_mask &= ~LCDC_FRAME_START;
588 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
589
590 dma = &dma2_data;
591 if (dma->waiting) {
592 dma->waiting = FALSE;
593 complete(&dma->comp);
594 }
595 }
596
597 /* DMA2 LCD-Out Complete */
598 if (mdp_interrupt & MDP_DMA_S_DONE) {
599 dma = &dma_s_data;
600 dma->busy = FALSE;
601 mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF,
602 TRUE);
603 complete(&dma->comp);
604 }
605#endif
606
607 /* DMA2 LCD-Out Complete */
608 if (mdp_interrupt & MDP_DMA_P_DONE) {
609 struct timeval now;
610 ktime_t now_k;
611
612 now_k = ktime_get_real();
613 mdp_dma2_last_update_time.tv.sec =
614 now_k.tv.sec - mdp_dma2_last_update_time.tv.sec;
615 mdp_dma2_last_update_time.tv.nsec =
616 now_k.tv.nsec - mdp_dma2_last_update_time.tv.nsec;
617
618 if (mdp_debug[MDP_DMA2_BLOCK]) {
619 jiffies_to_timeval(jiffies, &now);
620 mdp_dma2_timeval.tv_usec =
621 now.tv_usec - mdp_dma2_timeval.tv_usec;
622 }
623
624 dma = &dma2_data;
625 dma->busy = FALSE;
626 mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF,
627 TRUE);
628 complete(&dma->comp);
629 }
630 /* PPP Complete */
631 if (mdp_interrupt & MDP_PPP_DONE) {
632#ifdef CONFIG_MDP_PPP_ASYNC_OP
633 mdp_ppp_djob_done();
634#else
635 mdp_pipe_ctrl(MDP_PPP_BLOCK,
636 MDP_BLOCK_POWER_OFF, TRUE);
637 if (mdp_ppp_waiting) {
638 mdp_ppp_waiting = FALSE;
639 complete(&mdp_ppp_comp);
640 }
641#endif
642 }
643 } while (1);
644
645 mdp_is_in_isr = FALSE;
646
647 return IRQ_HANDLED;
648}
649#endif
650
651static void mdp_drv_init(void)
652{
653 int i;
654
655 for (i = 0; i < MDP_MAX_BLOCK; i++) {
656 mdp_debug[i] = 0;
657 }
658
659 /* initialize spin lock and workqueue */
660 spin_lock_init(&mdp_spin_lock);
661 mdp_dma_wq = create_singlethread_workqueue("mdp_dma_wq");
662 mdp_vsync_wq = create_singlethread_workqueue("mdp_vsync_wq");
663 mdp_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq");
664 INIT_DELAYED_WORK(&mdp_pipe_ctrl_worker,
665 mdp_pipe_ctrl_workqueue_handler);
666#ifdef CONFIG_MDP_PPP_ASYNC_OP
667 mdp_ppp_dq_init();
668#endif
669
670 /* initialize semaphore */
671 init_completion(&mdp_ppp_comp);
672 init_MUTEX(&mdp_ppp_mutex);
673 init_MUTEX(&mdp_pipe_ctrl_mutex);
674
675 dma2_data.busy = FALSE;
676 dma2_data.waiting = FALSE;
677 init_completion(&dma2_data.comp);
678 init_MUTEX(&dma2_data.mutex);
679 mutex_init(&dma2_data.ov_mutex);
680
681 dma3_data.busy = FALSE;
682 dma3_data.waiting = FALSE;
683 init_completion(&dma3_data.comp);
684 init_MUTEX(&dma3_data.mutex);
685
686 dma_s_data.busy = FALSE;
687 dma_s_data.waiting = FALSE;
688 init_completion(&dma_s_data.comp);
689 init_MUTEX(&dma_s_data.mutex);
690
691 dma_e_data.busy = FALSE;
692 dma_e_data.waiting = FALSE;
693 init_completion(&dma_e_data.comp);
694
695#ifndef CONFIG_FB_MSM_MDP22
696 init_completion(&mdp_hist_comp);
697#endif
698
699 /* initializing mdp power block counter to 0 */
700 for (i = 0; i < MDP_MAX_BLOCK; i++) {
701 mdp_block_power_cnt[i] = 0;
702 }
703
704#ifdef MSM_FB_ENABLE_DBGFS
705 {
706 struct dentry *root;
707 char sub_name[] = "mdp";
708
709 root = msm_fb_get_debugfs_root();
710 if (root != NULL) {
711 mdp_dir = debugfs_create_dir(sub_name, root);
712
713 if (mdp_dir) {
714 msm_fb_debugfs_file_create(mdp_dir,
715 "dma2_update_time_in_usec",
716 (u32 *) &mdp_dma2_update_time_in_usec);
717 msm_fb_debugfs_file_create(mdp_dir,
718 "vs_rdcnt_slow",
719 (u32 *) &mdp_lcd_rd_cnt_offset_slow);
720 msm_fb_debugfs_file_create(mdp_dir,
721 "vs_rdcnt_fast",
722 (u32 *) &mdp_lcd_rd_cnt_offset_fast);
723 msm_fb_debugfs_file_create(mdp_dir,
724 "mdp_usec_diff_threshold",
725 (u32 *) &mdp_usec_diff_threshold);
726 msm_fb_debugfs_file_create(mdp_dir,
727 "mdp_current_clk_on",
728 (u32 *) &mdp_current_clk_on);
729#ifdef CONFIG_FB_MSM_LCDC
730 msm_fb_debugfs_file_create(mdp_dir,
731 "lcdc_start_x",
732 (u32 *) &first_pixel_start_x);
733 msm_fb_debugfs_file_create(mdp_dir,
734 "lcdc_start_y",
735 (u32 *) &first_pixel_start_y);
736 msm_fb_debugfs_file_create(mdp_dir,
737 "mdp_lcdc_pclk_clk_rate",
738 (u32 *) &mdp_lcdc_pclk_clk_rate);
739 msm_fb_debugfs_file_create(mdp_dir,
740 "mdp_lcdc_pad_pclk_clk_rate",
741 (u32 *) &mdp_lcdc_pad_pclk_clk_rate);
742#endif
743 }
744 }
745 }
746#endif
747}
748
749static int mdp_probe(struct platform_device *pdev);
750static int mdp_remove(struct platform_device *pdev);
751
752static struct platform_driver mdp_driver = {
753 .probe = mdp_probe,
754 .remove = mdp_remove,
755#ifndef CONFIG_HAS_EARLYSUSPEND
756 .suspend = mdp_suspend,
757 .resume = NULL,
758#endif
759 .shutdown = NULL,
760 .driver = {
761 /*
762 * Driver name must match the device name added in
763 * platform.c.
764 */
765 .name = "mdp",
766 },
767};
768
769static int mdp_off(struct platform_device *pdev)
770{
771 int ret = 0;
772
773#ifdef MDP_HW_VSYNC
774 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
775#endif
776
777 ret = panel_next_off(pdev);
778
779#ifdef MDP_HW_VSYNC
780 mdp_hw_vsync_clk_disable(mfd);
781#endif
782
783 return ret;
784}
785
786static int mdp_on(struct platform_device *pdev)
787{
788#ifdef MDP_HW_VSYNC
789 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
790#endif
791
792 int ret = 0;
793
794#ifdef MDP_HW_VSYNC
795 mdp_hw_vsync_clk_enable(mfd);
796#endif
797
798 ret = panel_next_on(pdev);
799
800 return ret;
801}
802
803static int mdp_irq_clk_setup(void)
804{
805 int ret;
806
807#ifdef CONFIG_FB_MSM_MDP40
808 ret = request_irq(INT_MDP, mdp4_isr, IRQF_DISABLED, "MDP", 0);
809#else
810 ret = request_irq(INT_MDP, mdp_isr, IRQF_DISABLED, "MDP", 0);
811#endif
812 if (ret) {
813 printk(KERN_ERR "mdp request_irq() failed!\n");
814 return ret;
815 }
816 disable_irq(INT_MDP);
817
818 mdp_clk = clk_get(NULL, "mdp_clk");
819
820 if (IS_ERR(mdp_clk)) {
821 ret = PTR_ERR(mdp_clk);
822 printk(KERN_ERR "can't get mdp_clk error:%d!\n", ret);
823 free_irq(INT_MDP, 0);
824 return ret;
825 }
826
827 mdp_pclk = clk_get(NULL, "mdp_pclk");
828 if (IS_ERR(mdp_pclk))
829 mdp_pclk = NULL;
830
831
832#ifdef CONFIG_FB_MSM_MDP40
833 /*
834 * mdp_clk should greater than mdp_pclk always
835 */
836 clk_set_rate(mdp_clk, 122880000); /* 122.88 Mhz */
837 printk(KERN_INFO "mdp_clk: mdp_clk=%d mdp_pclk=%d\n",
838 (int)clk_get_rate(mdp_clk), (int)clk_get_rate(mdp_pclk));
839#endif
840
841 return 0;
842}
843
844static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
845static int pdev_list_cnt;
846static int mdp_resource_initialized;
847static struct msm_panel_common_pdata *mdp_pdata;
848
849static int mdp_probe(struct platform_device *pdev)
850{
851 struct platform_device *msm_fb_dev = NULL;
852 struct msm_fb_data_type *mfd;
853 struct msm_fb_panel_data *pdata = NULL;
854 int rc;
855 resource_size_t size ;
856#ifdef CONFIG_FB_MSM_MDP40
857 int intf, if_no;
858#else
859 unsigned long flag;
860#endif
861
862 if ((pdev->id == 0) && (pdev->num_resources > 0)) {
863 mdp_pdata = pdev->dev.platform_data;
864
865 size = resource_size(&pdev->resource[0]);
866 msm_mdp_base = ioremap(pdev->resource[0].start, size);
867
868 MSM_FB_INFO("MDP HW Base phy_Address = 0x%x virt = 0x%x\n",
869 (int)pdev->resource[0].start, (int)msm_mdp_base);
870
871 if (unlikely(!msm_mdp_base))
872 return -ENOMEM;
873
874 printk("irq clk setup\n");
875 rc = mdp_irq_clk_setup();
876 printk("irq clk setup done\n");
877 if (rc)
878 return rc;
879
880 /* initializing mdp hw */
881#ifdef CONFIG_FB_MSM_MDP40
882 mdp4_hw_init();
883#else
884 mdp_hw_init();
885#endif
886
887 mdp_resource_initialized = 1;
888 return 0;
889 }
890
891 if (!mdp_resource_initialized)
892 return -EPERM;
893
894 mfd = platform_get_drvdata(pdev);
895
896 if (!mfd)
897 return -ENODEV;
898
899 if (mfd->key != MFD_KEY)
900 return -EINVAL;
901
902 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
903 return -ENOMEM;
904
905 msm_fb_dev = platform_device_alloc("msm_fb", pdev->id);
906 if (!msm_fb_dev)
907 return -ENOMEM;
908
909 /* link to the latest pdev */
910 mfd->pdev = msm_fb_dev;
911
912 /* add panel data */
913 if (platform_device_add_data
914 (msm_fb_dev, pdev->dev.platform_data,
915 sizeof(struct msm_fb_panel_data))) {
916 printk(KERN_ERR "mdp_probe: platform_device_add_data failed!\n");
917 rc = -ENOMEM;
918 goto mdp_probe_err;
919 }
920 /* data chain */
921 pdata = msm_fb_dev->dev.platform_data;
922 pdata->on = mdp_on;
923 pdata->off = mdp_off;
924 pdata->next = pdev;
925
926 switch (mfd->panel.type) {
927 case EXT_MDDI_PANEL:
928 case MDDI_PANEL:
929 case EBI2_PANEL:
930 INIT_WORK(&mfd->dma_update_worker,
931 mdp_lcd_update_workqueue_handler);
932 INIT_WORK(&mfd->vsync_resync_worker,
933 mdp_vsync_resync_workqueue_handler);
934 mfd->hw_refresh = FALSE;
935
936 if (mfd->panel.type == EXT_MDDI_PANEL) {
937 /* 15 fps -> 66 msec */
938 mfd->refresh_timer_duration = (66 * HZ / 1000);
939 } else {
940 /* 24 fps -> 42 msec */
941 mfd->refresh_timer_duration = (42 * HZ / 1000);
942 }
943
944#ifdef CONFIG_FB_MSM_MDP22
945 mfd->dma_fnc = mdp_dma2_update;
946 mfd->dma = &dma2_data;
947#else
948 if (mfd->panel_info.pdest == DISPLAY_1) {
949#ifdef CONFIG_FB_MSM_OVERLAY
950 mfd->dma_fnc = mdp4_mddi_overlay;
951#else
952 mfd->dma_fnc = mdp_dma2_update;
953#endif
954 mfd->dma = &dma2_data;
955 mfd->lut_update = mdp_lut_update_nonlcdc;
956 mfd->do_histogram = mdp_do_histogram;
957 } else {
958 mfd->dma_fnc = mdp_dma_s_update;
959 mfd->dma = &dma_s_data;
960 }
961#endif
962 if (mdp_pdata)
963 mfd->vsync_gpio = mdp_pdata->gpio;
964 else
965 mfd->vsync_gpio = -1;
966
967#ifdef CONFIG_FB_MSM_MDP40
968 if (mfd->panel.type == EBI2_PANEL)
969 intf = EBI2_INTF;
970 else
971 intf = MDDI_INTF;
972
973 if (mfd->panel_info.pdest == DISPLAY_1)
974 if_no = PRIMARY_INTF_SEL;
975 else
976 if_no = SECONDARY_INTF_SEL;
977
978 mdp4_display_intf_sel(if_no, intf);
979#endif
980 mdp_config_vsync(mfd);
981 break;
982
983 case HDMI_PANEL:
984 case LCDC_PANEL:
985 pdata->on = mdp_lcdc_on;
986 pdata->off = mdp_lcdc_off;
987 mfd->hw_refresh = TRUE;
988 mfd->cursor_update = mdp_hw_cursor_update;
989#ifndef CONFIG_FB_MSM_MDP22
990 mfd->lut_update = mdp_lut_update_lcdc;
991 mfd->do_histogram = mdp_do_histogram;
992#endif
993#ifdef CONFIG_FB_MSM_OVERLAY
994 mfd->dma_fnc = mdp4_lcdc_overlay;
995#else
996 mfd->dma_fnc = mdp_lcdc_update;
997#endif
998
999#ifdef CONFIG_FB_MSM_MDP40
1000 if (mfd->panel.type == HDMI_PANEL) {
1001 mfd->dma = &dma_e_data;
1002 mdp4_display_intf_sel(EXTERNAL_INTF_SEL, LCDC_RGB_INTF);
1003 } else {
1004 mfd->dma = &dma2_data;
1005 mdp4_display_intf_sel(PRIMARY_INTF_SEL, LCDC_RGB_INTF);
1006 }
1007#else
1008 mfd->dma = &dma2_data;
1009 spin_lock_irqsave(&mdp_spin_lock, flag);
1010 mdp_intr_mask &= ~MDP_DMA_P_DONE;
1011 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
1012 spin_unlock_irqrestore(&mdp_spin_lock, flag);
1013#endif
1014 break;
1015
1016 case TV_PANEL:
1017 pdata->on = mdp_dma3_on;
1018 pdata->off = mdp_dma3_off;
1019 mfd->hw_refresh = TRUE;
1020 mfd->dma_fnc = mdp_dma3_update;
1021 mfd->dma = &dma3_data;
1022 break;
1023
1024 default:
1025 printk(KERN_ERR "mdp_probe: unknown device type!\n");
1026 rc = -ENODEV;
1027 goto mdp_probe_err;
1028 }
1029
1030 /* set driver data */
1031 platform_set_drvdata(msm_fb_dev, mfd);
1032
1033 rc = platform_device_add(msm_fb_dev);
1034 if (rc) {
1035 goto mdp_probe_err;
1036 }
1037
1038 pdev_list[pdev_list_cnt++] = pdev;
1039 return 0;
1040
1041 mdp_probe_err:
1042 platform_device_put(msm_fb_dev);
1043 return rc;
1044}
1045
1046static void mdp_suspend_sub(void)
1047{
1048 /* cancel pipe ctrl worker */
1049 cancel_delayed_work(&mdp_pipe_ctrl_worker);
1050
1051 /* for workder can't be cancelled... */
1052 flush_workqueue(mdp_pipe_ctrl_wq);
1053
1054 /* let's wait for PPP completion */
1055 while (mdp_block_power_cnt[MDP_PPP_BLOCK] > 0) ;
1056
1057 /* try to power down */
1058 mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1059}
1060
1061#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
1062static int mdp_suspend(struct platform_device *pdev, pm_message_t state)
1063{
1064 mdp_suspend_sub();
1065 return 0;
1066}
1067#endif
1068
1069#ifdef CONFIG_HAS_EARLYSUSPEND
1070static void mdp_early_suspend(struct early_suspend *h)
1071{
1072 mdp_suspend_sub();
1073}
1074#endif
1075
1076static int mdp_remove(struct platform_device *pdev)
1077{
1078 iounmap(msm_mdp_base);
1079 return 0;
1080}
1081
1082static int mdp_register_driver(void)
1083{
1084#ifdef CONFIG_HAS_EARLYSUSPEND
1085 early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
1086 early_suspend.suspend = mdp_early_suspend;
1087 register_early_suspend(&early_suspend);
1088#endif
1089
1090 return platform_driver_register(&mdp_driver);
1091}
1092
1093static int __init mdp_driver_init(void)
1094{
1095 int ret;
1096
1097 mdp_drv_init();
1098
1099 ret = mdp_register_driver();
1100 if (ret) {
1101 printk(KERN_ERR "mdp_register_driver() failed!\n");
1102 return ret;
1103 }
1104
1105#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_FB_MSM_MDP40)
1106 mdp4_debugfs_init();
1107#endif
1108
1109 return 0;
1110
1111}
1112
1113module_init(mdp_driver_init);
diff --git a/drivers/staging/msm/mdp.h b/drivers/staging/msm/mdp.h
new file mode 100644
index 000000000000..0a5d6ac386ac
--- /dev/null
+++ b/drivers/staging/msm/mdp.h
@@ -0,0 +1,695 @@
1/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef MDP_H
30#define MDP_H
31
32#include <linux/kernel.h>
33#include <linux/sched.h>
34#include <linux/time.h>
35#include <linux/init.h>
36#include <linux/interrupt.h>
37#include <linux/fb.h>
38#include <linux/hrtimer.h>
39#include "msm_mdp.h"
40
41#include <mach/hardware.h>
42#include <linux/io.h>
43
44#include <asm/system.h>
45#include <asm/mach-types.h>
46
47#include "msm_fb_panel.h"
48
49#ifdef CONFIG_MDP_PPP_ASYNC_OP
50#include "mdp_ppp_dq.h"
51#endif
52
53#ifdef BIT
54#undef BIT
55#endif
56
57#define BIT(x) (1<<(x))
58
59#define MDPOP_NOP 0
60#define MDPOP_LR BIT(0) /* left to right flip */
61#define MDPOP_UD BIT(1) /* up and down flip */
62#define MDPOP_ROT90 BIT(2) /* rotate image to 90 degree */
63#define MDPOP_ROT180 (MDPOP_UD|MDPOP_LR)
64#define MDPOP_ROT270 (MDPOP_ROT90|MDPOP_UD|MDPOP_LR)
65#define MDPOP_ASCALE BIT(7)
66#define MDPOP_ALPHAB BIT(8) /* enable alpha blending */
67#define MDPOP_TRANSP BIT(9) /* enable transparency */
68#define MDPOP_DITHER BIT(10) /* enable dither */
69#define MDPOP_SHARPENING BIT(11) /* enable sharpening */
70#define MDPOP_BLUR BIT(12) /* enable blur */
71#define MDPOP_FG_PM_ALPHA BIT(13)
72
73struct mdp_table_entry {
74 uint32_t reg;
75 uint32_t val;
76};
77
78extern struct mdp_ccs mdp_ccs_yuv2rgb ;
79extern struct mdp_ccs mdp_ccs_rgb2yuv ;
80
81/*
82 * MDP Image Structure
83 */
84typedef struct mdpImg_ {
85 uint32 imgType; /* Image type */
86 uint32 *bmy_addr; /* bitmap or y addr */
87 uint32 *cbcr_addr; /* cbcr addr */
88 uint32 width; /* image width */
89 uint32 mdpOp; /* image opertion (rotation,flip up/down, alpha/tp) */
90 uint32 tpVal; /* transparency color */
91 uint32 alpha; /* alpha percentage 0%(0x0) ~ 100%(0x100) */
92 int sp_value; /* sharpening strength */
93} MDPIMG;
94
95#ifdef CONFIG_MDP_PPP_ASYNC_OP
96#define MDP_OUTP(addr, data) mdp_ppp_outdw((uint32_t)(addr), \
97 (uint32_t)(data))
98#else
99#define MDP_OUTP(addr, data) outpdw((addr), (data))
100#endif
101
102#define MDP_KTIME2USEC(kt) (kt.tv.sec*1000000 + kt.tv.nsec/1000)
103
104#define MDP_BASE msm_mdp_base
105
106typedef enum {
107 MDP_BC_SCALE_POINT2_POINT4,
108 MDP_BC_SCALE_POINT4_POINT6,
109 MDP_BC_SCALE_POINT6_POINT8,
110 MDP_BC_SCALE_POINT8_1,
111 MDP_BC_SCALE_UP,
112 MDP_PR_SCALE_POINT2_POINT4,
113 MDP_PR_SCALE_POINT4_POINT6,
114 MDP_PR_SCALE_POINT6_POINT8,
115 MDP_PR_SCALE_POINT8_1,
116 MDP_PR_SCALE_UP,
117 MDP_SCALE_BLUR,
118 MDP_INIT_SCALE
119} MDP_SCALE_MODE;
120
121typedef enum {
122 MDP_BLOCK_POWER_OFF,
123 MDP_BLOCK_POWER_ON
124} MDP_BLOCK_POWER_STATE;
125
126typedef enum {
127 MDP_MASTER_BLOCK,
128 MDP_CMD_BLOCK,
129 MDP_PPP_BLOCK,
130 MDP_DMA2_BLOCK,
131 MDP_DMA3_BLOCK,
132 MDP_DMA_S_BLOCK,
133 MDP_DMA_E_BLOCK,
134 MDP_OVERLAY0_BLOCK,
135 MDP_OVERLAY1_BLOCK,
136 MDP_MAX_BLOCK
137} MDP_BLOCK_TYPE;
138
139/* Let's keep Q Factor power of 2 for optimization */
140#define MDP_SCALE_Q_FACTOR 512
141
142#ifdef CONFIG_FB_MSM_MDP31
143#define MDP_MAX_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*8)
144#define MDP_MIN_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/8)
145#define MDP_MAX_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*8)
146#define MDP_MIN_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/8)
147#else
148#define MDP_MAX_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*4)
149#define MDP_MIN_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/4)
150#define MDP_MAX_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*4)
151#define MDP_MIN_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/4)
152#endif
153
154/* SHIM Q Factor */
155#define PHI_Q_FACTOR 29
156#define PQF_PLUS_5 (PHI_Q_FACTOR + 5) /* due to 32 phases */
157#define PQF_PLUS_4 (PHI_Q_FACTOR + 4)
158#define PQF_PLUS_2 (PHI_Q_FACTOR + 2) /* to get 4.0 */
159#define PQF_MINUS_2 (PHI_Q_FACTOR - 2) /* to get 0.25 */
160#define PQF_PLUS_5_PLUS_2 (PQF_PLUS_5 + 2)
161#define PQF_PLUS_5_MINUS_2 (PQF_PLUS_5 - 2)
162
163#define MDP_CONVTP(tpVal) (((tpVal&0xF800)<<8)|((tpVal&0x7E0)<<5)|((tpVal&0x1F)<<3))
164
165#define MDPOP_ROTATION (MDPOP_ROT90|MDPOP_LR|MDPOP_UD)
166#define MDP_CHKBIT(val, bit) ((bit) == ((val) & (bit)))
167
168/* overlay interface API defines */
169typedef enum {
170 MORE_IBUF,
171 FINAL_IBUF,
172 COMPLETE_IBUF
173} MDP_IBUF_STATE;
174
175struct mdp_dirty_region {
176 __u32 xoffset; /* source origin in the x-axis */
177 __u32 yoffset; /* source origin in the y-axis */
178 __u32 width; /* number of pixels in the x-axis */
179 __u32 height; /* number of pixels in the y-axis */
180};
181
182/*
183 * MDP extended data types
184 */
185typedef struct mdp_roi_s {
186 uint32 x;
187 uint32 y;
188 uint32 width;
189 uint32 height;
190 int32 lcd_x;
191 int32 lcd_y;
192 uint32 dst_width;
193 uint32 dst_height;
194} MDP_ROI;
195
196typedef struct mdp_ibuf_s {
197 uint8 *buf;
198 uint32 bpp;
199 uint32 ibuf_type;
200 uint32 ibuf_width;
201 uint32 ibuf_height;
202
203 MDP_ROI roi;
204 MDPIMG mdpImg;
205
206 int32 dma_x;
207 int32 dma_y;
208 uint32 dma_w;
209 uint32 dma_h;
210
211 uint32 vsync_enable;
212 uint32 visible_swapped;
213} MDPIBUF;
214
215struct mdp_dma_data {
216 boolean busy;
217 boolean waiting;
218 struct mutex ov_mutex;
219 struct semaphore mutex;
220 struct completion comp;
221};
222
223#define MDP_CMD_DEBUG_ACCESS_BASE (MDP_BASE+0x10000)
224
225#define MDP_DMA2_TERM 0x1
226#define MDP_DMA3_TERM 0x2
227#define MDP_PPP_TERM 0x4
228#define MDP_DMA_S_TERM 0x8
229#ifdef CONFIG_FB_MSM_MDP40
230#define MDP_DMA_E_TERM 0x10
231#define MDP_OVERLAY0_TERM 0x20
232#define MDP_OVERLAY1_TERM 0x40
233#endif
234
235#define ACTIVE_START_X_EN BIT(31)
236#define ACTIVE_START_Y_EN BIT(31)
237#define ACTIVE_HIGH 0
238#define ACTIVE_LOW 1
239#define MDP_DMA_S_DONE BIT(2)
240#define LCDC_FRAME_START BIT(15)
241#define LCDC_UNDERFLOW BIT(16)
242
243#ifdef CONFIG_FB_MSM_MDP22
244#define MDP_DMA_P_DONE BIT(2)
245#else
246#define MDP_DMA_P_DONE BIT(14)
247#endif
248
249#define MDP_PPP_DONE BIT(0)
250#define TV_OUT_DMA3_DONE BIT(6)
251#define TV_ENC_UNDERRUN BIT(7)
252#define TV_OUT_DMA3_START BIT(13)
253#define MDP_HIST_DONE BIT(20)
254
255#ifdef CONFIG_FB_MSM_MDP22
256#define MDP_ANY_INTR_MASK (MDP_PPP_DONE| \
257 MDP_DMA_P_DONE| \
258 TV_ENC_UNDERRUN)
259#else
260#define MDP_ANY_INTR_MASK (MDP_PPP_DONE| \
261 MDP_DMA_P_DONE| \
262 MDP_DMA_S_DONE| \
263 LCDC_UNDERFLOW| \
264 MDP_HIST_DONE| \
265 TV_ENC_UNDERRUN)
266#endif
267
268#define MDP_TOP_LUMA 16
269#define MDP_TOP_CHROMA 0
270#define MDP_BOTTOM_LUMA 19
271#define MDP_BOTTOM_CHROMA 3
272#define MDP_LEFT_LUMA 22
273#define MDP_LEFT_CHROMA 6
274#define MDP_RIGHT_LUMA 25
275#define MDP_RIGHT_CHROMA 9
276
277#define CLR_G 0x0
278#define CLR_B 0x1
279#define CLR_R 0x2
280#define CLR_ALPHA 0x3
281
282#define CLR_Y CLR_G
283#define CLR_CB CLR_B
284#define CLR_CR CLR_R
285
286/* from lsb to msb */
287#define MDP_GET_PACK_PATTERN(a,x,y,z,bit) (((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
288
289/*
290 * 0x0000 0x0004 0x0008 MDP sync config
291 */
292#ifdef CONFIG_FB_MSM_MDP22
293#define MDP_SYNCFG_HGT_LOC 22
294#define MDP_SYNCFG_VSYNC_EXT_EN BIT(21)
295#define MDP_SYNCFG_VSYNC_INT_EN BIT(20)
296#else
297#define MDP_SYNCFG_HGT_LOC 21
298#define MDP_SYNCFG_VSYNC_EXT_EN BIT(20)
299#define MDP_SYNCFG_VSYNC_INT_EN BIT(19)
300#define MDP_HW_VSYNC
301#endif
302
303/*
304 * 0x0018 MDP VSYNC THREASH
305 */
306#define MDP_PRIM_BELOW_LOC 0
307#define MDP_PRIM_ABOVE_LOC 8
308
309/*
310 * MDP_PRIMARY_VSYNC_OUT_CTRL
311 * 0x0080,84,88 internal vsync pulse config
312 */
313#define VSYNC_PULSE_EN BIT(31)
314#define VSYNC_PULSE_INV BIT(30)
315
316/*
317 * 0x008c MDP VSYNC CONTROL
318 */
319#define DISP0_VSYNC_MAP_VSYNC0 0
320#define DISP0_VSYNC_MAP_VSYNC1 BIT(0)
321#define DISP0_VSYNC_MAP_VSYNC2 BIT(0)|BIT(1)
322
323#define DISP1_VSYNC_MAP_VSYNC0 0
324#define DISP1_VSYNC_MAP_VSYNC1 BIT(2)
325#define DISP1_VSYNC_MAP_VSYNC2 BIT(2)|BIT(3)
326
327#define PRIMARY_LCD_SYNC_EN BIT(4)
328#define PRIMARY_LCD_SYNC_DISABLE 0
329
330#define SECONDARY_LCD_SYNC_EN BIT(5)
331#define SECONDARY_LCD_SYNC_DISABLE 0
332
333#define EXTERNAL_LCD_SYNC_EN BIT(6)
334#define EXTERNAL_LCD_SYNC_DISABLE 0
335
336/*
337 * 0x101f0 MDP VSYNC Threshold
338 */
339#define VSYNC_THRESHOLD_ABOVE_LOC 0
340#define VSYNC_THRESHOLD_BELOW_LOC 16
341#define VSYNC_ANTI_TEAR_EN BIT(31)
342
343/*
344 * 0x10004 command config
345 */
346#define MDP_CMD_DBGBUS_EN BIT(0)
347
348/*
349 * 0x10124 or 0x101d4PPP source config
350 */
351#define PPP_SRC_C0G_8BITS (BIT(1)|BIT(0))
352#define PPP_SRC_C1B_8BITS (BIT(3)|BIT(2))
353#define PPP_SRC_C2R_8BITS (BIT(5)|BIT(4))
354#define PPP_SRC_C3A_8BITS (BIT(7)|BIT(6))
355
356#define PPP_SRC_C0G_6BITS BIT(1)
357#define PPP_SRC_C1B_6BITS BIT(3)
358#define PPP_SRC_C2R_6BITS BIT(5)
359
360#define PPP_SRC_C0G_5BITS BIT(0)
361#define PPP_SRC_C1B_5BITS BIT(2)
362#define PPP_SRC_C2R_5BITS BIT(4)
363
364#define PPP_SRC_C3_ALPHA_EN BIT(8)
365
366#define PPP_SRC_BPP_INTERLVD_1BYTES 0
367#define PPP_SRC_BPP_INTERLVD_2BYTES BIT(9)
368#define PPP_SRC_BPP_INTERLVD_3BYTES BIT(10)
369#define PPP_SRC_BPP_INTERLVD_4BYTES (BIT(10)|BIT(9))
370
371#define PPP_SRC_BPP_ROI_ODD_X BIT(11)
372#define PPP_SRC_BPP_ROI_ODD_Y BIT(12)
373#define PPP_SRC_INTERLVD_2COMPONENTS BIT(13)
374#define PPP_SRC_INTERLVD_3COMPONENTS BIT(14)
375#define PPP_SRC_INTERLVD_4COMPONENTS (BIT(14)|BIT(13))
376
377/*
378 * RGB666 unpack format
379 * TIGHT means R6+G6+B6 together
380 * LOOSE means R6+2 +G6+2+ B6+2 (with MSB)
381 * or 2+R6 +2+G6 +2+B6 (with LSB)
382 */
383#define PPP_SRC_UNPACK_TIGHT BIT(17)
384#define PPP_SRC_UNPACK_LOOSE 0
385#define PPP_SRC_UNPACK_ALIGN_LSB 0
386#define PPP_SRC_UNPACK_ALIGN_MSB BIT(18)
387
388#define PPP_SRC_FETCH_PLANES_INTERLVD 0
389#define PPP_SRC_FETCH_PLANES_PSEUDOPLNR BIT(20)
390
391#define PPP_SRC_WMV9_MODE BIT(21) /* window media version 9 */
392
393/*
394 * 0x10138 PPP operation config
395 */
396#define PPP_OP_SCALE_X_ON BIT(0)
397#define PPP_OP_SCALE_Y_ON BIT(1)
398
399#define PPP_OP_CONVERT_RGB2YCBCR 0
400#define PPP_OP_CONVERT_YCBCR2RGB BIT(2)
401#define PPP_OP_CONVERT_ON BIT(3)
402
403#define PPP_OP_CONVERT_MATRIX_PRIMARY 0
404#define PPP_OP_CONVERT_MATRIX_SECONDARY BIT(4)
405
406#define PPP_OP_LUT_C0_ON BIT(5)
407#define PPP_OP_LUT_C1_ON BIT(6)
408#define PPP_OP_LUT_C2_ON BIT(7)
409
410/* rotate or blend enable */
411#define PPP_OP_ROT_ON BIT(8)
412
413#define PPP_OP_ROT_90 BIT(9)
414#define PPP_OP_FLIP_LR BIT(10)
415#define PPP_OP_FLIP_UD BIT(11)
416
417#define PPP_OP_BLEND_ON BIT(12)
418
419#define PPP_OP_BLEND_SRCPIXEL_ALPHA 0
420#define PPP_OP_BLEND_DSTPIXEL_ALPHA BIT(13)
421#define PPP_OP_BLEND_CONSTANT_ALPHA BIT(14)
422#define PPP_OP_BLEND_SRCPIXEL_TRANSP (BIT(13)|BIT(14))
423
424#define PPP_OP_BLEND_ALPHA_BLEND_NORMAL 0
425#define PPP_OP_BLEND_ALPHA_BLEND_REVERSE BIT(15)
426
427#define PPP_OP_DITHER_EN BIT(16)
428
429#define PPP_OP_COLOR_SPACE_RGB 0
430#define PPP_OP_COLOR_SPACE_YCBCR BIT(17)
431
432#define PPP_OP_SRC_CHROMA_RGB 0
433#define PPP_OP_SRC_CHROMA_H2V1 BIT(18)
434#define PPP_OP_SRC_CHROMA_H1V2 BIT(19)
435#define PPP_OP_SRC_CHROMA_420 (BIT(18)|BIT(19))
436#define PPP_OP_SRC_CHROMA_COSITE 0
437#define PPP_OP_SRC_CHROMA_OFFSITE BIT(20)
438
439#define PPP_OP_DST_CHROMA_RGB 0
440#define PPP_OP_DST_CHROMA_H2V1 BIT(21)
441#define PPP_OP_DST_CHROMA_H1V2 BIT(22)
442#define PPP_OP_DST_CHROMA_420 (BIT(21)|BIT(22))
443#define PPP_OP_DST_CHROMA_COSITE 0
444#define PPP_OP_DST_CHROMA_OFFSITE BIT(23)
445
446#define PPP_BLEND_CALPHA_TRNASP BIT(24)
447
448#define PPP_OP_BG_CHROMA_RGB 0
449#define PPP_OP_BG_CHROMA_H2V1 BIT(25)
450#define PPP_OP_BG_CHROMA_H1V2 BIT(26)
451#define PPP_OP_BG_CHROMA_420 BIT(25)|BIT(26)
452#define PPP_OP_BG_CHROMA_SITE_COSITE 0
453#define PPP_OP_BG_CHROMA_SITE_OFFSITE BIT(27)
454#define PPP_OP_DEINT_EN BIT(29)
455
456#define PPP_BLEND_BG_USE_ALPHA_SEL (1 << 0)
457#define PPP_BLEND_BG_ALPHA_REVERSE (1 << 3)
458#define PPP_BLEND_BG_SRCPIXEL_ALPHA (0 << 1)
459#define PPP_BLEND_BG_DSTPIXEL_ALPHA (1 << 1)
460#define PPP_BLEND_BG_CONSTANT_ALPHA (2 << 1)
461#define PPP_BLEND_BG_CONST_ALPHA_VAL(x) ((x) << 24)
462
463#define PPP_OP_DST_RGB 0
464#define PPP_OP_DST_YCBCR BIT(30)
465/*
466 * 0x10150 PPP destination config
467 */
468#define PPP_DST_C0G_8BIT (BIT(0)|BIT(1))
469#define PPP_DST_C1B_8BIT (BIT(3)|BIT(2))
470#define PPP_DST_C2R_8BIT (BIT(5)|BIT(4))
471#define PPP_DST_C3A_8BIT (BIT(7)|BIT(6))
472
473#define PPP_DST_C0G_6BIT BIT(1)
474#define PPP_DST_C1B_6BIT BIT(3)
475#define PPP_DST_C2R_6BIT BIT(5)
476
477#define PPP_DST_C0G_5BIT BIT(0)
478#define PPP_DST_C1B_5BIT BIT(2)
479#define PPP_DST_C2R_5BIT BIT(4)
480
481#define PPP_DST_C3A_8BIT (BIT(7)|BIT(6))
482#define PPP_DST_C3ALPHA_EN BIT(8)
483
484#define PPP_DST_PACKET_CNT_INTERLVD_2ELEM BIT(9)
485#define PPP_DST_PACKET_CNT_INTERLVD_3ELEM BIT(10)
486#define PPP_DST_PACKET_CNT_INTERLVD_4ELEM (BIT(10)|BIT(9))
487#define PPP_DST_PACKET_CNT_INTERLVD_6ELEM (BIT(11)|BIT(9))
488
489#define PPP_DST_PACK_LOOSE 0
490#define PPP_DST_PACK_TIGHT BIT(13)
491#define PPP_DST_PACK_ALIGN_LSB 0
492#define PPP_DST_PACK_ALIGN_MSB BIT(14)
493
494#define PPP_DST_OUT_SEL_AXI 0
495#define PPP_DST_OUT_SEL_MDDI BIT(15)
496
497#define PPP_DST_BPP_2BYTES BIT(16)
498#define PPP_DST_BPP_3BYTES BIT(17)
499#define PPP_DST_BPP_4BYTES (BIT(17)|BIT(16))
500
501#define PPP_DST_PLANE_INTERLVD 0
502#define PPP_DST_PLANE_PLANAR BIT(18)
503#define PPP_DST_PLANE_PSEUDOPLN BIT(19)
504
505#define PPP_DST_TO_TV BIT(20)
506
507#define PPP_DST_MDDI_PRIMARY 0
508#define PPP_DST_MDDI_SECONDARY BIT(21)
509#define PPP_DST_MDDI_EXTERNAL BIT(22)
510
511/*
512 * 0x10180 DMA config
513 */
514#define DMA_DSTC0G_8BITS (BIT(1)|BIT(0))
515#define DMA_DSTC1B_8BITS (BIT(3)|BIT(2))
516#define DMA_DSTC2R_8BITS (BIT(5)|BIT(4))
517
518#define DMA_DSTC0G_6BITS BIT(1)
519#define DMA_DSTC1B_6BITS BIT(3)
520#define DMA_DSTC2R_6BITS BIT(5)
521
522#define DMA_DSTC0G_5BITS BIT(0)
523#define DMA_DSTC1B_5BITS BIT(2)
524#define DMA_DSTC2R_5BITS BIT(4)
525
526#define DMA_PACK_TIGHT BIT(6)
527#define DMA_PACK_LOOSE 0
528#define DMA_PACK_ALIGN_LSB 0
529/*
530 * use DMA_PACK_ALIGN_MSB if the upper 6 bits from 8 bits output
531 * from LCDC block maps into 6 pins out to the panel
532 */
533#define DMA_PACK_ALIGN_MSB BIT(7)
534#define DMA_PACK_PATTERN_RGB \
535 (MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8)
536#define DMA_PACK_PATTERN_BGR \
537 (MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 2)<<8)
538#define DMA_OUT_SEL_AHB 0
539#define DMA_OUT_SEL_LCDC BIT(20)
540#define DMA_IBUF_FORMAT_RGB888 0
541#define DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888 BIT(26)
542
543#ifdef CONFIG_FB_MSM_MDP22
544#define DMA_OUT_SEL_MDDI BIT(14)
545#define DMA_AHBM_LCD_SEL_PRIMARY 0
546#define DMA_AHBM_LCD_SEL_SECONDARY BIT(15)
547#define DMA_IBUF_C3ALPHA_EN BIT(16)
548#define DMA_DITHER_EN BIT(17)
549#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
550#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY BIT(18)
551#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL BIT(19)
552#define DMA_IBUF_FORMAT_RGB565 BIT(20)
553#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 0
554#define DMA_IBUF_NONCONTIGUOUS BIT(21)
555#else
556#define DMA_OUT_SEL_MDDI BIT(19)
557#define DMA_AHBM_LCD_SEL_PRIMARY 0
558#define DMA_AHBM_LCD_SEL_SECONDARY 0
559#define DMA_IBUF_C3ALPHA_EN 0
560#define DMA_DITHER_EN BIT(24)
561#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
562#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY 0
563#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL 0
564#define DMA_IBUF_FORMAT_RGB565 BIT(25)
565#define DMA_IBUF_NONCONTIGUOUS 0
566#endif
567
568/*
569 * MDDI Register
570 */
571#define MDDI_VDO_PACKET_DESC 0x5666
572
573#ifdef CONFIG_FB_MSM_MDP40
574#define MDP_INTR_ENABLE (msm_mdp_base + 0x0050)
575#define MDP_INTR_STATUS (msm_mdp_base + 0x0054)
576#define MDP_INTR_CLEAR (msm_mdp_base + 0x0058)
577#define MDP_EBI2_LCD0 (msm_mdp_base + 0x0060)
578#define MDP_EBI2_LCD1 (msm_mdp_base + 0x0064)
579#define MDP_EBI2_PORTMAP_MODE (msm_mdp_base + 0x0070)
580
581#define MDP_DMA_P_HIST_INTR_STATUS (msm_mdp_base + 0x95014)
582#define MDP_DMA_P_HIST_INTR_CLEAR (msm_mdp_base + 0x95018)
583#define MDP_DMA_P_HIST_INTR_ENABLE (msm_mdp_base + 0x9501C)
584#else
585#define MDP_INTR_ENABLE (msm_mdp_base + 0x0020)
586#define MDP_INTR_STATUS (msm_mdp_base + 0x0024)
587#define MDP_INTR_CLEAR (msm_mdp_base + 0x0028)
588#define MDP_EBI2_LCD0 (msm_mdp_base + 0x003c)
589#define MDP_EBI2_LCD1 (msm_mdp_base + 0x0040)
590#define MDP_EBI2_PORTMAP_MODE (msm_mdp_base + 0x005c)
591#endif
592
593#define MDP_FULL_BYPASS_WORD43 (msm_mdp_base + 0x101ac)
594
595#define MDP_CSC_PFMVn(n) (msm_mdp_base + 0x40400 + 4 * (n))
596#define MDP_CSC_PRMVn(n) (msm_mdp_base + 0x40440 + 4 * (n))
597#define MDP_CSC_PRE_BV1n(n) (msm_mdp_base + 0x40500 + 4 * (n))
598#define MDP_CSC_PRE_BV2n(n) (msm_mdp_base + 0x40540 + 4 * (n))
599#define MDP_CSC_POST_BV1n(n) (msm_mdp_base + 0x40580 + 4 * (n))
600#define MDP_CSC_POST_BV2n(n) (msm_mdp_base + 0x405c0 + 4 * (n))
601
602#ifdef CONFIG_FB_MSM_MDP31
603#define MDP_CSC_PRE_LV1n(n) (msm_mdp_base + 0x40600 + 4 * (n))
604#define MDP_CSC_PRE_LV2n(n) (msm_mdp_base + 0x40640 + 4 * (n))
605#define MDP_CSC_POST_LV1n(n) (msm_mdp_base + 0x40680 + 4 * (n))
606#define MDP_CSC_POST_LV2n(n) (msm_mdp_base + 0x406c0 + 4 * (n))
607#define MDP_PPP_SCALE_COEFF_LSBn(n) (msm_mdp_base + 0x50400 + 8 * (n))
608#define MDP_PPP_SCALE_COEFF_MSBn(n) (msm_mdp_base + 0x50404 + 8 * (n))
609
610#define SCALE_D0_SET 0
611#define SCALE_D1_SET BIT(0)
612#define SCALE_D2_SET BIT(1)
613#define SCALE_U1_SET (BIT(0)|BIT(1))
614
615#else
616#define MDP_CSC_PRE_LV1n(n) (msm_mdp_base + 0x40580 + 4 * (n))
617#endif
618
619#define MDP_CURSOR_WIDTH 64
620#define MDP_CURSOR_HEIGHT 64
621#define MDP_CURSOR_SIZE (MDP_CURSOR_WIDTH*MDP_CURSOR_WIDTH*4)
622
623#define MDP_DMA_P_LUT_C0_EN BIT(0)
624#define MDP_DMA_P_LUT_C1_EN BIT(1)
625#define MDP_DMA_P_LUT_C2_EN BIT(2)
626#define MDP_DMA_P_LUT_POST BIT(4)
627
628void mdp_hw_init(void);
629int mdp_ppp_pipe_wait(void);
630void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd);
631void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
632 boolean isr);
633void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
634 boolean sync);
635void mdp_dma_pan_update(struct fb_info *info);
636void mdp_refresh_screen(unsigned long data);
637int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req,
638 struct file **pp_src, struct file **pp_dest);
639void mdp_lcd_update_workqueue_handler(struct work_struct *work);
640void mdp_vsync_resync_workqueue_handler(struct work_struct *work);
641void mdp_dma2_update(struct msm_fb_data_type *mfd);
642void mdp_config_vsync(struct msm_fb_data_type *);
643uint32 mdp_get_lcd_line_counter(struct msm_fb_data_type *mfd);
644enum hrtimer_restart mdp_dma2_vsync_hrtimer_handler(struct hrtimer *ht);
645void mdp_set_scale(MDPIBUF *iBuf,
646 uint32 dst_roi_width,
647 uint32 dst_roi_height,
648 boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr);
649void mdp_init_scale_table(void);
650void mdp_adjust_start_addr(uint8 **src0,
651 uint8 **src1,
652 int v_slice,
653 int h_slice,
654 int x,
655 int y,
656 uint32 width,
657 uint32 height, int bpp, MDPIBUF *iBuf, int layer);
658void mdp_set_blend_attr(MDPIBUF *iBuf,
659 uint32 *alpha,
660 uint32 *tpVal,
661 uint32 perPixelAlpha, uint32 *pppop_reg_ptr);
662
663int mdp_dma3_on(struct platform_device *pdev);
664int mdp_dma3_off(struct platform_device *pdev);
665void mdp_dma3_update(struct msm_fb_data_type *mfd);
666
667int mdp_lcdc_on(struct platform_device *pdev);
668int mdp_lcdc_off(struct platform_device *pdev);
669void mdp_lcdc_update(struct msm_fb_data_type *mfd);
670int mdp_hw_cursor_update(struct fb_info *info, struct fb_cursor *cursor);
671void mdp_enable_irq(uint32 term);
672void mdp_disable_irq(uint32 term);
673void mdp_disable_irq_nolock(uint32 term);
674uint32_t mdp_get_bytes_per_pixel(uint32_t format);
675
676#ifdef MDP_HW_VSYNC
677void mdp_hw_vsync_clk_enable(struct msm_fb_data_type *mfd);
678void mdp_hw_vsync_clk_disable(struct msm_fb_data_type *mfd);
679#endif
680
681void mdp_dma_s_update(struct msm_fb_data_type *mfd);
682
683/* Added to support flipping */
684void mdp_set_offset_info(struct fb_info *info, uint32 address, uint32 interval);
685
686int get_gem_img(struct mdp_img *img, unsigned long *start,
687 unsigned long *len);
688int get_img(struct mdp_img *img, struct fb_info *info,
689 unsigned long *start, unsigned long *len,
690 struct file **pp_file);
691
692
693/*int get_img(struct msmfb_data *img, struct fb_info *info,
694 unsigned long *start, unsigned long *len, struct file **pp_file);*/
695#endif /* MDP_H */
diff --git a/drivers/staging/msm/mdp4.h b/drivers/staging/msm/mdp4.h
new file mode 100644
index 000000000000..26ec8f12cf64
--- /dev/null
+++ b/drivers/staging/msm/mdp4.h
@@ -0,0 +1,352 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef MDP4_H
30#define MDP4_H
31
32extern struct mdp_dma_data dma2_data;
33extern struct mdp_dma_data dma_s_data;
34extern struct mdp_dma_data dma_e_data;
35extern struct mdp_histogram mdp_hist;
36extern struct completion mdp_hist_comp;
37extern boolean mdp_is_in_isr;
38extern uint32 mdp_intr_mask;
39extern spinlock_t mdp_spin_lock;
40
41
42#define MDP4_NONBLOCKING /* enable non blocking ioctl */
43
44#define MDP4_OVERLAYPROC0_BASE 0x10000
45#define MDP4_OVERLAYPROC1_BASE 0x18000
46
47#define MDP4_VIDEO_BASE 0x20000
48#define MDP4_VIDEO_OFF 0x10000
49
50#define MDP4_RGB_BASE 0x40000
51#define MDP4_RGB_OFF 0x10000
52
53enum { /* display */
54 PRIMARY_INTF_SEL,
55 SECONDARY_INTF_SEL,
56 EXTERNAL_INTF_SEL
57};
58
59enum {
60 LCDC_RGB_INTF,
61 DTV_INTF = LCDC_RGB_INTF,
62 MDDI_LCDC_INTF,
63 MDDI_INTF,
64 EBI2_INTF
65};
66
67enum {
68 MDDI_PRIMARY_SET,
69 MDDI_SECONDARY_SET,
70 MDDI_EXTERNAL_SET
71};
72
73enum {
74 EBI2_LCD0,
75 EBI2_LCD1
76};
77
78enum {
79 OVERLAY_MODE_NONE,
80 OVERLAY_MODE_BLT
81};
82
83enum {
84 OVERLAY_REFRESH_ON_DEMAND,
85 OVERLAY_REFRESH_VSYNC,
86 OVERLAY_REFRESH_VSYNC_HALF,
87 OVERLAY_REFRESH_VSYNC_QUARTER
88};
89
90enum {
91 OVERLAY_FRAMEBUF,
92 OVERLAY_DIRECTOUT
93};
94
95/* system interrupts */
96#define INTR_OVERLAY0_DONE BIT(0)
97#define INTR_OVERLAY1_DONE BIT(1)
98#define INTR_DMA_S_DONE BIT(2)
99#define INTR_DMA_E_DONE BIT(3)
100#define INTR_DMA_P_DONE BIT(4)
101#define INTR_VG1_HISTOGRAM BIT(5)
102#define INTR_VG2_HISTOGRAM BIT(6)
103#define INTR_PRIMARY_VSYNC BIT(7)
104#define INTR_PRIMARY_INTF_UDERRUN BIT(8)
105#define INTR_EXTERNAL_VSYNC BIT(9)
106#define INTR_EXTERNAL_INTF_UDERRUN BIT(10)
107#define INTR_DMA_P_HISTOGRAM BIT(17)
108
109/* histogram interrupts */
110#define INTR_HIST_DONE BIT(0)
111#define INTR_HIST_RESET_SEQ_DONE BIT(1)
112
113
114#ifdef CONFIG_FB_MSM_OVERLAY
115#define MDP4_ANY_INTR_MASK (INTR_OVERLAY0_DONE)
116#else
117#define MDP4_ANY_INTR_MASK (INTR_DMA_P_DONE)
118#endif
119
120enum {
121 OVERLAY_PIPE_RGB1,
122 OVERLAY_PIPE_RGB2,
123};
124
125enum {
126 OVERLAY_PIPE_VG1, /* video/graphic */
127 OVERLAY_PIPE_VG2
128};
129
130enum {
131 OVERLAY_TYPE_RGB,
132 OVERLAY_TYPE_VG /* video/graphic */
133};
134
135enum {
136 MDP4_MIXER0,
137 MDP4_MIXER1
138};
139
140#define MDP4_MAX_MIXER 2
141
142enum {
143 OVERLAY_PLANE_INTERLEAVED,
144 OVERLAY_PLANE_PLANAR,
145 OVERLAY_PLANE_PSEUDO_PLANAR
146};
147
148enum {
149 MDP4_MIXER_STAGE_UNUNSED, /* pipe not used */
150 MDP4_MIXER_STAGE_BASE,
151 MDP4_MIXER_STAGE0, /* zorder 0 */
152 MDP4_MIXER_STAGE1, /* zorder 1 */
153 MDP4_MIXER_STAGE2 /* zorder 2 */
154};
155
156#define MDP4_MAX_STAGE 4
157
158enum {
159 MDP4_FRAME_FORMAT_LINEAR,
160 MDP4_FRAME_FORMAT_ARGB_TILE,
161 MDP4_FRAME_FORMAT_VIDEO_SUPERTILE
162};
163
164enum {
165 MDP4_CHROMA_RGB,
166 MDP4_CHROMA_H2V1,
167 MDP4_CHROMA_H1V2,
168 MDP4_CHROMA_420
169};
170
171#define MDP4_BLEND_BG_TRANSP_EN BIT(9)
172#define MDP4_BLEND_FG_TRANSP_EN BIT(8)
173#define MDP4_BLEND_BG_MOD_ALPHA BIT(7)
174#define MDP4_BLEND_BG_INV_ALPHA BIT(6)
175#define MDP4_BLEND_BG_ALPHA_FG_CONST (0 << 4)
176#define MDP4_BLEND_BG_ALPHA_BG_CONST (1 << 4)
177#define MDP4_BLEND_BG_ALPHA_FG_PIXEL (2 << 4)
178#define MDP4_BLEND_BG_ALPHA_BG_PIXEL (3 << 4)
179#define MDP4_BLEND_FG_MOD_ALPHA BIT(3)
180#define MDP4_BLEND_FG_INV_ALPHA BIT(2)
181#define MDP4_BLEND_FG_ALPHA_FG_CONST (0 << 0)
182#define MDP4_BLEND_FG_ALPHA_BG_CONST (1 << 0)
183#define MDP4_BLEND_FG_ALPHA_FG_PIXEL (2 << 0)
184#define MDP4_BLEND_FG_ALPHA_BG_PIXEL (3 << 0)
185
186#define MDP4_FORMAT_SOLID_FILL BIT(22)
187#define MDP4_FORMAT_UNPACK_ALIGN_MSB BIT(18)
188#define MDP4_FORMAT_UNPACK_TIGHT BIT(17)
189#define MDP4_FORMAT_90_ROTATED BIT(12)
190#define MDP4_FORMAT_ALPHA_ENABLE BIT(8)
191
192#define MDP4_OP_DEINT_ODD_REF BIT(19)
193#define MDP4_OP_IGC_LUT_EN BIT(16)
194#define MDP4_OP_DITHER_EN BIT(15)
195#define MDP4_OP_FLIP_UD BIT(14)
196#define MDP4_OP_FLIP_LR BIT(13)
197#define MDP4_OP_CSC_EN BIT(11)
198#define MDP4_OP_SRC_DATA_YCBCR BIT(9)
199#define MDP4_OP_SCALEY_FIR (0 << 4)
200#define MDP4_OP_SCALEY_MN_PHASE (1 << 4)
201#define MDP4_OP_SCALEY_PIXEL_RPT (2 << 4)
202#define MDP4_OP_SCALEX_FIR (0 << 2)
203#define MDP4_OP_SCALEX_MN_PHASE (1 << 2)
204#define MDP4_OP_SCALEX_PIXEL_RPT (2 << 2)
205#define MDP4_OP_SCALEY_EN BIT(1)
206#define MDP4_OP_SCALEX_EN BIT(0)
207
208#define MDP4_PIPE_PER_MIXER 2
209
210#define MDP4_MAX_PLANE 4
211
212#define MDP4_MAX_VIDEO_PIPE 2
213#define MDP4_MAX_RGB_PIPE 2
214#define MDP4_MAX_OVERLAY_PIPE 16
215
216
217struct mdp4_overlay_pipe {
218 uint32 pipe_type; /* rgb, video/graphic */
219 uint32 pipe_num;
220 uint32 pipe_ndx;
221 uint32 mixer_num; /* which mixer used */
222 uint32 mixer_stage; /* which stage of mixer used */
223 uint32 src_format;
224 uint32 src_width; /* source img width */
225 uint32 src_height; /* source img height */
226 uint32 src_w; /* roi */
227 uint32 src_h; /* roi */
228 uint32 src_x; /* roi */
229 uint32 src_y; /* roi */
230 uint32 dst_w; /* roi */
231 uint32 dst_h; /* roi */
232 uint32 dst_x; /* roi */
233 uint32 dst_y; /* roi */
234 uint32 op_mode;
235 uint32 transp;
236 uint32 blend_op;
237 uint32 phasex_step;
238 uint32 phasey_step;
239 uint32 alpha;
240 uint32 is_fg; /* control alpha & color key */
241 uint32 srcp0_addr; /* interleave, luma */
242 uint32 srcp0_ystride;
243 uint32 srcp1_addr; /* pseudoplanar, chroma plane */
244 uint32 srcp1_ystride;
245 uint32 srcp2_addr; /* planar color 2*/
246 uint32 srcp2_ystride;
247 uint32 srcp3_addr; /* alpha/color 3 */
248 uint32 srcp3_ystride;
249 uint32 fetch_plane;
250 uint32 frame_format; /* video */
251 uint32 chroma_site; /* video */
252 uint32 chroma_sample; /* video */
253 uint32 solid_fill;
254 uint32 vc1_reduce; /* video */
255 uint32 fatch_planes; /* video */
256 uint32 unpack_align_msb;/* 0 to LSB, 1 to MSB */
257 uint32 unpack_tight;/* 0 for loose, 1 for tight */
258 uint32 unpack_count;/* 0 = 1 component, 1 = 2 component ... */
259 uint32 rotated_90; /* has been rotated 90 degree */
260 uint32 bpp; /* byte per pixel */
261 uint32 alpha_enable;/* source has alpha */
262 /*
263 * number of bits for source component,
264 * 0 = 1 bit, 1 = 2 bits, 2 = 6 bits, 3 = 8 bits
265 */
266 uint32 a_bit; /* component 3, alpha */
267 uint32 r_bit; /* component 2, R_Cr */
268 uint32 b_bit; /* component 1, B_Cb */
269 uint32 g_bit; /* component 0, G_lumz */
270 /*
271 * unpack pattern
272 * A = C3, R = C2, B = C1, G = C0
273 */
274 uint32 element3; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
275 uint32 element2; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
276 uint32 element1; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
277 uint32 element0; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
278 struct completion comp;
279 struct mdp_overlay req_data;
280};
281
282void mdp4_sw_reset(unsigned long bits);
283void mdp4_display_intf_sel(int output, unsigned long intf);
284void mdp4_overlay_cfg(int layer, int blt_mode, int refresh, int direct_out);
285void mdp4_ebi2_lcd_setup(int lcd, unsigned long base, int ystride);
286void mdp4_mddi_setup(int which, unsigned long id);
287unsigned long mdp4_display_status(void);
288void mdp4_enable_clk_irq(void);
289void mdp4_disable_clk_irq(void);
290void mdp4_dma_p_update(struct msm_fb_data_type *mfd);
291void mdp4_dma_s_update(struct msm_fb_data_type *mfd);
292void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
293 boolean isr);
294void mdp4_pipe_kickoff(uint32 pipe, struct msm_fb_data_type *mfd);
295int mdp4_lcdc_on(struct platform_device *pdev);
296int mdp4_lcdc_off(struct platform_device *pdev);
297void mdp4_lcdc_update(struct msm_fb_data_type *mfd);
298void mdp4_intr_clear_set(ulong clear, ulong set);
299void mdp4_dma_p_cfg(void);
300void mdp4_hw_init(void);
301void mdp4_isr_read(int);
302void mdp4_clear_lcdc(void);
303void mdp4_mixer_blend_init(int mixer_num);
304void mdp4_vg_qseed_init(int vg_num);
305void mdp4_vg_csc_mv_setup(int vp_num);
306void mdp4_vg_csc_pre_bv_setup(int vp_num);
307void mdp4_vg_csc_post_bv_setup(int vp_num);
308void mdp4_vg_csc_pre_lv_setup(int vp_num);
309void mdp4_vg_csc_post_lv_setup(int vp_num);
310irqreturn_t mdp4_isr(int irq, void *ptr);
311void mdp4_overlay_format_to_pipe(uint32 format, struct mdp4_overlay_pipe *pipe);
312uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe);
313uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe);
314uint32 mdp4_overlay_op_mode(struct mdp4_overlay_pipe *pipe);
315void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd);
316void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe);
317void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all);
318void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe);
319void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe);
320void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe);
321int mdp4_mixer_stage_can_run(struct mdp4_overlay_pipe *pipe);
322void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe);
323void mdp4_mddi_overlay(struct msm_fb_data_type *mfd);
324int mdp4_overlay_format2type(uint32 format);
325int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe);
326int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req);
327int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req);
328int mdp4_overlay_unset(struct fb_info *info, int ndx);
329int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
330 struct file **pp_src_file);
331struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void);
332void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe);
333void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc);
334void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe);
335int mdp4_overlay_active(int mixer);
336void mdp4_overlay0_done_lcdc(void);
337void mdp4_overlay0_done_mddi(void);
338void mdp4_mddi_overlay_restore(void);
339void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd,
340 struct mdp4_overlay_pipe *pipe);
341void mdp4_rgb_igc_lut_setup(int num);
342void mdp4_vg_igc_lut_setup(int num);
343void mdp4_mixer_gc_lut_setup(int mixer_num);
344
345#ifdef CONFIG_DEBUG_FS
346int mdp4_debugfs_init(void);
347#endif
348
349int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req,
350 struct file **pp_src_file, struct file **pp_dst_file);
351
352#endif /* MDP_H */
diff --git a/drivers/staging/msm/mdp4_debugfs.c b/drivers/staging/msm/mdp4_debugfs.c
new file mode 100644
index 000000000000..844d46775ecd
--- /dev/null
+++ b/drivers/staging/msm/mdp4_debugfs.c
@@ -0,0 +1,181 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/time.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/spinlock.h>
24#include <linux/hrtimer.h>
25#include <linux/clk.h>
26#include <mach/hardware.h>
27#include <linux/io.h>
28#include <linux/debugfs.h>
29
30#include <asm/system.h>
31#include <asm/mach-types.h>
32#include <linux/semaphore.h>
33#include <linux/uaccess.h>
34
35#include "mdp.h"
36#include "msm_fb.h"
37#include "mdp4.h"
38
39
40#define MDP4_DEBUG_BUF 128
41
42
43static char mdp4_debug_buf[MDP4_DEBUG_BUF];
44static ulong mdp4_debug_offset;
45static ulong mdp4_base_addr;
46
47static int mdp4_offset_set(void *data, u64 val)
48{
49 mdp4_debug_offset = (int)val;
50 return 0;
51}
52
53static int mdp4_offset_get(void *data, u64 *val)
54{
55 *val = (u64)mdp4_debug_offset;
56 return 0;
57}
58
59DEFINE_SIMPLE_ATTRIBUTE(
60 mdp4_offset_fops,
61 mdp4_offset_get,
62 mdp4_offset_set,
63 "%llx\n");
64
65
66static int mdp4_debugfs_open(struct inode *inode, struct file *file)
67{
68 /* non-seekable */
69 file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
70 return 0;
71}
72
73static int mdp4_debugfs_release(struct inode *inode, struct file *file)
74{
75 return 0;
76}
77
78static ssize_t mdp4_debugfs_write(
79 struct file *file,
80 const char __user *buff,
81 size_t count,
82 loff_t *ppos)
83{
84 int cnt;
85 unsigned int data;
86
87 printk(KERN_INFO "%s: offset=%d count=%d *ppos=%d\n",
88 __func__, (int)mdp4_debug_offset, (int)count, (int)*ppos);
89
90 if (count > sizeof(mdp4_debug_buf))
91 return -EFAULT;
92
93 if (copy_from_user(mdp4_debug_buf, buff, count))
94 return -EFAULT;
95
96
97 mdp4_debug_buf[count] = 0; /* end of string */
98
99 cnt = sscanf(mdp4_debug_buf, "%x", &data);
100 if (cnt < 1) {
101 printk(KERN_ERR "%s: sscanf failed cnt=%d" , __func__, cnt);
102 return -EINVAL;
103 }
104
105 writel(&data, mdp4_base_addr + mdp4_debug_offset);
106
107 return 0;
108}
109
110static ssize_t mdp4_debugfs_read(
111 struct file *file,
112 char __user *buff,
113 size_t count,
114 loff_t *ppos)
115{
116 int len = 0;
117 unsigned int data;
118
119 printk(KERN_INFO "%s: offset=%d count=%d *ppos=%d\n",
120 __func__, (int)mdp4_debug_offset, (int)count, (int)*ppos);
121
122 if (*ppos)
123 return 0; /* the end */
124
125 data = readl(mdp4_base_addr + mdp4_debug_offset);
126
127 len = snprintf(mdp4_debug_buf, 4, "%x\n", data);
128
129 if (len > 0) {
130 if (len > count)
131 len = count;
132 if (copy_to_user(buff, mdp4_debug_buf, len))
133 return -EFAULT;
134 }
135
136 printk(KERN_INFO "%s: len=%d\n", __func__, len);
137
138 if (len < 0)
139 return 0;
140
141 *ppos += len; /* increase offset */
142
143 return len;
144}
145
146static const struct file_operations mdp4_debugfs_fops = {
147 .open = mdp4_debugfs_open,
148 .release = mdp4_debugfs_release,
149 .read = mdp4_debugfs_read,
150 .write = mdp4_debugfs_write,
151};
152
153int mdp4_debugfs_init(void)
154{
155 struct dentry *dent = debugfs_create_dir("mdp4", NULL);
156
157 if (IS_ERR(dent)) {
158 printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
159 __FILE__, __LINE__, PTR_ERR(dent));
160 return -1;
161 }
162
163 if (debugfs_create_file("offset", 0644, dent, 0, &mdp4_offset_fops)
164 == NULL) {
165 printk(KERN_ERR "%s(%d): debugfs_create_file: offset fail\n",
166 __FILE__, __LINE__);
167 return -1;
168 }
169
170 if (debugfs_create_file("regs", 0644, dent, 0, &mdp4_debugfs_fops)
171 == NULL) {
172 printk(KERN_ERR "%s(%d): debugfs_create_file: regs fail\n",
173 __FILE__, __LINE__);
174 return -1;
175 }
176
177 mdp4_debug_offset = 0;
178 mdp4_base_addr = (ulong) msm_mdp_base; /* defined at msm_fb_def.h */
179
180 return 0;
181}
diff --git a/drivers/staging/msm/mdp4_overlay.c b/drivers/staging/msm/mdp4_overlay.c
new file mode 100644
index 000000000000..304bb8297635
--- /dev/null
+++ b/drivers/staging/msm/mdp4_overlay.c
@@ -0,0 +1,1259 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/hrtimer.h>
26#include <linux/clk.h>
27#include <mach/hardware.h>
28#include <linux/io.h>
29#include <linux/debugfs.h>
30#include <linux/fb.h>
31#include <msm_mdp.h>
32#include <linux/file.h>
33#include "android_pmem.h"
34#include <linux/major.h>
35#include <asm/system.h>
36#include <asm/mach-types.h>
37#include <linux/semaphore.h>
38#include <linux/uaccess.h>
39#include <linux/mutex.h>
40
41#include "mdp.h"
42#include "msm_fb.h"
43#include "mdp4.h"
44
45
46struct mdp4_overlay_ctrl {
47 struct mdp4_overlay_pipe plist[MDP4_MAX_OVERLAY_PIPE];
48 struct mdp4_overlay_pipe *stage[MDP4_MAX_MIXER][MDP4_MAX_STAGE];
49} mdp4_overlay_db;
50
51static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
52
53
54void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc)
55{
56 uint32 dma2_cfg_reg;
57
58 dma2_cfg_reg = DMA_DITHER_EN;
59
60 if (mfd->fb_imgType == MDP_BGR_565)
61 dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
62 else
63 dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
64
65
66 if (mfd->panel_info.bpp == 18) {
67 dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
68 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
69 } else if (mfd->panel_info.bpp == 16) {
70 dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
71 DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
72 } else {
73 dma2_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 16BPP */
74 DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
75 }
76
77 if (lcdc)
78 dma2_cfg_reg |= DMA_PACK_ALIGN_MSB;
79
80 /* dma2 config register */
81 MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
82
83}
84
85void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
86{
87
88 /* dma_p source */
89 MDP_OUTP(MDP_BASE + 0x90004,
90 (pipe->src_height << 16 | pipe->src_width));
91 MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
92 MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
93
94 /* dma_p dest */
95 MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
96}
97
98#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000
99#define MDP4_VG_PHASE_STEP_SHIFT 29
100
101static int mdp4_leading_0(uint32 num)
102{
103 uint32 bit = 0x80000000;
104 int i;
105
106 for (i = 0; i < 32; i++) {
107 if (bit & num)
108 return i;
109 bit >>= 1;
110 }
111
112 return i;
113}
114
115static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
116{
117 uint32 val;
118 int n;
119
120 n = mdp4_leading_0(src);
121 if (n > f_num)
122 n = f_num;
123 val = src << n; /* maximum to reduce lose of resolution */
124 val /= dst;
125 if (n < f_num) {
126 n = f_num - n;
127 val <<= n;
128 }
129
130 return val;
131}
132
133static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe)
134{
135
136 pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
137 pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
138
139 if (pipe->dst_h && pipe->src_h != pipe->dst_h) {
140 if (pipe->dst_h >= pipe->src_h * 8) /* too much */
141 return;
142 pipe->op_mode |= MDP4_OP_SCALEY_EN;
143
144 if (pipe->pipe_type == OVERLAY_TYPE_VG) {
145 if (pipe->dst_h <= (pipe->src_h / 4))
146 pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
147 else
148 pipe->op_mode |= MDP4_OP_SCALEY_FIR;
149 }
150
151 pipe->phasey_step = mdp4_scale_phase_step(29,
152 pipe->src_h, pipe->dst_h);
153 }
154
155 if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
156 if (pipe->dst_w >= pipe->src_w * 8) /* too much */
157 return;
158 pipe->op_mode |= MDP4_OP_SCALEX_EN;
159
160 if (pipe->pipe_type == OVERLAY_TYPE_VG) {
161 if (pipe->dst_w <= (pipe->src_w / 4))
162 pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
163 else
164 pipe->op_mode |= MDP4_OP_SCALEY_FIR;
165 }
166
167 pipe->phasex_step = mdp4_scale_phase_step(29,
168 pipe->src_w, pipe->dst_w);
169 }
170}
171
172void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
173{
174 char *rgb_base;
175 uint32 src_size, src_xy, dst_size, dst_xy;
176 uint32 format, pattern;
177
178 rgb_base = MDP_BASE + MDP4_RGB_BASE;
179 rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
180
181 src_size = ((pipe->src_h << 16) | pipe->src_w);
182 src_xy = ((pipe->src_y << 16) | pipe->src_x);
183 dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
184 dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
185
186 format = mdp4_overlay_format(pipe);
187 pattern = mdp4_overlay_unpack_pattern(pipe);
188
189 pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
190
191 mdp4_scale_setup(pipe);
192
193 outpdw(rgb_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
194 outpdw(rgb_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
195 outpdw(rgb_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
196 outpdw(rgb_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
197
198 outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
199 outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
200
201 outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
202 outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */
203 outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
204 outpdw(rgb_base + 0x005c, pipe->phasex_step);
205 outpdw(rgb_base + 0x0060, pipe->phasey_step);
206
207 /* 16 bytes-burst x 3 req <= 48 bytes */
208 outpdw(rgb_base + 0x1004, 0xc2); /* MDP_RGB_FETCH_CFG */
209}
210
211void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
212{
213 char *vg_base;
214 uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
215 uint32 format, pattern;
216
217 vg_base = MDP_BASE + MDP4_VIDEO_BASE;
218 vg_base += (MDP4_VIDEO_OFF * pipe->pipe_num);
219
220 frame_size = ((pipe->src_height << 16) | pipe->src_width);
221 src_size = ((pipe->src_h << 16) | pipe->src_w);
222 src_xy = ((pipe->src_y << 16) | pipe->src_x);
223 dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
224 dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
225
226 format = mdp4_overlay_format(pipe);
227 pattern = mdp4_overlay_unpack_pattern(pipe);
228
229 pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR |
230 MDP4_OP_IGC_LUT_EN);
231
232 mdp4_scale_setup(pipe);
233
234 outpdw(vg_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
235 outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
236 outpdw(vg_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
237 outpdw(vg_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
238 outpdw(vg_base + 0x0048, frame_size); /* TILE frame size */
239
240 /* luma component plane */
241 outpdw(vg_base + 0x0010, pipe->srcp0_addr);
242
243 /* chroma component plane */
244 outpdw(vg_base + 0x0014, pipe->srcp1_addr);
245
246 outpdw(vg_base + 0x0040,
247 pipe->srcp1_ystride << 16 | pipe->srcp0_ystride);
248
249 outpdw(vg_base + 0x0050, format); /* MDP_RGB_SRC_FORMAT */
250 outpdw(vg_base + 0x0054, pattern); /* MDP_RGB_SRC_UNPACK_PATTERN */
251 outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
252 outpdw(vg_base + 0x005c, pipe->phasex_step);
253 outpdw(vg_base + 0x0060, pipe->phasey_step);
254
255 if (pipe->op_mode & MDP4_OP_DITHER_EN) {
256 outpdw(vg_base + 0x0068,
257 pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit);
258 }
259
260 /* 16 bytes-burst x 3 req <= 48 bytes */
261 outpdw(vg_base + 0x1004, 0xc2); /* MDP_VG_FETCH_CFG */
262}
263
264int mdp4_overlay_format2type(uint32 format)
265{
266 switch (format) {
267 case MDP_RGB_565:
268 case MDP_RGB_888:
269 case MDP_BGR_565:
270 case MDP_ARGB_8888:
271 case MDP_RGBA_8888:
272 case MDP_BGRA_8888:
273 return OVERLAY_TYPE_RGB;
274 case MDP_YCRYCB_H2V1:
275 case MDP_Y_CRCB_H2V1:
276 case MDP_Y_CBCR_H2V1:
277 case MDP_Y_CRCB_H2V2:
278 case MDP_Y_CBCR_H2V2:
279 case MDP_Y_CBCR_H2V2_TILE:
280 case MDP_Y_CRCB_H2V2_TILE:
281 return OVERLAY_TYPE_VG;
282 default:
283 return -ERANGE;
284 }
285
286}
287
288#define C3_ALPHA 3 /* alpha */
289#define C2_R_Cr 2 /* R/Cr */
290#define C1_B_Cb 1 /* B/Cb */
291#define C0_G_Y 0 /* G/luma */
292
293int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe)
294{
295 switch (pipe->src_format) {
296 case MDP_RGB_565:
297 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
298 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
299 pipe->a_bit = 0;
300 pipe->r_bit = 1; /* R, 5 bits */
301 pipe->b_bit = 1; /* B, 5 bits */
302 pipe->g_bit = 2; /* G, 6 bits */
303 pipe->alpha_enable = 0;
304 pipe->unpack_tight = 1;
305 pipe->unpack_align_msb = 0;
306 pipe->unpack_count = 2;
307 pipe->element2 = C2_R_Cr; /* R */
308 pipe->element1 = C0_G_Y; /* G */
309 pipe->element0 = C1_B_Cb; /* B */
310 pipe->bpp = 2; /* 2 bpp */
311 break;
312 case MDP_RGB_888:
313 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
314 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
315 pipe->a_bit = 0;
316 pipe->r_bit = 3; /* R, 8 bits */
317 pipe->b_bit = 3; /* B, 8 bits */
318 pipe->g_bit = 3; /* G, 8 bits */
319 pipe->alpha_enable = 0;
320 pipe->unpack_tight = 1;
321 pipe->unpack_align_msb = 0;
322 pipe->unpack_count = 2;
323 pipe->element2 = C2_R_Cr; /* R */
324 pipe->element1 = C0_G_Y; /* G */
325 pipe->element0 = C1_B_Cb; /* B */
326 pipe->bpp = 3; /* 3 bpp */
327 break;
328 case MDP_BGR_565:
329 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
330 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
331 pipe->a_bit = 0;
332 pipe->r_bit = 1; /* R, 5 bits */
333 pipe->b_bit = 1; /* B, 5 bits */
334 pipe->g_bit = 2; /* G, 6 bits */
335 pipe->alpha_enable = 0;
336 pipe->unpack_tight = 1;
337 pipe->unpack_align_msb = 0;
338 pipe->unpack_count = 2;
339 pipe->element2 = C1_B_Cb; /* B */
340 pipe->element1 = C0_G_Y; /* G */
341 pipe->element0 = C2_R_Cr; /* R */
342 pipe->bpp = 2; /* 2 bpp */
343 break;
344 case MDP_ARGB_8888:
345 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
346 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
347 pipe->a_bit = 3; /* alpha, 4 bits */
348 pipe->r_bit = 3; /* R, 8 bits */
349 pipe->b_bit = 3; /* B, 8 bits */
350 pipe->g_bit = 3; /* G, 8 bits */
351 pipe->alpha_enable = 1;
352 pipe->unpack_tight = 1;
353 pipe->unpack_align_msb = 0;
354 pipe->unpack_count = 3;
355 pipe->element3 = C3_ALPHA; /* alpha */
356 pipe->element2 = C2_R_Cr; /* R */
357 pipe->element1 = C0_G_Y; /* G */
358 pipe->element0 = C1_B_Cb; /* B */
359 pipe->bpp = 4; /* 4 bpp */
360 break;
361 case MDP_RGBA_8888:
362 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
363 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
364 pipe->a_bit = 3; /* alpha, 4 bits */
365 pipe->r_bit = 3; /* R, 8 bits */
366 pipe->b_bit = 3; /* B, 8 bits */
367 pipe->g_bit = 3; /* G, 8 bits */
368 pipe->alpha_enable = 1;
369 pipe->unpack_tight = 1;
370 pipe->unpack_align_msb = 0;
371 pipe->unpack_count = 3;
372 pipe->element3 = C2_R_Cr; /* R */
373 pipe->element2 = C0_G_Y; /* G */
374 pipe->element1 = C1_B_Cb; /* B */
375 pipe->element0 = C3_ALPHA; /* alpha */
376 pipe->bpp = 4; /* 4 bpp */
377 break;
378 case MDP_BGRA_8888:
379 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
380 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
381 pipe->a_bit = 3; /* alpha, 4 bits */
382 pipe->r_bit = 3; /* R, 8 bits */
383 pipe->b_bit = 3; /* B, 8 bits */
384 pipe->g_bit = 3; /* G, 8 bits */
385 pipe->alpha_enable = 1;
386 pipe->unpack_tight = 1;
387 pipe->unpack_align_msb = 0;
388 pipe->unpack_count = 3;
389 pipe->element3 = C1_B_Cb; /* B */
390 pipe->element2 = C0_G_Y; /* G */
391 pipe->element1 = C2_R_Cr; /* R */
392 pipe->element0 = C3_ALPHA; /* alpha */
393 pipe->bpp = 4; /* 4 bpp */
394 break;
395 case MDP_YCRYCB_H2V1:
396 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
397 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
398 pipe->a_bit = 0; /* alpha, 4 bits */
399 pipe->r_bit = 3; /* R, 8 bits */
400 pipe->b_bit = 3; /* B, 8 bits */
401 pipe->g_bit = 3; /* G, 8 bits */
402 pipe->alpha_enable = 0;
403 pipe->unpack_tight = 1;
404 pipe->unpack_align_msb = 0;
405 pipe->unpack_count = 3;
406 pipe->element3 = C0_G_Y; /* G */
407 pipe->element2 = C2_R_Cr; /* R */
408 pipe->element1 = C0_G_Y; /* G */
409 pipe->element0 = C1_B_Cb; /* B */
410 pipe->bpp = 2; /* 2 bpp */
411 pipe->chroma_sample = MDP4_CHROMA_H2V1;
412 break;
413 case MDP_Y_CRCB_H2V1:
414 case MDP_Y_CBCR_H2V1:
415 case MDP_Y_CRCB_H2V2:
416 case MDP_Y_CBCR_H2V2:
417 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
418 pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
419 pipe->a_bit = 0;
420 pipe->r_bit = 3; /* R, 8 bits */
421 pipe->b_bit = 3; /* B, 8 bits */
422 pipe->g_bit = 3; /* G, 8 bits */
423 pipe->alpha_enable = 0;
424 pipe->unpack_tight = 1;
425 pipe->unpack_align_msb = 0;
426 pipe->unpack_count = 1; /* 2 */
427 pipe->element3 = C0_G_Y; /* not used */
428 pipe->element2 = C0_G_Y; /* not used */
429 if (pipe->src_format == MDP_Y_CRCB_H2V1) {
430 pipe->element1 = C2_R_Cr; /* R */
431 pipe->element0 = C1_B_Cb; /* B */
432 pipe->chroma_sample = MDP4_CHROMA_H2V1;
433 } else if (pipe->src_format == MDP_Y_CBCR_H2V1) {
434 pipe->element1 = C1_B_Cb; /* B */
435 pipe->element0 = C2_R_Cr; /* R */
436 pipe->chroma_sample = MDP4_CHROMA_H2V1;
437 } else if (pipe->src_format == MDP_Y_CRCB_H2V2) {
438 pipe->element1 = C2_R_Cr; /* R */
439 pipe->element0 = C1_B_Cb; /* B */
440 pipe->chroma_sample = MDP4_CHROMA_420;
441 } else if (pipe->src_format == MDP_Y_CBCR_H2V2) {
442 pipe->element1 = C1_B_Cb; /* B */
443 pipe->element0 = C2_R_Cr; /* R */
444 pipe->chroma_sample = MDP4_CHROMA_420;
445 }
446 pipe->bpp = 2; /* 2 bpp */
447 break;
448 case MDP_Y_CBCR_H2V2_TILE:
449 case MDP_Y_CRCB_H2V2_TILE:
450 pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE;
451 pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
452 pipe->a_bit = 0;
453 pipe->r_bit = 3; /* R, 8 bits */
454 pipe->b_bit = 3; /* B, 8 bits */
455 pipe->g_bit = 3; /* G, 8 bits */
456 pipe->alpha_enable = 0;
457 pipe->unpack_tight = 1;
458 pipe->unpack_align_msb = 0;
459 pipe->unpack_count = 1; /* 2 */
460 pipe->element3 = C0_G_Y; /* not used */
461 pipe->element2 = C0_G_Y; /* not used */
462 if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) {
463 pipe->element1 = C2_R_Cr; /* R */
464 pipe->element0 = C1_B_Cb; /* B */
465 pipe->chroma_sample = MDP4_CHROMA_420;
466 } else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) {
467 pipe->element1 = C1_B_Cb; /* B */
468 pipe->element0 = C2_R_Cr; /* R */
469 pipe->chroma_sample = MDP4_CHROMA_420;
470 }
471 pipe->bpp = 2; /* 2 bpp */
472 break;
473 default:
474 /* not likely */
475 return -ERANGE;
476 }
477
478 return 0;
479}
480
481/*
482 * color_key_convert: output with 12 bits color key
483 */
484static uint32 color_key_convert(int start, int num, uint32 color)
485{
486
487 uint32 data;
488
489 data = (color >> start) & ((1 << num) - 1);
490
491 if (num == 5)
492 data = (data << 7) + (data << 2) + (data >> 3);
493 else if (num == 6)
494 data = (data << 6) + data;
495 else /* 8 bits */
496 data = (data << 4) + (data >> 4);
497
498 return data;
499
500}
501
502void transp_color_key(int format, uint32 transp,
503 uint32 *c0, uint32 *c1, uint32 *c2)
504{
505 int b_start, g_start, r_start;
506 int b_num, g_num, r_num;
507
508 switch (format) {
509 case MDP_RGB_565:
510 b_start = 0;
511 g_start = 5;
512 r_start = 11;
513 r_num = 5;
514 g_num = 6;
515 b_num = 5;
516 break;
517 case MDP_RGB_888:
518 case MDP_XRGB_8888:
519 case MDP_ARGB_8888:
520 b_start = 0;
521 g_start = 8;
522 r_start = 16;
523 r_num = 8;
524 g_num = 8;
525 b_num = 8;
526 break;
527 case MDP_BGR_565:
528 b_start = 11;
529 g_start = 5;
530 r_start = 0;
531 r_num = 5;
532 g_num = 6;
533 b_num = 5;
534 break;
535 case MDP_Y_CBCR_H2V2:
536 case MDP_Y_CBCR_H2V1:
537 b_start = 8;
538 g_start = 16;
539 r_start = 0;
540 r_num = 8;
541 g_num = 8;
542 b_num = 8;
543 break;
544 case MDP_Y_CRCB_H2V2:
545 case MDP_Y_CRCB_H2V1:
546 b_start = 0;
547 g_start = 16;
548 r_start = 8;
549 r_num = 8;
550 g_num = 8;
551 b_num = 8;
552 break;
553 default:
554 b_start = 0;
555 g_start = 8;
556 r_start = 16;
557 r_num = 8;
558 g_num = 8;
559 b_num = 8;
560 break;
561 }
562
563 *c0 = color_key_convert(g_start, g_num, transp);
564 *c1 = color_key_convert(b_start, b_num, transp);
565 *c2 = color_key_convert(r_start, r_num, transp);
566}
567
568uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
569{
570 uint32 format;
571
572 format = 0;
573
574 if (pipe->solid_fill)
575 format |= MDP4_FORMAT_SOLID_FILL;
576
577 if (pipe->unpack_align_msb)
578 format |= MDP4_FORMAT_UNPACK_ALIGN_MSB;
579
580 if (pipe->unpack_tight)
581 format |= MDP4_FORMAT_UNPACK_TIGHT;
582
583 if (pipe->alpha_enable)
584 format |= MDP4_FORMAT_ALPHA_ENABLE;
585
586 format |= (pipe->unpack_count << 13);
587 format |= ((pipe->bpp - 1) << 9);
588 format |= (pipe->a_bit << 6);
589 format |= (pipe->r_bit << 4);
590 format |= (pipe->b_bit << 2);
591 format |= pipe->g_bit;
592
593 format |= (pipe->frame_format << 29);
594
595 if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
596 /* video/graphic */
597 format |= (pipe->fetch_plane << 19);
598 format |= (pipe->chroma_site << 28);
599 format |= (pipe->chroma_sample << 26);
600 }
601
602 return format;
603}
604
605uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
606{
607 return (pipe->element3 << 24) | (pipe->element2 << 16) |
608 (pipe->element1 << 8) | pipe->element0;
609}
610
611void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe)
612{
613 uint32 data;
614 char *overlay_base;
615
616 if (pipe->mixer_num == MDP4_MIXER1)
617 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
618 else
619 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
620
621 /* MDP_OVERLAYPROC_CFG */
622 outpdw(overlay_base + 0x0004, 0x01); /* directout */
623 data = pipe->src_height;
624 data <<= 16;
625 data |= pipe->src_width;
626 outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
627 outpdw(overlay_base + 0x000c, pipe->srcp0_addr);
628 outpdw(overlay_base + 0x0010, pipe->srcp0_ystride);
629 outpdw(overlay_base + 0x0014, 0x4); /* GC_LUT_EN, 888 */
630}
631
632int mdp4_overlay_active(int mixer)
633{
634 uint32 data, mask, i;
635 int p1, p2;
636
637 data = inpdw(MDP_BASE + 0x10100);
638 p1 = 0;
639 p2 = 0;
640 for (i = 0; i < 8; i++) {
641 mask = data & 0x0f;
642 if (mask) {
643 if (mask <= 4)
644 p1++;
645 else
646 p2++;
647 }
648 data >>= 4;
649 }
650
651 if (mixer)
652 return p2;
653 else
654 return p1;
655}
656
657void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
658{
659 uint32 data, mask, snum, stage, mixer;
660
661 stage = pipe->mixer_stage;
662 mixer = pipe->mixer_num;
663
664 /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
665 data = inpdw(MDP_BASE + 0x10100);
666
667 if (mixer == MDP4_MIXER1)
668 stage += 8;
669
670 if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */
671 snum = 0;
672 snum += (4 * pipe->pipe_num);
673 } else {
674 snum = 8;
675 snum += (4 * pipe->pipe_num); /* RGB1 and RGB2 */
676 }
677
678 mask = 0x0f;
679 mask <<= snum;
680 stage <<= snum;
681 data &= ~mask; /* clear old bits */
682
683 data |= stage;
684
685 outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
686
687 data = inpdw(MDP_BASE + 0x10100);
688
689 ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe; /* keep it */
690}
691
692void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe)
693{
694 uint32 data, mask, snum, stage, mixer;
695
696 stage = pipe->mixer_stage;
697 mixer = pipe->mixer_num;
698
699 if (pipe != ctrl->stage[mixer][stage]) /* not runing */
700 return;
701
702 /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
703 data = inpdw(MDP_BASE + 0x10100);
704
705 if (mixer == MDP4_MIXER1)
706 stage += 8;
707
708 if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */
709 snum = 0;
710 snum += (4 * pipe->pipe_num);
711 } else {
712 snum = 8;
713 snum += (4 * pipe->pipe_num); /* RGB1 and RGB2 */
714 }
715
716 mask = 0x0f;
717 mask <<= snum;
718 data &= ~mask; /* clear old bits */
719
720 outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
721
722 data = inpdw(MDP_BASE + 0x10100);
723
724 ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL; /* clear it */
725}
726
727void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
728{
729 unsigned char *overlay_base;
730 uint32 c0, c1, c2, blend_op;
731 int off;
732
733 if (pipe->mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */
734 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
735 else
736 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
737
738 /* stage 0 to stage 2 */
739 off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
740
741 blend_op = 0;
742 if (pipe->alpha_enable) /* ARGB */
743 blend_op = MDP4_BLEND_FG_ALPHA_FG_PIXEL |
744 MDP4_BLEND_BG_ALPHA_FG_PIXEL;
745 else
746 blend_op = (MDP4_BLEND_BG_ALPHA_BG_CONST |
747 MDP4_BLEND_FG_ALPHA_FG_CONST);
748
749
750 if (pipe->alpha_enable == 0) { /* not ARGB */
751 if (pipe->is_fg) {
752 outpdw(overlay_base + off + 0x108, pipe->alpha);
753 outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha);
754 } else {
755 outpdw(overlay_base + off + 0x108, 0xff - pipe->alpha);
756 outpdw(overlay_base + off + 0x10c, pipe->alpha);
757 }
758 }
759
760 if (pipe->transp != MDP_TRANSP_NOP) {
761 transp_color_key(pipe->src_format, pipe->transp, &c0, &c1, &c2);
762 if (pipe->is_fg) {
763 blend_op |= MDP4_BLEND_FG_TRANSP_EN; /* Fg blocked */
764 /* lower limit */
765 if (c0 > 0x10)
766 c0 -= 0x10;
767 if (c1 > 0x10)
768 c1 -= 0x10;
769 if (c2 > 0x10)
770 c2 -= 0x10;
771 outpdw(overlay_base + off + 0x110,
772 (c1 << 16 | c0));/* low */
773 outpdw(overlay_base + off + 0x114, c2);/* low */
774 /* upper limit */
775 if ((c0 + 0x20) < 0x0fff)
776 c0 += 0x20;
777 else
778 c0 = 0x0fff;
779 if ((c1 + 0x20) < 0x0fff)
780 c1 += 0x20;
781 else
782 c1 = 0x0fff;
783 if ((c2 + 0x20) < 0x0fff)
784 c2 += 0x20;
785 else
786 c2 = 0x0fff;
787 outpdw(overlay_base + off + 0x118,
788 (c1 << 16 | c0));/* high */
789 outpdw(overlay_base + off + 0x11c, c2);/* high */
790 } else {
791 blend_op |= MDP4_BLEND_BG_TRANSP_EN; /* bg blocked */
792 /* lower limit */
793 if (c0 > 0x10)
794 c0 -= 0x10;
795 if (c1 > 0x10)
796 c1 -= 0x10;
797 if (c2 > 0x10)
798 c2 -= 0x10;
799 outpdw(overlay_base + 0x180,
800 (c1 << 16 | c0));/* low */
801 outpdw(overlay_base + 0x184, c2);/* low */
802 /* upper limit */
803 if ((c0 + 0x20) < 0x0fff)
804 c0 += 0x20;
805 else
806 c0 = 0x0fff;
807 if ((c1 + 0x20) < 0x0fff)
808 c1 += 0x20;
809 else
810 c1 = 0x0fff;
811 if ((c2 + 0x20) < 0x0fff)
812 c2 += 0x20;
813 else
814 c2 = 0x0fff;
815 outpdw(overlay_base + 0x188,
816 (c1 << 16 | c0));/* high */
817 outpdw(overlay_base + 0x18c, c2);/* high */
818 }
819 }
820 outpdw(overlay_base + off + 0x104, blend_op);
821}
822
823void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
824{
825 uint32 bits = 0;
826
827 if (pipe->mixer_num == MDP4_MIXER1)
828 bits |= 0x02;
829 else
830 bits |= 0x01;
831
832 if (all) {
833 if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
834 if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
835 bits |= 0x20;
836 else
837 bits |= 0x10;
838 } else {
839 if (pipe->pipe_num == OVERLAY_PIPE_VG2)
840 bits |= 0x08;
841 else
842 bits |= 0x04;
843 }
844 }
845
846 outpdw(MDP_BASE + 0x18000, bits); /* MDP_OVERLAY_REG_FLUSH */
847
848 while (inpdw(MDP_BASE + 0x18000) & bits) /* self clear when complete */
849 ;
850}
851
852struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx)
853{
854 struct mdp4_overlay_pipe *pipe;
855
856 if (ndx == 0 || ndx >= MDP4_MAX_OVERLAY_PIPE)
857 return NULL;
858
859 pipe = &ctrl->plist[ndx - 1]; /* ndx start from 1 */
860
861 if (pipe->pipe_ndx == 0)
862 return NULL;
863
864 return pipe;
865}
866
867struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void)
868{
869 int i;
870 struct mdp4_overlay_pipe *pipe;
871
872 pipe = &ctrl->plist[0];
873 for (i = 0; i < MDP4_MAX_OVERLAY_PIPE; i++) {
874 if (pipe->pipe_ndx == 0) {
875 pipe->pipe_ndx = i + 1; /* start from 1 */
876 init_completion(&pipe->comp);
877 printk(KERN_INFO "mdp4_overlay_pipe_alloc: pipe=%x ndx=%d\n",
878 (int)pipe, pipe->pipe_ndx);
879 return pipe;
880 }
881 pipe++;
882 }
883
884 return NULL;
885}
886
887
888void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
889{
890 printk(KERN_INFO "mdp4_overlay_pipe_free: pipe=%x ndx=%d\n",
891 (int)pipe, pipe->pipe_ndx);
892 memset(pipe, 0, sizeof(*pipe));
893}
894
895static int get_pipe_num(int ptype, int stage)
896{
897 if (ptype == OVERLAY_TYPE_RGB) {
898 if (stage == MDP4_MIXER_STAGE_BASE)
899 return OVERLAY_PIPE_RGB1;
900 else
901 return OVERLAY_PIPE_RGB2;
902 } else {
903 if (stage == MDP4_MIXER_STAGE0)
904 return OVERLAY_PIPE_VG1;
905 else
906 return OVERLAY_PIPE_VG2;
907 }
908}
909
910int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer)
911{
912 struct mdp4_overlay_pipe *pipe;
913
914 pipe = ctrl->stage[mixer][z_order];
915
916 if (pipe == NULL)
917 return 0;
918
919 if (pipe->pipe_ndx == id) /* same req, recycle */
920 return 0;
921
922 return -EPERM;
923}
924
925static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
926 struct mdp4_overlay_pipe **ppipe)
927{
928 struct mdp4_overlay_pipe *pipe;
929 int ret, ptype;
930
931 if (mixer >= MDP4_MAX_MIXER) {
932 printk(KERN_ERR "mpd_overlay_req2pipe: mixer out of range!\n");
933 return -ERANGE;
934 }
935
936 if (req->z_order < 0 || req->z_order > 2) {
937 printk(KERN_ERR "mpd_overlay_req2pipe: z_order=%d out of range!\n",
938 req->z_order);
939 return -ERANGE;
940 }
941
942 if (req->src_rect.h == 0 || req->src_rect.w == 0) {
943 printk(KERN_ERR "mpd_overlay_req2pipe: src img of zero size!\n");
944 return -EINVAL;
945 }
946
947 ret = mdp4_overlay_req_check(req->id, req->z_order, mixer);
948 if (ret < 0)
949 return ret;
950
951 ptype = mdp4_overlay_format2type(req->src.format);
952 if (ptype < 0)
953 return ptype;
954
955 if (req->id == MSMFB_NEW_REQUEST) /* new request */
956 pipe = mdp4_overlay_pipe_alloc();
957 else
958 pipe = mdp4_overlay_ndx2pipe(req->id);
959
960 if (pipe == NULL)
961 return -ENOMEM;
962
963 pipe->src_format = req->src.format;
964 ret = mdp4_overlay_format2pipe(pipe);
965
966 if (ret < 0)
967 return ret;
968
969 /*
970 * base layer == 1, reserved for frame buffer
971 * zorder 0 == stage 0 == 2
972 * zorder 1 == stage 1 == 3
973 * zorder 2 == stage 2 == 4
974 */
975 if (req->id == MSMFB_NEW_REQUEST) { /* new request */
976 pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
977 pipe->pipe_type = ptype;
978 pipe->pipe_num = get_pipe_num(ptype, pipe->mixer_stage);
979 printk(KERN_INFO "mpd4_overlay_req2pipe: zorder=%d pipe_num=%d\n",
980 req->z_order, pipe->pipe_num);
981 }
982
983 pipe->src_width = req->src.width & 0x07ff; /* source img width */
984 pipe->src_height = req->src.height & 0x07ff; /* source img height */
985 pipe->src_h = req->src_rect.h & 0x07ff;
986 pipe->src_w = req->src_rect.w & 0x07ff;
987 pipe->src_y = req->src_rect.y & 0x07ff;
988 pipe->src_x = req->src_rect.x & 0x07ff;
989 pipe->dst_h = req->dst_rect.h & 0x07ff;
990 pipe->dst_w = req->dst_rect.w & 0x07ff;
991 pipe->dst_y = req->dst_rect.y & 0x07ff;
992 pipe->dst_x = req->dst_rect.x & 0x07ff;
993
994 if (req->flags & MDP_FLIP_LR)
995 pipe->op_mode |= MDP4_OP_FLIP_LR;
996
997 if (req->flags & MDP_FLIP_UD)
998 pipe->op_mode |= MDP4_OP_FLIP_UD;
999
1000 if (req->flags & MDP_DITHER)
1001 pipe->op_mode |= MDP4_OP_DITHER_EN;
1002
1003 if (req->flags & MDP_DEINTERLACE)
1004 pipe->op_mode |= MDP4_OP_DEINT_ODD_REF;
1005
1006 pipe->is_fg = req->is_fg;/* control alpha and color key */
1007
1008 pipe->alpha = req->alpha & 0x0ff;
1009
1010 pipe->transp = req->transp_mask;
1011
1012 *ppipe = pipe;
1013
1014 return 0;
1015}
1016
1017int get_img(struct msmfb_data *img, struct fb_info *info,
1018 unsigned long *start, unsigned long *len, struct file **pp_file)
1019{
1020 int put_needed, ret = 0;
1021 struct file *file;
1022#ifdef CONFIG_ANDROID_PMEM
1023 unsigned long vstart;
1024#endif
1025
1026#ifdef CONFIG_ANDROID_PMEM
1027 if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
1028 return 0;
1029#endif
1030 file = fget_light(img->memory_id, &put_needed);
1031 if (file == NULL)
1032 return -1;
1033
1034 if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
1035 *start = info->fix.smem_start;
1036 *len = info->fix.smem_len;
1037 *pp_file = file;
1038 } else {
1039 ret = -1;
1040 fput_light(file, put_needed);
1041 }
1042 return ret;
1043}
1044int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
1045{
1046 struct mdp4_overlay_pipe *pipe;
1047
1048 pipe = mdp4_overlay_ndx2pipe(req->id);
1049 if (pipe == NULL)
1050 return -ENODEV;
1051
1052 *req = pipe->req_data;
1053
1054 return 0;
1055}
1056
1057int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
1058{
1059 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1060 int ret, mixer;
1061 struct mdp4_overlay_pipe *pipe;
1062 int lcdc;
1063
1064 if (mfd == NULL)
1065 return -ENODEV;
1066
1067 if (req->src.format == MDP_FB_FORMAT)
1068 req->src.format = mfd->fb_imgType;
1069
1070 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1071 return -EINTR;
1072
1073 mixer = info->node; /* minor number of char device */
1074
1075 ret = mdp4_overlay_req2pipe(req, mixer, &pipe);
1076 if (ret < 0) {
1077 mutex_unlock(&mfd->dma->ov_mutex);
1078 return ret;
1079 }
1080
1081 lcdc = inpdw(MDP_BASE + 0xc0000);
1082
1083 if (lcdc == 0) { /* mddi */
1084 /* MDP cmd block enable */
1085 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1086 }
1087
1088 /* return id back to user */
1089 req->id = pipe->pipe_ndx; /* pipe_ndx start from 1 */
1090 pipe->req_data = *req; /* keep original req */
1091
1092 mutex_unlock(&mfd->dma->ov_mutex);
1093
1094 return 0;
1095}
1096
1097int mdp4_overlay_unset(struct fb_info *info, int ndx)
1098{
1099 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1100 struct mdp4_overlay_pipe *pipe;
1101 int lcdc;
1102
1103 if (mfd == NULL)
1104 return -ENODEV;
1105
1106 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1107 return -EINTR;
1108
1109 pipe = mdp4_overlay_ndx2pipe(ndx);
1110
1111 if (pipe == NULL) {
1112 mutex_unlock(&mfd->dma->ov_mutex);
1113 return -ENODEV;
1114 }
1115
1116 lcdc = inpdw(MDP_BASE + 0xc0000);
1117
1118 mdp4_mixer_stage_down(pipe);
1119
1120 if (lcdc == 0) { /* mddi */
1121 /* MDP cmd block disable */
1122 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1123 }
1124
1125 if (lcdc) /* LCDC mode */
1126 mdp4_overlay_reg_flush(pipe, 0);
1127
1128 mdp4_overlay_pipe_free(pipe);
1129
1130 if (lcdc == 0) { /* mddi */
1131 mdp4_mddi_overlay_restore();
1132 }
1133
1134 mutex_unlock(&mfd->dma->ov_mutex);
1135
1136 return 0;
1137}
1138
1139struct tile_desc {
1140 uint32 width; /* tile's width */
1141 uint32 height; /* tile's height */
1142 uint32 row_tile_w; /* tiles per row's width */
1143 uint32 row_tile_h; /* tiles per row's height */
1144};
1145
1146void tile_samsung(struct tile_desc *tp)
1147{
1148 /*
1149 * each row of samsung tile consists of two tiles in height
1150 * and two tiles in width which means width should align to
1151 * 64 x 2 bytes and height should align to 32 x 2 bytes.
1152 * video decoder generate two tiles in width and one tile
1153 * in height which ends up height align to 32 X 1 bytes.
1154 */
1155 tp->width = 64; /* 64 bytes */
1156 tp->row_tile_w = 2; /* 2 tiles per row's width */
1157 tp->height = 32; /* 32 bytes */
1158 tp->row_tile_h = 1; /* 1 tiles per row's height */
1159}
1160
1161uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
1162{
1163 uint32 tile_w, tile_h;
1164 uint32 row_num_w, row_num_h;
1165
1166
1167 tile_w = tp->width * tp->row_tile_w;
1168 tile_h = tp->height * tp->row_tile_h;
1169
1170 row_num_w = (pipe->src_width + tile_w - 1) / tile_w;
1171 row_num_h = (pipe->src_height + tile_h - 1) / tile_h;
1172
1173 return row_num_w * row_num_h * tile_w * tile_h;
1174}
1175
1176int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
1177 struct file **pp_src_file)
1178{
1179 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1180 struct msmfb_data *img;
1181 struct mdp4_overlay_pipe *pipe;
1182 ulong start, addr;
1183 ulong len = 0;
1184 struct file *p_src_file = 0;
1185 int lcdc;
1186
1187 if (mfd == NULL)
1188 return -ENODEV;
1189
1190 pipe = mdp4_overlay_ndx2pipe(req->id);
1191 if (pipe == NULL)
1192 return -ENODEV;
1193
1194 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1195 return -EINTR;
1196
1197 img = &req->data;
1198 get_img(img, info, &start, &len, &p_src_file);
1199 if (len == 0) {
1200 mutex_unlock(&mfd->dma->ov_mutex);
1201 printk(KERN_ERR "mdp_overlay_play: could not retrieve"
1202 " image from memory\n");
1203 return -1;
1204 }
1205 *pp_src_file = p_src_file;
1206
1207 addr = start + img->offset;
1208 pipe->srcp0_addr = addr;
1209 pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
1210
1211 if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
1212 if (pipe->frame_format == MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
1213 struct tile_desc tile;
1214
1215 tile_samsung(&tile);
1216 pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile);
1217 } else
1218 pipe->srcp1_addr = addr +
1219 pipe->src_width * pipe->src_height;
1220
1221 pipe->srcp0_ystride = pipe->src_width;
1222 pipe->srcp1_ystride = pipe->src_width;
1223 }
1224
1225 lcdc = inpdw(MDP_BASE + 0xc0000);
1226 lcdc &= 0x01; /* LCDC mode */
1227
1228 if (pipe->pipe_type == OVERLAY_TYPE_VG)
1229 mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */
1230 else
1231 mdp4_overlay_rgb_setup(pipe); /* rgb pipe */
1232
1233 mdp4_mixer_blend_setup(pipe);
1234 mdp4_mixer_stage_up(pipe);
1235
1236 if (lcdc) { /* LCDC mode */
1237 mdp4_overlay_reg_flush(pipe, 1);
1238 }
1239
1240 if (lcdc) { /* LCDC mode */
1241 if (pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) { /* done */
1242 mutex_unlock(&mfd->dma->ov_mutex);
1243 return 0;
1244 }
1245 }
1246
1247 if (lcdc == 0) { /* MDDI mode */
1248#ifdef MDP4_NONBLOCKING
1249 if (mfd->panel_power_on)
1250#else
1251 if (!mfd->dma->busy && mfd->panel_power_on)
1252#endif
1253 mdp4_mddi_overlay_kickoff(mfd, pipe);
1254 }
1255
1256 mutex_unlock(&mfd->dma->ov_mutex);
1257
1258 return 0;
1259}
diff --git a/drivers/staging/msm/mdp4_overlay_lcdc.c b/drivers/staging/msm/mdp4_overlay_lcdc.c
new file mode 100644
index 000000000000..a6ab8ec83f55
--- /dev/null
+++ b/drivers/staging/msm/mdp4_overlay_lcdc.c
@@ -0,0 +1,313 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/hrtimer.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/spinlock.h>
33
34#include <linux/fb.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38#include "mdp4.h"
39
40#ifdef CONFIG_FB_MSM_MDP40
41#define LCDC_BASE 0xC0000
42#else
43#define LCDC_BASE 0xE0000
44#endif
45
46int first_pixel_start_x;
47int first_pixel_start_y;
48
49static struct mdp4_overlay_pipe *lcdc_pipe;
50
51int mdp_lcdc_on(struct platform_device *pdev)
52{
53 int lcdc_width;
54 int lcdc_height;
55 int lcdc_bpp;
56 int lcdc_border_clr;
57 int lcdc_underflow_clr;
58 int lcdc_hsync_skew;
59
60 int hsync_period;
61 int hsync_ctrl;
62 int vsync_period;
63 int display_hctl;
64 int display_v_start;
65 int display_v_end;
66 int active_hctl;
67 int active_h_start;
68 int active_h_end;
69 int active_v_start;
70 int active_v_end;
71 int ctrl_polarity;
72 int h_back_porch;
73 int h_front_porch;
74 int v_back_porch;
75 int v_front_porch;
76 int hsync_pulse_width;
77 int vsync_pulse_width;
78 int hsync_polarity;
79 int vsync_polarity;
80 int data_en_polarity;
81 int hsync_start_x;
82 int hsync_end_x;
83 uint8 *buf;
84 int bpp, ptype;
85 uint32 format;
86 struct fb_info *fbi;
87 struct fb_var_screeninfo *var;
88 struct msm_fb_data_type *mfd;
89 struct mdp4_overlay_pipe *pipe;
90 int ret;
91
92 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
93
94 if (!mfd)
95 return -ENODEV;
96
97 if (mfd->key != MFD_KEY)
98 return -EINVAL;
99
100 fbi = mfd->fbi;
101 var = &fbi->var;
102
103 /* MDP cmd block enable */
104 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
105
106 bpp = fbi->var.bits_per_pixel / 8;
107 buf = (uint8 *) fbi->fix.smem_start;
108 buf += fbi->var.xoffset * bpp +
109 fbi->var.yoffset * fbi->fix.line_length;
110
111 if (bpp == 2)
112 format = MDP_RGB_565;
113 else if (bpp == 3)
114 format = MDP_RGB_888;
115 else
116 format = MDP_ARGB_8888;
117
118
119 if (lcdc_pipe == NULL) {
120 ptype = mdp4_overlay_format2type(format);
121 pipe = mdp4_overlay_pipe_alloc();
122 pipe->pipe_type = ptype;
123 /* use RGB1 pipe */
124 pipe->pipe_num = OVERLAY_PIPE_RGB1;
125 pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
126 pipe->mixer_num = MDP4_MIXER0;
127 pipe->src_format = format;
128 mdp4_overlay_format2pipe(pipe);
129
130 lcdc_pipe = pipe; /* keep it */
131 } else {
132 pipe = lcdc_pipe;
133 }
134
135 pipe->src_height = fbi->var.yres;
136 pipe->src_width = fbi->var.xres;
137 pipe->src_h = fbi->var.yres;
138 pipe->src_w = fbi->var.xres;
139 pipe->src_y = 0;
140 pipe->src_x = 0;
141 pipe->srcp0_addr = (uint32) buf;
142 pipe->srcp0_ystride = fbi->fix.line_length;
143
144 mdp4_overlay_dmap_xy(pipe);
145 mdp4_overlay_dmap_cfg(mfd, 1);
146
147 mdp4_overlay_rgb_setup(pipe);
148
149 mdp4_mixer_stage_up(pipe);
150
151 mdp4_overlayproc_cfg(pipe);
152
153 /*
154 * LCDC timing setting
155 */
156 h_back_porch = var->left_margin;
157 h_front_porch = var->right_margin;
158 v_back_porch = var->upper_margin;
159 v_front_porch = var->lower_margin;
160 hsync_pulse_width = var->hsync_len;
161 vsync_pulse_width = var->vsync_len;
162 lcdc_border_clr = mfd->panel_info.lcdc.border_clr;
163 lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
164 lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
165
166 lcdc_width = mfd->panel_info.xres;
167 lcdc_height = mfd->panel_info.yres;
168 lcdc_bpp = mfd->panel_info.bpp;
169
170 hsync_period =
171 hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch;
172 hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
173 hsync_start_x = hsync_pulse_width + h_back_porch;
174 hsync_end_x = hsync_period - h_front_porch - 1;
175 display_hctl = (hsync_end_x << 16) | hsync_start_x;
176
177 vsync_period =
178 (vsync_pulse_width + v_back_porch + lcdc_height +
179 v_front_porch) * hsync_period;
180 display_v_start =
181 (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew;
182 display_v_end =
183 vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1;
184
185 if (lcdc_width != var->xres) {
186 active_h_start = hsync_start_x + first_pixel_start_x;
187 active_h_end = active_h_start + var->xres - 1;
188 active_hctl =
189 ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
190 } else {
191 active_hctl = 0;
192 }
193
194 if (lcdc_height != var->yres) {
195 active_v_start =
196 display_v_start + first_pixel_start_y * hsync_period;
197 active_v_end = active_v_start + (var->yres) * hsync_period - 1;
198 active_v_start |= ACTIVE_START_Y_EN;
199 } else {
200 active_v_start = 0;
201 active_v_end = 0;
202 }
203
204
205#ifdef CONFIG_FB_MSM_MDP40
206 hsync_polarity = 1;
207 vsync_polarity = 1;
208 lcdc_underflow_clr |= 0x80000000; /* enable recovery */
209#else
210 hsync_polarity = 0;
211 vsync_polarity = 0;
212#endif
213 data_en_polarity = 0;
214
215 ctrl_polarity =
216 (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);
217
218 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x4, hsync_ctrl);
219 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x8, vsync_period);
220 MDP_OUTP(MDP_BASE + LCDC_BASE + 0xc, vsync_pulse_width * hsync_period);
221 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x10, display_hctl);
222 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x14, display_v_start);
223 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x18, display_v_end);
224 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x28, lcdc_border_clr);
225 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x2c, lcdc_underflow_clr);
226 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x30, lcdc_hsync_skew);
227 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x38, ctrl_polarity);
228 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x1c, active_hctl);
229 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start);
230 MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end);
231
232 ret = panel_next_on(pdev);
233 if (ret == 0) {
234 /* enable LCDC block */
235 MDP_OUTP(MDP_BASE + LCDC_BASE, 1);
236 mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
237 }
238 /* MDP cmd block disable */
239 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
240
241 return ret;
242}
243
244int mdp_lcdc_off(struct platform_device *pdev)
245{
246 int ret = 0;
247 struct mdp4_overlay_pipe *pipe;
248
249 /* MDP cmd block enable */
250 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
251 MDP_OUTP(MDP_BASE + LCDC_BASE, 0);
252 /* MDP cmd block disable */
253 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
254 mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
255
256 ret = panel_next_off(pdev);
257
258 /* delay to make sure the last frame finishes */
259 mdelay(100);
260
261 /* dis-engage rgb0 from mixer */
262 pipe = lcdc_pipe;
263 mdp4_mixer_stage_down(pipe);
264
265 return ret;
266}
267
268/*
269 * mdp4_overlay0_done_lcdc: called from isr
270 */
271void mdp4_overlay0_done_lcdc()
272{
273 complete(&lcdc_pipe->comp);
274}
275
276void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd)
277{
278 struct fb_info *fbi = mfd->fbi;
279 uint8 *buf;
280 int bpp;
281 unsigned long flag;
282 struct mdp4_overlay_pipe *pipe;
283
284 if (!mfd->panel_power_on)
285 return;
286
287 /* no need to power on cmd block since it's lcdc mode */
288 bpp = fbi->var.bits_per_pixel / 8;
289 buf = (uint8 *) fbi->fix.smem_start;
290 buf += fbi->var.xoffset * bpp +
291 fbi->var.yoffset * fbi->fix.line_length;
292
293 mutex_lock(&mfd->dma->ov_mutex);
294
295 pipe = lcdc_pipe;
296 pipe->srcp0_addr = (uint32) buf;
297 mdp4_overlay_rgb_setup(pipe);
298 mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */
299
300 /* enable irq */
301 spin_lock_irqsave(&mdp_spin_lock, flag);
302 mdp_enable_irq(MDP_OVERLAY0_TERM);
303 INIT_COMPLETION(lcdc_pipe->comp);
304 mfd->dma->waiting = TRUE;
305 outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
306 mdp_intr_mask |= INTR_OVERLAY0_DONE;
307 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
308 spin_unlock_irqrestore(&mdp_spin_lock, flag);
309 wait_for_completion_killable(&lcdc_pipe->comp);
310 mdp_disable_irq(MDP_OVERLAY0_TERM);
311
312 mutex_unlock(&mfd->dma->ov_mutex);
313}
diff --git a/drivers/staging/msm/mdp4_overlay_mddi.c b/drivers/staging/msm/mdp4_overlay_mddi.c
new file mode 100644
index 000000000000..be1b2874185b
--- /dev/null
+++ b/drivers/staging/msm/mdp4_overlay_mddi.c
@@ -0,0 +1,254 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/hrtimer.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/spinlock.h>
33
34#include <linux/fb.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38#include "mdp4.h"
39
40static struct mdp4_overlay_pipe *mddi_pipe;
41static struct mdp4_overlay_pipe *pending_pipe;
42static struct msm_fb_data_type *mddi_mfd;
43
44#define WHOLESCREEN
45
46void mdp4_overlay_update_lcd(struct msm_fb_data_type *mfd)
47{
48 MDPIBUF *iBuf = &mfd->ibuf;
49 uint8 *src;
50 int bpp, ptype;
51 uint32 format;
52 uint32 mddi_ld_param;
53 uint16 mddi_vdo_packet_reg;
54 struct mdp4_overlay_pipe *pipe;
55
56 if (mfd->key != MFD_KEY)
57 return;
58
59 mddi_mfd = mfd; /* keep it */
60
61 bpp = iBuf->bpp;
62
63 if (bpp == 2)
64 format = MDP_RGB_565;
65 else if (bpp == 3)
66 format = MDP_RGB_888;
67 else
68 format = MDP_ARGB_8888;
69
70 /* MDP cmd block enable */
71 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
72
73 if (mddi_pipe == NULL) {
74 ptype = mdp4_overlay_format2type(format);
75 pipe = mdp4_overlay_pipe_alloc();
76 pipe->pipe_type = ptype;
77 /* use RGB1 pipe */
78 pipe->pipe_num = OVERLAY_PIPE_RGB1;
79 pipe->mixer_num = MDP4_MIXER0;
80 pipe->src_format = format;
81 mdp4_overlay_format2pipe(pipe);
82
83 mddi_pipe = pipe; /* keep it */
84
85 mddi_ld_param = 0;
86 mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
87
88 if (mfd->panel_info.type == MDDI_PANEL) {
89 if (mfd->panel_info.pdest == DISPLAY_1)
90 mddi_ld_param = 0;
91 else
92 mddi_ld_param = 1;
93 } else {
94 mddi_ld_param = 2;
95 }
96
97 MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param);
98 MDP_OUTP(MDP_BASE + 0x00094,
99 (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
100 } else {
101 pipe = mddi_pipe;
102 }
103
104
105 src = (uint8 *) iBuf->buf;
106
107#ifdef WHOLESCREEN
108 {
109 struct fb_info *fbi;
110
111 fbi = mfd->fbi;
112 pipe->src_height = fbi->var.yres;
113 pipe->src_width = fbi->var.xres;
114 pipe->src_h = fbi->var.yres;
115 pipe->src_w = fbi->var.xres;
116 pipe->src_y = 0;
117 pipe->src_x = 0;
118 pipe->dst_h = fbi->var.yres;
119 pipe->dst_w = fbi->var.xres;
120 pipe->dst_y = 0;
121 pipe->dst_x = 0;
122 pipe->srcp0_addr = (uint32)src;
123 pipe->srcp0_ystride = fbi->var.xres_virtual * bpp;
124 }
125
126#else
127 if (mdp4_overlay_active(MDP4_MIXER0)) {
128 struct fb_info *fbi;
129
130 fbi = mfd->fbi;
131 pipe->src_height = fbi->var.yres;
132 pipe->src_width = fbi->var.xres;
133 pipe->src_h = fbi->var.yres;
134 pipe->src_w = fbi->var.xres;
135 pipe->src_y = 0;
136 pipe->src_x = 0;
137 pipe->dst_h = fbi->var.yres;
138 pipe->dst_w = fbi->var.xres;
139 pipe->dst_y = 0;
140 pipe->dst_x = 0;
141 pipe->srcp0_addr = (uint32) src;
142 pipe->srcp0_ystride = fbi->var.xres_virtual * bpp;
143 } else {
144 /* starting input address */
145 src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * bpp;
146
147 pipe->src_height = iBuf->dma_h;
148 pipe->src_width = iBuf->dma_w;
149 pipe->src_h = iBuf->dma_h;
150 pipe->src_w = iBuf->dma_w;
151 pipe->src_y = 0;
152 pipe->src_x = 0;
153 pipe->dst_h = iBuf->dma_h;
154 pipe->dst_w = iBuf->dma_w;
155 pipe->dst_y = iBuf->dma_y;
156 pipe->dst_x = iBuf->dma_x;
157 pipe->srcp0_addr = (uint32) src;
158 pipe->srcp0_ystride = iBuf->ibuf_width * bpp;
159 }
160#endif
161
162 pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
163
164 mdp4_overlay_rgb_setup(pipe);
165
166 mdp4_mixer_stage_up(pipe);
167
168 mdp4_overlayproc_cfg(pipe);
169
170 mdp4_overlay_dmap_xy(pipe);
171
172 mdp4_overlay_dmap_cfg(mfd, 0);
173
174 /* MDP cmd block disable */
175 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
176
177}
178
179/*
180 * mdp4_overlay0_done_mddi: called from isr
181 */
182void mdp4_overlay0_done_mddi()
183{
184 if (pending_pipe)
185 complete(&pending_pipe->comp);
186}
187
188void mdp4_mddi_overlay_restore(void)
189{
190 /* mutex holded by caller */
191 mdp4_overlay_update_lcd(mddi_mfd);
192 mdp4_mddi_overlay_kickoff(mddi_mfd, mddi_pipe);
193}
194
195void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd,
196 struct mdp4_overlay_pipe *pipe)
197{
198#ifdef MDP4_NONBLOCKING
199 unsigned long flag;
200
201 spin_lock_irqsave(&mdp_spin_lock, flag);
202 if (mfd->dma->busy == TRUE) {
203 INIT_COMPLETION(pipe->comp);
204 pending_pipe = pipe;
205 }
206 spin_unlock_irqrestore(&mdp_spin_lock, flag);
207
208 if (pending_pipe != NULL) {
209 /* wait until DMA finishes the current job */
210 wait_for_completion_killable(&pipe->comp);
211 pending_pipe = NULL;
212 }
213 down(&mfd->sem);
214 mdp_enable_irq(MDP_OVERLAY0_TERM);
215 mfd->dma->busy = TRUE;
216 /* start OVERLAY pipe */
217 mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
218 up(&mfd->sem);
219#else
220 down(&mfd->sem);
221 mdp_enable_irq(MDP_OVERLAY0_TERM);
222 mfd->dma->busy = TRUE;
223 INIT_COMPLETION(pipe->comp);
224 pending_pipe = pipe;
225
226 /* start OVERLAY pipe */
227 mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
228 up(&mfd->sem);
229
230 /* wait until DMA finishes the current job */
231 wait_for_completion_killable(&pipe->comp);
232 mdp_disable_irq(MDP_OVERLAY0_TERM);
233#endif
234
235}
236
237void mdp4_mddi_overlay(struct msm_fb_data_type *mfd)
238{
239 mutex_lock(&mfd->dma->ov_mutex);
240
241 if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
242 mdp4_overlay_update_lcd(mfd);
243
244 mdp4_mddi_overlay_kickoff(mfd, mddi_pipe);
245
246 /* signal if pan function is waiting for the update completion */
247 if (mfd->pan_waiting) {
248 mfd->pan_waiting = FALSE;
249 complete(&mfd->pan_comp);
250 }
251 }
252
253 mutex_unlock(&mfd->dma->ov_mutex);
254}
diff --git a/drivers/staging/msm/mdp4_util.c b/drivers/staging/msm/mdp4_util.c
new file mode 100644
index 000000000000..fd97f5205992
--- /dev/null
+++ b/drivers/staging/msm/mdp4_util.c
@@ -0,0 +1,1686 @@
1
2/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
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 version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301, USA.
17 */
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/hrtimer.h>
26#include <linux/clk.h>
27#include <mach/hardware.h>
28#include <linux/io.h>
29#include <linux/debugfs.h>
30
31#include <asm/system.h>
32#include <asm/mach-types.h>
33#include <linux/semaphore.h>
34#include <linux/uaccess.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38#include "mdp4.h"
39
40void mdp4_sw_reset(ulong bits)
41{
42 bits &= 0x1f; /* 5 bits */
43 outpdw(MDP_BASE + 0x001c, bits); /* MDP_SW_RESET */
44
45 while (inpdw(MDP_BASE + 0x001c) & bits) /* self clear when complete */
46 ;
47 MSM_FB_INFO("mdp4_sw_reset: 0x%x\n", (int)bits);
48}
49
50void mdp4_overlay_cfg(int overlayer, int blt_mode, int refresh, int direct_out)
51{
52 ulong bits = 0;
53
54 if (blt_mode)
55 bits |= (1 << 3);
56 refresh &= 0x03; /* 2 bites */
57 bits |= (refresh << 1);
58 direct_out &= 0x01;
59 bits |= direct_out;
60
61 if (overlayer == MDP4_MIXER0)
62 outpdw(MDP_BASE + 0x10004, bits); /* MDP_OVERLAY0_CFG */
63 else
64 outpdw(MDP_BASE + 0x18004, bits); /* MDP_OVERLAY1_CFG */
65
66 MSM_FB_INFO("mdp4_overlay_cfg: 0x%x\n", (int)inpdw(MDP_BASE + 0x10004));
67}
68
69void mdp4_display_intf_sel(int output, ulong intf)
70{
71 ulong bits, mask;
72
73 bits = inpdw(MDP_BASE + 0x0038); /* MDP_DISP_INTF_SEL */
74
75 mask = 0x03; /* 2 bits */
76 intf &= 0x03; /* 2 bits */
77
78 switch (output) {
79 case EXTERNAL_INTF_SEL:
80 intf <<= 4;
81 mask <<= 4;
82 break;
83 case SECONDARY_INTF_SEL:
84 intf &= 0x02; /* only MDDI and EBI2 support */
85 intf <<= 2;
86 mask <<= 2;
87 break;
88 default:
89 break;
90 }
91
92
93 bits &= ~mask;
94 bits |= intf;
95
96 outpdw(MDP_BASE + 0x0038, bits); /* MDP_DISP_INTF_SEL */
97
98 MSM_FB_INFO("mdp4_display_intf_sel: 0x%x\n", (int)inpdw(MDP_BASE + 0x0038));
99}
100
101unsigned long mdp4_display_status(void)
102{
103 return inpdw(MDP_BASE + 0x0018) & 0x3ff; /* MDP_DISPLAY_STATUS */
104}
105
106void mdp4_ebi2_lcd_setup(int lcd, ulong base, int ystride)
107{
108 /* always use memory map */
109 ystride &= 0x01fff; /* 13 bits */
110 if (lcd == EBI2_LCD0) {
111 outpdw(MDP_BASE + 0x0060, base);/* MDP_EBI2_LCD0 */
112 outpdw(MDP_BASE + 0x0068, ystride);/* MDP_EBI2_LCD0_YSTRIDE */
113 } else {
114 outpdw(MDP_BASE + 0x0064, base);/* MDP_EBI2_LCD1 */
115 outpdw(MDP_BASE + 0x006c, ystride);/* MDP_EBI2_LCD1_YSTRIDE */
116 }
117}
118
119void mdp4_mddi_setup(int mddi, unsigned long id)
120{
121 ulong bits;
122
123 if (mddi == MDDI_EXTERNAL_SET)
124 bits = 0x02;
125 else if (mddi == MDDI_SECONDARY_SET)
126 bits = 0x01;
127 else
128 bits = 0; /* PRIMARY_SET */
129
130 id <<= 16;
131
132 bits |= id;
133
134 outpdw(MDP_BASE + 0x0090, bits); /* MDP_MDDI_PARAM_WR_SEL */
135}
136
137int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req,
138 struct file **pp_src_file, struct file **pp_dst_file)
139{
140
141 /* not implemented yet */
142 return -1;
143}
144
145void mdp4_hw_init(void)
146{
147 ulong bits;
148
149 /* MDP cmd block enable */
150 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
151
152#ifdef MDP4_ERROR
153 /*
154 * Issue software reset on DMA_P will casue DMA_P dma engine stall
155 * on LCDC mode. However DMA_P does not stall at MDDI mode.
156 * This need further investigation.
157 */
158 mdp4_sw_reset(0x17);
159#endif
160
161 mdp4_clear_lcdc();
162
163 mdp4_mixer_blend_init(0);
164 mdp4_mixer_blend_init(1);
165 mdp4_vg_qseed_init(0);
166 mdp4_vg_qseed_init(1);
167 mdp4_vg_csc_mv_setup(0);
168 mdp4_vg_csc_mv_setup(1);
169 mdp4_vg_csc_pre_bv_setup(0);
170 mdp4_vg_csc_pre_bv_setup(1);
171 mdp4_vg_csc_post_bv_setup(0);
172 mdp4_vg_csc_post_bv_setup(1);
173 mdp4_vg_csc_pre_lv_setup(0);
174 mdp4_vg_csc_pre_lv_setup(1);
175 mdp4_vg_csc_post_lv_setup(0);
176 mdp4_vg_csc_post_lv_setup(1);
177
178 mdp4_mixer_gc_lut_setup(0);
179 mdp4_mixer_gc_lut_setup(1);
180
181 mdp4_vg_igc_lut_setup(0);
182 mdp4_vg_igc_lut_setup(1);
183
184 mdp4_rgb_igc_lut_setup(0);
185 mdp4_rgb_igc_lut_setup(1);
186
187 outp32(MDP_EBI2_PORTMAP_MODE, 0x3);
188
189 /* system interrupts */
190
191 bits = mdp_intr_mask;
192 outpdw(MDP_BASE + 0x0050, bits);/* enable specififed interrupts */
193
194 /* histogram */
195 MDP_OUTP(MDP_BASE + 0x95010, 1); /* auto clear HIST */
196
197 /* enable histogram interrupts */
198 outpdw(MDP_BASE + 0x9501c, INTR_HIST_DONE);
199
200 /* For the max read pending cmd config below, if the MDP clock */
201 /* is less than the AXI clock, then we must use 3 pending */
202 /* pending requests. Otherwise, we should use 8 pending requests. */
203 /* In the future we should do this detection automatically. */
204
205 /* max read pending cmd config */
206 outpdw(MDP_BASE + 0x004c, 0x02222); /* 3 pending requests */
207
208 /* dma_p fetch config */
209 outpdw(MDP_BASE + 0x91004, 0x27); /* burst size of 8 */
210
211#ifndef CONFIG_FB_MSM_OVERLAY
212 /* both REFRESH_MODE and DIRECT_OUT are ignored at BLT mode */
213 mdp4_overlay_cfg(MDP4_MIXER0, OVERLAY_MODE_BLT, 0, 0);
214 mdp4_overlay_cfg(MDP4_MIXER1, OVERLAY_MODE_BLT, 0, 0);
215#endif
216
217 /* MDP cmd block disable */
218 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
219}
220
221
222void mdp4_clear_lcdc(void)
223{
224 uint32 bits;
225
226 bits = inpdw(MDP_BASE + 0xc0000);
227 if (bits & 0x01) /* enabled already */
228 return;
229
230 outpdw(MDP_BASE + 0xc0004, 0); /* vsync ctrl out */
231 outpdw(MDP_BASE + 0xc0008, 0); /* vsync period */
232 outpdw(MDP_BASE + 0xc000c, 0); /* vsync pusle width */
233 outpdw(MDP_BASE + 0xc0010, 0); /* lcdc display HCTL */
234 outpdw(MDP_BASE + 0xc0014, 0); /* lcdc display v start */
235 outpdw(MDP_BASE + 0xc0018, 0); /* lcdc display v end */
236 outpdw(MDP_BASE + 0xc001c, 0); /* lcdc active hctl */
237 outpdw(MDP_BASE + 0xc0020, 0); /* lcdc active v start */
238 outpdw(MDP_BASE + 0xc0024, 0); /* lcdc active v end */
239 outpdw(MDP_BASE + 0xc0028, 0); /* lcdc board color */
240 outpdw(MDP_BASE + 0xc002c, 0); /* lcdc underflow ctrl */
241 outpdw(MDP_BASE + 0xc0030, 0); /* lcdc hsync skew */
242 outpdw(MDP_BASE + 0xc0034, 0); /* lcdc test ctl */
243 outpdw(MDP_BASE + 0xc0038, 0); /* lcdc ctl polarity */
244}
245
246static struct mdp_dma_data overlay1_data;
247static int intr_dma_p;
248static int intr_dma_s;
249static int intr_dma_e;
250static int intr_overlay0;
251static int intr_overlay1;
252
253irqreturn_t mdp4_isr(int irq, void *ptr)
254{
255 uint32 isr, mask, lcdc;
256 struct mdp_dma_data *dma;
257
258 mdp_is_in_isr = TRUE;
259
260 while (1) {
261 isr = inpdw(MDP_INTR_STATUS);
262 if (isr == 0)
263 break;
264
265 mask = inpdw(MDP_INTR_ENABLE);
266 outpdw(MDP_INTR_CLEAR, isr);
267
268 isr &= mask;
269
270 if (unlikely(isr == 0))
271 break;
272
273 if (isr & INTR_DMA_P_DONE) {
274 intr_dma_p++;
275 lcdc = inpdw(MDP_BASE + 0xc0000);
276 dma = &dma2_data;
277 if (lcdc & 0x01) { /* LCDC enable */
278 /* disable LCDC interrupt */
279 mdp_intr_mask &= ~INTR_DMA_P_DONE;
280 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
281 dma->waiting = FALSE;
282 } else {
283 dma->busy = FALSE;
284 mdp_pipe_ctrl(MDP_DMA2_BLOCK,
285 MDP_BLOCK_POWER_OFF, TRUE);
286 }
287 complete(&dma->comp);
288 }
289 if (isr & INTR_DMA_S_DONE) {
290 intr_dma_s++;
291 dma = &dma_s_data;
292 dma->busy = FALSE;
293 mdp_pipe_ctrl(MDP_DMA_S_BLOCK,
294 MDP_BLOCK_POWER_OFF, TRUE);
295 complete(&dma->comp);
296 }
297 if (isr & INTR_DMA_E_DONE) {
298 intr_dma_e++;
299 dma = &dma_e_data;
300 mdp_intr_mask &= ~INTR_DMA_E_DONE;
301 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
302 dma->busy = FALSE;
303
304 if (dma->waiting) {
305 dma->waiting = FALSE;
306 complete(&dma->comp);
307 }
308 }
309 if (isr & INTR_OVERLAY0_DONE) {
310 intr_overlay0++;
311 lcdc = inpdw(MDP_BASE + 0xc0000);
312 dma = &dma2_data;
313 if (lcdc & 0x01) { /* LCDC enable */
314 /* disable LCDC interrupt */
315 mdp_intr_mask &= ~INTR_OVERLAY0_DONE;
316 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
317 dma->waiting = FALSE;
318 mdp4_overlay0_done_lcdc();
319 } else { /* MDDI */
320 dma->busy = FALSE;
321#ifdef MDP4_NONBLOCKING
322 mdp_disable_irq_nolock(MDP_OVERLAY0_TERM);
323#endif
324 mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK,
325 MDP_BLOCK_POWER_OFF, TRUE);
326 mdp4_overlay0_done_mddi();
327 }
328 }
329 if (isr & INTR_OVERLAY1_DONE) {
330 intr_overlay1++;
331 dma = &overlay1_data;
332 dma->busy = FALSE;
333 mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK,
334 MDP_BLOCK_POWER_OFF, TRUE);
335 complete(&dma->comp);
336 }
337 if (isr & INTR_DMA_P_HISTOGRAM) {
338 isr = inpdw(MDP_DMA_P_HIST_INTR_STATUS);
339 mask = inpdw(MDP_DMA_P_HIST_INTR_ENABLE);
340 outpdw(MDP_DMA_P_HIST_INTR_CLEAR, isr);
341 isr &= mask;
342 if (isr & INTR_HIST_DONE) {
343 if (mdp_hist.r)
344 memcpy(mdp_hist.r, MDP_BASE + 0x95100,
345 mdp_hist.bin_cnt*4);
346 if (mdp_hist.g)
347 memcpy(mdp_hist.g, MDP_BASE + 0x95200,
348 mdp_hist.bin_cnt*4);
349 if (mdp_hist.b)
350 memcpy(mdp_hist.b, MDP_BASE + 0x95300,
351 mdp_hist.bin_cnt*4);
352 complete(&mdp_hist_comp);
353 }
354 }
355 }
356
357 mdp_is_in_isr = FALSE;
358
359 return IRQ_HANDLED;
360}
361
362
363/*
364 * QSEED tables
365 */
366
367static uint32 vg_qseed_table0[] = {
368 0x5556aaff, 0x00000000, 0x00000000, 0x00000000
369};
370
371static uint32 vg_qseed_table1[] = {
372 0x76543210, 0xfedcba98
373};
374
375static uint32 vg_qseed_table2[] = {
376 0x02000000, 0x00000000, 0x02060ff2, 0x00000008,
377 0x02090fe4, 0x00000013, 0x020a0fd9, 0x0ffc0021,
378 0x02080fce, 0x0ffa0030, 0x02030fc5, 0x0ff60042,
379 0x01fd0fbe, 0x0ff10054, 0x01f50fb6, 0x0fed0068,
380 0x01e90fb1, 0x0fe60080, 0x01dc0fae, 0x0fe10095,
381 0x01ca0fae, 0x0fda00ae, 0x01b70fad, 0x0fd600c6,
382 0x01a40fad, 0x0fcf00e0, 0x018f0faf, 0x0fc800fa,
383 0x01780fb1, 0x0fc30114, 0x015f0fb5, 0x0fbf012d,
384 0x01490fb7, 0x0fb70149, 0x012d0fbf, 0x0fb5015f,
385 0x01140fc3, 0x0fb10178, 0x00fa0fc8, 0x0faf018f,
386 0x00e00fcf, 0x0fad01a4, 0x00c60fd6, 0x0fad01b7,
387 0x00ae0fda, 0x0fae01ca, 0x00950fe1, 0x0fae01dc,
388 0x00800fe6, 0x0fb101e9, 0x00680fed, 0x0fb601f5,
389 0x00540ff1, 0x0fbe01fd, 0x00420ff6, 0x0fc50203,
390 0x00300ffa, 0x0fce0208, 0x00210ffc, 0x0fd9020a,
391 0x00130000, 0x0fe40209, 0x00080000, 0x0ff20206,
392 0x02000000, 0x00000000, 0x02040ff2, 0x0000000a,
393 0x02040fe4, 0x00000018, 0x02010fda, 0x0ffc0029,
394 0x01fc0fcf, 0x0ffa003b, 0x01f30fc7, 0x0ff60050,
395 0x01e90fc0, 0x0ff20065, 0x01dc0fba, 0x0fee007c,
396 0x01cc0fb6, 0x0fe80096, 0x01ba0fb4, 0x0fe400ae,
397 0x01a70fb4, 0x0fdd00c8, 0x018f0fb5, 0x0fda00e2,
398 0x017a0fb5, 0x0fd400fd, 0x01630fb8, 0x0fce0117,
399 0x014c0fba, 0x0fca0130, 0x01320fbf, 0x0fc70148,
400 0x011b0fc1, 0x0fc10163, 0x01010fc8, 0x0fc00177,
401 0x00e90fcd, 0x0fbd018d, 0x00d10fd1, 0x0fbc01a2,
402 0x00ba0fd7, 0x0fbb01b4, 0x00a30fdd, 0x0fbc01c4,
403 0x008e0fe1, 0x0fbd01d4, 0x00790fe7, 0x0fbe01e2,
404 0x00670feb, 0x0fc001ee, 0x00540ff1, 0x0fc501f6,
405 0x00430ff4, 0x0fcb01fe, 0x00340ff8, 0x0fd10203,
406 0x00260ffb, 0x0fd80207, 0x001a0ffd, 0x0fe10208,
407 0x000f0000, 0x0fea0207, 0x00060000, 0x0ff50205,
408 0x02000000, 0x00000000, 0x02020ff2, 0x0000000c,
409 0x02000fe4, 0x0000001c, 0x01fa0fda, 0x0ffc0030,
410 0x01f10fd0, 0x0ffa0045, 0x01e50fc8, 0x0ff6005d,
411 0x01d60fc3, 0x0ff30074, 0x01c60fbd, 0x0fef008e,
412 0x01b30fba, 0x0fe900aa, 0x019e0fb9, 0x0fe500c4,
413 0x01870fba, 0x0fe000df, 0x016f0fbb, 0x0fdd00f9,
414 0x01580fbc, 0x0fd80114, 0x01400fbf, 0x0fd3012e,
415 0x01280fc2, 0x0fd00146, 0x010f0fc6, 0x0fce015d,
416 0x00f90fc9, 0x0fc90175, 0x00e00fcf, 0x0fc90188,
417 0x00ca0fd4, 0x0fc6019c, 0x00b40fd8, 0x0fc601ae,
418 0x009f0fdd, 0x0fc501bf, 0x008b0fe3, 0x0fc601cc,
419 0x00780fe6, 0x0fc701db, 0x00660feb, 0x0fc801e7,
420 0x00560fef, 0x0fcb01f0, 0x00460ff3, 0x0fcf01f8,
421 0x00380ff6, 0x0fd401fe, 0x002c0ff9, 0x0fd90202,
422 0x00200ffc, 0x0fdf0205, 0x00160ffe, 0x0fe60206,
423 0x000c0000, 0x0fed0207, 0x00050000, 0x0ff70204,
424 0x02000000, 0x00000000, 0x01fe0ff3, 0x0000000f,
425 0x01f60fe5, 0x00000025, 0x01ea0fdb, 0x0ffd003e,
426 0x01db0fd2, 0x0ffb0058, 0x01c80fcc, 0x0ff70075,
427 0x01b50fc7, 0x0ff40090, 0x01a00fc3, 0x0ff000ad,
428 0x01880fc1, 0x0feb00cc, 0x01700fc1, 0x0fe800e7,
429 0x01550fc3, 0x0fe40104, 0x013b0fc5, 0x0fe2011e,
430 0x01240fc6, 0x0fde0138, 0x010c0fca, 0x0fda0150,
431 0x00f40fcd, 0x0fd90166, 0x00dd0fd1, 0x0fd7017b,
432 0x00c80fd4, 0x0fd40190, 0x00b20fd9, 0x0fd401a1,
433 0x009f0fdd, 0x0fd301b1, 0x008c0fe1, 0x0fd301c0,
434 0x007b0fe5, 0x0fd301cd, 0x006a0fea, 0x0fd401d8,
435 0x005c0fec, 0x0fd501e3, 0x004d0ff0, 0x0fd601ed,
436 0x00410ff3, 0x0fd801f4, 0x00340ff7, 0x0fdb01fa,
437 0x002a0ff9, 0x0fdf01fe, 0x00200ffb, 0x0fe30202,
438 0x00180ffd, 0x0fe70204, 0x00100ffe, 0x0fed0205,
439 0x00090000, 0x0ff20205, 0x00040000, 0x0ff90203,
440 0x02000000, 0x00000000, 0x02050ff5, 0x00000006,
441 0x02070fea, 0x0000000f, 0x02080fe1, 0x0ffd001a,
442 0x02070fd8, 0x0ffb0026, 0x02030fd1, 0x0ff80034,
443 0x01fe0fcb, 0x0ff40043, 0x01f60fc5, 0x0ff10054,
444 0x01ee0fc0, 0x0feb0067, 0x01e20fbe, 0x0fe70079,
445 0x01d40fbd, 0x0fe1008e, 0x01c40fbc, 0x0fdd00a3,
446 0x01b40fbb, 0x0fd700ba, 0x01a20fbc, 0x0fd100d1,
447 0x018d0fbd, 0x0fcd00e9, 0x01770fc0, 0x0fc80101,
448 0x01630fc1, 0x0fc1011b, 0x01480fc7, 0x0fbf0132,
449 0x01300fca, 0x0fba014c, 0x01170fce, 0x0fb80163,
450 0x00fd0fd4, 0x0fb5017a, 0x00e20fda, 0x0fb5018f,
451 0x00c80fdd, 0x0fb401a7, 0x00ae0fe4, 0x0fb401ba,
452 0x00960fe8, 0x0fb601cc, 0x007c0fee, 0x0fba01dc,
453 0x00650ff2, 0x0fc001e9, 0x00500ff6, 0x0fc701f3,
454 0x003b0ffa, 0x0fcf01fc, 0x00290ffc, 0x0fda0201,
455 0x00180000, 0x0fe40204, 0x000a0000, 0x0ff20204,
456 0x02000000, 0x00000000, 0x02030ff5, 0x00000008,
457 0x02030fea, 0x00000013, 0x02020fe1, 0x0ffd0020,
458 0x01fc0fd9, 0x0ffc002f, 0x01f60fd2, 0x0ff80040,
459 0x01ed0fcd, 0x0ff50051, 0x01e30fc7, 0x0ff10065,
460 0x01d70fc3, 0x0fec007a, 0x01c60fc2, 0x0fe9008f,
461 0x01b60fc1, 0x0fe300a6, 0x01a20fc1, 0x0fe000bd,
462 0x018f0fc1, 0x0fdb00d5, 0x017b0fc2, 0x0fd500ee,
463 0x01640fc4, 0x0fd20106, 0x014d0fc8, 0x0fce011d,
464 0x01370fc9, 0x0fc90137, 0x011d0fce, 0x0fc8014d,
465 0x01060fd2, 0x0fc40164, 0x00ee0fd5, 0x0fc2017b,
466 0x00d50fdb, 0x0fc1018f, 0x00bd0fe0, 0x0fc101a2,
467 0x00a60fe3, 0x0fc101b6, 0x008f0fe9, 0x0fc201c6,
468 0x007a0fec, 0x0fc301d7, 0x00650ff1, 0x0fc701e3,
469 0x00510ff5, 0x0fcd01ed, 0x00400ff8, 0x0fd201f6,
470 0x002f0ffc, 0x0fd901fc, 0x00200ffd, 0x0fe10202,
471 0x00130000, 0x0fea0203, 0x00080000, 0x0ff50203,
472 0x02000000, 0x00000000, 0x02020ff5, 0x00000009,
473 0x01ff0fea, 0x00000017, 0x01fb0fe2, 0x0ffd0026,
474 0x01f30fda, 0x0ffc0037, 0x01ea0fd3, 0x0ff8004b,
475 0x01df0fce, 0x0ff5005e, 0x01d10fc9, 0x0ff20074,
476 0x01c10fc6, 0x0fed008c, 0x01ae0fc5, 0x0fea00a3,
477 0x019b0fc5, 0x0fe500bb, 0x01850fc6, 0x0fe200d3,
478 0x01700fc6, 0x0fde00ec, 0x015a0fc8, 0x0fd90105,
479 0x01430fca, 0x0fd6011d, 0x012b0fcd, 0x0fd30135,
480 0x01150fcf, 0x0fcf014d, 0x00fc0fd4, 0x0fce0162,
481 0x00e50fd8, 0x0fcc0177, 0x00cf0fdb, 0x0fca018c,
482 0x00b80fe0, 0x0fc9019f, 0x00a20fe5, 0x0fca01af,
483 0x008e0fe8, 0x0fcb01bf, 0x00790fec, 0x0fcb01d0,
484 0x00670fef, 0x0fcd01dd, 0x00550ff4, 0x0fd001e7,
485 0x00440ff7, 0x0fd501f0, 0x00350ffa, 0x0fda01f7,
486 0x00270ffc, 0x0fdf01fe, 0x001b0ffe, 0x0fe70200,
487 0x00100000, 0x0fee0202, 0x00060000, 0x0ff70203,
488 0x02000000, 0x00000000, 0x01ff0ff5, 0x0000000c,
489 0x01f80fea, 0x0000001e, 0x01ef0fe2, 0x0ffd0032,
490 0x01e20fdb, 0x0ffc0047, 0x01d30fd5, 0x0ff9005f,
491 0x01c20fd1, 0x0ff60077, 0x01b00fcd, 0x0ff30090,
492 0x019b0fcb, 0x0fef00ab, 0x01850fcb, 0x0fec00c4,
493 0x016e0fcc, 0x0fe800de, 0x01550fcd, 0x0fe600f8,
494 0x013f0fce, 0x0fe20111, 0x01280fd0, 0x0fdf0129,
495 0x01110fd2, 0x0fdd0140, 0x00f90fd6, 0x0fdb0156,
496 0x00e40fd8, 0x0fd8016c, 0x00cd0fdd, 0x0fd8017e,
497 0x00b80fe0, 0x0fd60192, 0x00a40fe3, 0x0fd601a3,
498 0x00910fe7, 0x0fd501b3, 0x007f0feb, 0x0fd601c0,
499 0x006e0fed, 0x0fd701ce, 0x005d0ff1, 0x0fd701db,
500 0x004f0ff3, 0x0fd901e5, 0x00400ff7, 0x0fdc01ed,
501 0x00330ff9, 0x0fe001f4, 0x00280ffb, 0x0fe301fa,
502 0x001d0ffd, 0x0fe801fe, 0x00140ffe, 0x0fed0201,
503 0x000c0000, 0x0ff20202, 0x00050000, 0x0ff90202,
504 0x02000000, 0x00000000, 0x02040ff7, 0x00000005,
505 0x02070fed, 0x0000000c, 0x02060fe6, 0x0ffe0016,
506 0x02050fdf, 0x0ffc0020, 0x02020fd9, 0x0ff9002c,
507 0x01fe0fd4, 0x0ff60038, 0x01f80fcf, 0x0ff30046,
508 0x01f00fcb, 0x0fef0056, 0x01e70fc8, 0x0feb0066,
509 0x01db0fc7, 0x0fe60078, 0x01cc0fc6, 0x0fe3008b,
510 0x01bf0fc5, 0x0fdd009f, 0x01ae0fc6, 0x0fd800b4,
511 0x019c0fc6, 0x0fd400ca, 0x01880fc9, 0x0fcf00e0,
512 0x01750fc9, 0x0fc900f9, 0x015d0fce, 0x0fc6010f,
513 0x01460fd0, 0x0fc20128, 0x012e0fd3, 0x0fbf0140,
514 0x01140fd8, 0x0fbc0158, 0x00f90fdd, 0x0fbb016f,
515 0x00df0fe0, 0x0fba0187, 0x00c40fe5, 0x0fb9019e,
516 0x00aa0fe9, 0x0fba01b3, 0x008e0fef, 0x0fbd01c6,
517 0x00740ff3, 0x0fc301d6, 0x005d0ff6, 0x0fc801e5,
518 0x00450ffa, 0x0fd001f1, 0x00300ffc, 0x0fda01fa,
519 0x001c0000, 0x0fe40200, 0x000c0000, 0x0ff20202,
520 0x02000000, 0x00000000, 0x02030ff7, 0x00000006,
521 0x02020fee, 0x00000010, 0x02000fe7, 0x0ffe001b,
522 0x01fe0fdf, 0x0ffc0027, 0x01f70fda, 0x0ffa0035,
523 0x01f00fd5, 0x0ff70044, 0x01e70fd0, 0x0ff40055,
524 0x01dd0fcd, 0x0fef0067, 0x01d00fcb, 0x0fec0079,
525 0x01bf0fcb, 0x0fe8008e, 0x01af0fca, 0x0fe500a2,
526 0x019f0fc9, 0x0fe000b8, 0x018c0fca, 0x0fdb00cf,
527 0x01770fcc, 0x0fd800e5, 0x01620fce, 0x0fd400fc,
528 0x014d0fcf, 0x0fcf0115, 0x01350fd3, 0x0fcd012b,
529 0x011d0fd6, 0x0fca0143, 0x01050fd9, 0x0fc8015a,
530 0x00ec0fde, 0x0fc60170, 0x00d30fe2, 0x0fc60185,
531 0x00bb0fe5, 0x0fc5019b, 0x00a30fea, 0x0fc501ae,
532 0x008c0fed, 0x0fc601c1, 0x00740ff2, 0x0fc901d1,
533 0x005e0ff5, 0x0fce01df, 0x004b0ff8, 0x0fd301ea,
534 0x00370ffc, 0x0fda01f3, 0x00260ffd, 0x0fe201fb,
535 0x00170000, 0x0fea01ff, 0x00090000, 0x0ff50202,
536 0x02000000, 0x00000000, 0x02010ff7, 0x00000008,
537 0x01ff0fee, 0x00000013, 0x01fb0fe7, 0x0ffe0020,
538 0x01f60fe0, 0x0ffc002e, 0x01ed0fda, 0x0ffa003f,
539 0x01e40fd6, 0x0ff7004f, 0x01d80fd2, 0x0ff40062,
540 0x01ca0fcf, 0x0ff00077, 0x01bb0fcd, 0x0fed008b,
541 0x01a90fcd, 0x0fe900a1, 0x01960fcd, 0x0fe600b7,
542 0x01830fcd, 0x0fe200ce, 0x016d0fcf, 0x0fde00e6,
543 0x01580fd0, 0x0fdb00fd, 0x01410fd3, 0x0fd80114,
544 0x012c0fd4, 0x0fd4012c, 0x01140fd8, 0x0fd30141,
545 0x00fd0fdb, 0x0fd00158, 0x00e60fde, 0x0fcf016d,
546 0x00ce0fe2, 0x0fcd0183, 0x00b70fe6, 0x0fcd0196,
547 0x00a10fe9, 0x0fcd01a9, 0x008b0fed, 0x0fcd01bb,
548 0x00770ff0, 0x0fcf01ca, 0x00620ff4, 0x0fd201d8,
549 0x004f0ff7, 0x0fd601e4, 0x003f0ffa, 0x0fda01ed,
550 0x002e0ffc, 0x0fe001f6, 0x00200ffe, 0x0fe701fb,
551 0x00130000, 0x0fee01ff, 0x00080000, 0x0ff70201,
552 0x02000000, 0x00000000, 0x01ff0ff7, 0x0000000a,
553 0x01f90fee, 0x00000019, 0x01f10fe7, 0x0ffe002a,
554 0x01e60fe1, 0x0ffd003c, 0x01d90fdc, 0x0ffa0051,
555 0x01cc0fd8, 0x0ff70065, 0x01bb0fd5, 0x0ff5007b,
556 0x01a80fd3, 0x0ff10094, 0x01950fd2, 0x0fef00aa,
557 0x01800fd2, 0x0feb00c3, 0x016a0fd3, 0x0fe900da,
558 0x01540fd3, 0x0fe600f3, 0x013f0fd5, 0x0fe2010a,
559 0x01280fd7, 0x0fe00121, 0x01100fda, 0x0fde0138,
560 0x00fb0fdb, 0x0fdb014f, 0x00e40fdf, 0x0fdb0162,
561 0x00ce0fe2, 0x0fd90177, 0x00b90fe4, 0x0fd8018b,
562 0x00a50fe8, 0x0fd8019b, 0x00910fec, 0x0fd801ab,
563 0x007e0fee, 0x0fd801bc, 0x006c0ff2, 0x0fd901c9,
564 0x005c0ff4, 0x0fda01d6, 0x004b0ff7, 0x0fdd01e1,
565 0x003c0ff9, 0x0fe001eb, 0x002f0ffb, 0x0fe401f2,
566 0x00230ffd, 0x0fe801f8, 0x00180ffe, 0x0fed01fd,
567 0x000e0000, 0x0ff20200, 0x00060000, 0x0ff90201,
568 0x02000000, 0x00000000, 0x02030ff9, 0x00000004,
569 0x02050ff2, 0x00000009, 0x02050fed, 0x0ffe0010,
570 0x02040fe7, 0x0ffd0018, 0x02020fe3, 0x0ffb0020,
571 0x01fe0fdf, 0x0ff9002a, 0x01fa0fdb, 0x0ff70034,
572 0x01f40fd8, 0x0ff30041, 0x01ed0fd6, 0x0ff0004d,
573 0x01e30fd5, 0x0fec005c, 0x01d80fd4, 0x0fea006a,
574 0x01cd0fd3, 0x0fe5007b, 0x01c00fd3, 0x0fe1008c,
575 0x01b10fd3, 0x0fdd009f, 0x01a10fd4, 0x0fd900b2,
576 0x01900fd4, 0x0fd400c8, 0x017b0fd7, 0x0fd100dd,
577 0x01660fd9, 0x0fcd00f4, 0x01500fda, 0x0fca010c,
578 0x01380fde, 0x0fc60124, 0x011e0fe2, 0x0fc5013b,
579 0x01040fe4, 0x0fc30155, 0x00e70fe8, 0x0fc10170,
580 0x00cc0feb, 0x0fc10188, 0x00ad0ff0, 0x0fc301a0,
581 0x00900ff4, 0x0fc701b5, 0x00750ff7, 0x0fcc01c8,
582 0x00580ffb, 0x0fd201db, 0x003e0ffd, 0x0fdb01ea,
583 0x00250000, 0x0fe501f6, 0x000f0000, 0x0ff301fe,
584 0x02000000, 0x00000000, 0x02020ff9, 0x00000005,
585 0x02020ff2, 0x0000000c, 0x02010fed, 0x0ffe0014,
586 0x01fe0fe8, 0x0ffd001d, 0x01fa0fe3, 0x0ffb0028,
587 0x01f40fe0, 0x0ff90033, 0x01ed0fdc, 0x0ff70040,
588 0x01e50fd9, 0x0ff3004f, 0x01db0fd7, 0x0ff1005d,
589 0x01ce0fd7, 0x0fed006e, 0x01c00fd6, 0x0feb007f,
590 0x01b30fd5, 0x0fe70091, 0x01a30fd6, 0x0fe300a4,
591 0x01920fd6, 0x0fe000b8, 0x017e0fd8, 0x0fdd00cd,
592 0x016c0fd8, 0x0fd800e4, 0x01560fdb, 0x0fd600f9,
593 0x01400fdd, 0x0fd20111, 0x01290fdf, 0x0fd00128,
594 0x01110fe2, 0x0fce013f, 0x00f80fe6, 0x0fcd0155,
595 0x00de0fe8, 0x0fcc016e, 0x00c40fec, 0x0fcb0185,
596 0x00ab0fef, 0x0fcb019b, 0x00900ff3, 0x0fcd01b0,
597 0x00770ff6, 0x0fd101c2, 0x005f0ff9, 0x0fd501d3,
598 0x00470ffc, 0x0fdb01e2, 0x00320ffd, 0x0fe201ef,
599 0x001e0000, 0x0fea01f8, 0x000c0000, 0x0ff501ff,
600 0x02000000, 0x00000000, 0x02010ff9, 0x00000006,
601 0x02000ff2, 0x0000000e, 0x01fd0fed, 0x0ffe0018,
602 0x01f80fe8, 0x0ffd0023, 0x01f20fe4, 0x0ffb002f,
603 0x01eb0fe0, 0x0ff9003c, 0x01e10fdd, 0x0ff7004b,
604 0x01d60fda, 0x0ff4005c, 0x01c90fd9, 0x0ff2006c,
605 0x01bc0fd8, 0x0fee007e, 0x01ab0fd8, 0x0fec0091,
606 0x019b0fd8, 0x0fe800a5, 0x018b0fd8, 0x0fe400b9,
607 0x01770fd9, 0x0fe200ce, 0x01620fdb, 0x0fdf00e4,
608 0x014f0fdb, 0x0fdb00fb, 0x01380fde, 0x0fda0110,
609 0x01210fe0, 0x0fd70128, 0x010a0fe2, 0x0fd5013f,
610 0x00f30fe6, 0x0fd30154, 0x00da0fe9, 0x0fd3016a,
611 0x00c30feb, 0x0fd20180, 0x00aa0fef, 0x0fd20195,
612 0x00940ff1, 0x0fd301a8, 0x007b0ff5, 0x0fd501bb,
613 0x00650ff7, 0x0fd801cc, 0x00510ffa, 0x0fdc01d9,
614 0x003c0ffd, 0x0fe101e6, 0x002a0ffe, 0x0fe701f1,
615 0x00190000, 0x0fee01f9, 0x000a0000, 0x0ff701ff,
616 0x02000000, 0x00000000, 0x01ff0ff9, 0x00000008,
617 0x01fb0ff2, 0x00000013, 0x01f50fed, 0x0ffe0020,
618 0x01ed0fe8, 0x0ffd002e, 0x01e30fe4, 0x0ffb003e,
619 0x01d80fe1, 0x0ff9004e, 0x01cb0fde, 0x0ff70060,
620 0x01bc0fdc, 0x0ff40074, 0x01ac0fdb, 0x0ff20087,
621 0x019a0fdb, 0x0fef009c, 0x01870fdb, 0x0fed00b1,
622 0x01740fdb, 0x0fea00c7, 0x01600fdc, 0x0fe700dd,
623 0x014b0fdd, 0x0fe500f3, 0x01350fdf, 0x0fe30109,
624 0x01200fe0, 0x0fe00120, 0x01090fe3, 0x0fdf0135,
625 0x00f30fe5, 0x0fdd014b, 0x00dd0fe7, 0x0fdc0160,
626 0x00c70fea, 0x0fdb0174, 0x00b10fed, 0x0fdb0187,
627 0x009c0fef, 0x0fdb019a, 0x00870ff2, 0x0fdb01ac,
628 0x00740ff4, 0x0fdc01bc, 0x00600ff7, 0x0fde01cb,
629 0x004e0ff9, 0x0fe101d8, 0x003e0ffb, 0x0fe401e3,
630 0x002e0ffd, 0x0fe801ed, 0x00200ffe, 0x0fed01f5,
631 0x00130000, 0x0ff201fb, 0x00080000, 0x0ff901ff,
632 0x02000000, 0x00000000, 0x02060ff2, 0x00000008,
633 0x02090fe4, 0x00000013, 0x020a0fd9, 0x0ffc0021,
634 0x02080fce, 0x0ffa0030, 0x02030fc5, 0x0ff60042,
635 0x01fd0fbe, 0x0ff10054, 0x01f50fb6, 0x0fed0068,
636 0x01e90fb1, 0x0fe60080, 0x01dc0fae, 0x0fe10095,
637 0x01ca0fae, 0x0fda00ae, 0x01b70fad, 0x0fd600c6,
638 0x01a40fad, 0x0fcf00e0, 0x018f0faf, 0x0fc800fa,
639 0x01780fb1, 0x0fc30114, 0x015f0fb5, 0x0fbf012d,
640 0x01490fb7, 0x0fb70149, 0x012d0fbf, 0x0fb5015f,
641 0x01140fc3, 0x0fb10178, 0x00fa0fc8, 0x0faf018f,
642 0x00e00fcf, 0x0fad01a4, 0x00c60fd6, 0x0fad01b7,
643 0x00ae0fda, 0x0fae01ca, 0x00950fe1, 0x0fae01dc,
644 0x00800fe6, 0x0fb101e9, 0x00680fed, 0x0fb601f5,
645 0x00540ff1, 0x0fbe01fd, 0x00420ff6, 0x0fc50203,
646 0x00300ffa, 0x0fce0208, 0x00210ffc, 0x0fd9020a,
647 0x00130000, 0x0fe40209, 0x00080000, 0x0ff20206,
648 0x02000000, 0x00000000, 0x02040ff2, 0x0000000a,
649 0x02040fe4, 0x00000018, 0x02010fda, 0x0ffc0029,
650 0x01fc0fcf, 0x0ffa003b, 0x01f30fc7, 0x0ff60050,
651 0x01e90fc0, 0x0ff20065, 0x01dc0fba, 0x0fee007c,
652 0x01cc0fb6, 0x0fe80096, 0x01ba0fb4, 0x0fe400ae,
653 0x01a70fb4, 0x0fdd00c8, 0x018f0fb5, 0x0fda00e2,
654 0x017a0fb5, 0x0fd400fd, 0x01630fb8, 0x0fce0117,
655 0x014c0fba, 0x0fca0130, 0x01320fbf, 0x0fc70148,
656 0x011b0fc1, 0x0fc10163, 0x01010fc8, 0x0fc00177,
657 0x00e90fcd, 0x0fbd018d, 0x00d10fd1, 0x0fbc01a2,
658 0x00ba0fd7, 0x0fbb01b4, 0x00a30fdd, 0x0fbc01c4,
659 0x008e0fe1, 0x0fbd01d4, 0x00790fe7, 0x0fbe01e2,
660 0x00670feb, 0x0fc001ee, 0x00540ff1, 0x0fc501f6,
661 0x00430ff4, 0x0fcb01fe, 0x00340ff8, 0x0fd10203,
662 0x00260ffb, 0x0fd80207, 0x001a0ffd, 0x0fe10208,
663 0x000f0000, 0x0fea0207, 0x00060000, 0x0ff50205,
664 0x02000000, 0x00000000, 0x02020ff2, 0x0000000c,
665 0x02000fe4, 0x0000001c, 0x01fa0fda, 0x0ffc0030,
666 0x01f10fd0, 0x0ffa0045, 0x01e50fc8, 0x0ff6005d,
667 0x01d60fc3, 0x0ff30074, 0x01c60fbd, 0x0fef008e,
668 0x01b30fba, 0x0fe900aa, 0x019e0fb9, 0x0fe500c4,
669 0x01870fba, 0x0fe000df, 0x016f0fbb, 0x0fdd00f9,
670 0x01580fbc, 0x0fd80114, 0x01400fbf, 0x0fd3012e,
671 0x01280fc2, 0x0fd00146, 0x010f0fc6, 0x0fce015d,
672 0x00f90fc9, 0x0fc90175, 0x00e00fcf, 0x0fc90188,
673 0x00ca0fd4, 0x0fc6019c, 0x00b40fd8, 0x0fc601ae,
674 0x009f0fdd, 0x0fc501bf, 0x008b0fe3, 0x0fc601cc,
675 0x00780fe6, 0x0fc701db, 0x00660feb, 0x0fc801e7,
676 0x00560fef, 0x0fcb01f0, 0x00460ff3, 0x0fcf01f8,
677 0x00380ff6, 0x0fd401fe, 0x002c0ff9, 0x0fd90202,
678 0x00200ffc, 0x0fdf0205, 0x00160ffe, 0x0fe60206,
679 0x000c0000, 0x0fed0207, 0x00050000, 0x0ff70204,
680 0x02000000, 0x00000000, 0x01fe0ff3, 0x0000000f,
681 0x01f60fe5, 0x00000025, 0x01ea0fdb, 0x0ffd003e,
682 0x01db0fd2, 0x0ffb0058, 0x01c80fcc, 0x0ff70075,
683 0x01b50fc7, 0x0ff40090, 0x01a00fc3, 0x0ff000ad,
684 0x01880fc1, 0x0feb00cc, 0x01700fc1, 0x0fe800e7,
685 0x01550fc3, 0x0fe40104, 0x013b0fc5, 0x0fe2011e,
686 0x01240fc6, 0x0fde0138, 0x010c0fca, 0x0fda0150,
687 0x00f40fcd, 0x0fd90166, 0x00dd0fd1, 0x0fd7017b,
688 0x00c80fd4, 0x0fd40190, 0x00b20fd9, 0x0fd401a1,
689 0x009f0fdd, 0x0fd301b1, 0x008c0fe1, 0x0fd301c0,
690 0x007b0fe5, 0x0fd301cd, 0x006a0fea, 0x0fd401d8,
691 0x005c0fec, 0x0fd501e3, 0x004d0ff0, 0x0fd601ed,
692 0x00410ff3, 0x0fd801f4, 0x00340ff7, 0x0fdb01fa,
693 0x002a0ff9, 0x0fdf01fe, 0x00200ffb, 0x0fe30202,
694 0x00180ffd, 0x0fe70204, 0x00100ffe, 0x0fed0205,
695 0x00090000, 0x0ff20205, 0x00040000, 0x0ff90203,
696 0x02000000, 0x00000000, 0x02050ff5, 0x00000006,
697 0x02070fea, 0x0000000f, 0x02080fe1, 0x0ffd001a,
698 0x02070fd8, 0x0ffb0026, 0x02030fd1, 0x0ff80034,
699 0x01fe0fcb, 0x0ff40043, 0x01f60fc5, 0x0ff10054,
700 0x01ee0fc0, 0x0feb0067, 0x01e20fbe, 0x0fe70079,
701 0x01d40fbd, 0x0fe1008e, 0x01c40fbc, 0x0fdd00a3,
702 0x01b40fbb, 0x0fd700ba, 0x01a20fbc, 0x0fd100d1,
703 0x018d0fbd, 0x0fcd00e9, 0x01770fc0, 0x0fc80101,
704 0x01630fc1, 0x0fc1011b, 0x01480fc7, 0x0fbf0132,
705 0x01300fca, 0x0fba014c, 0x01170fce, 0x0fb80163,
706 0x00fd0fd4, 0x0fb5017a, 0x00e20fda, 0x0fb5018f,
707 0x00c80fdd, 0x0fb401a7, 0x00ae0fe4, 0x0fb401ba,
708 0x00960fe8, 0x0fb601cc, 0x007c0fee, 0x0fba01dc,
709 0x00650ff2, 0x0fc001e9, 0x00500ff6, 0x0fc701f3,
710 0x003b0ffa, 0x0fcf01fc, 0x00290ffc, 0x0fda0201,
711 0x00180000, 0x0fe40204, 0x000a0000, 0x0ff20204,
712 0x02000000, 0x00000000, 0x02030ff5, 0x00000008,
713 0x02030fea, 0x00000013, 0x02020fe1, 0x0ffd0020,
714 0x01fc0fd9, 0x0ffc002f, 0x01f60fd2, 0x0ff80040,
715 0x01ed0fcd, 0x0ff50051, 0x01e30fc7, 0x0ff10065,
716 0x01d70fc3, 0x0fec007a, 0x01c60fc2, 0x0fe9008f,
717 0x01b60fc1, 0x0fe300a6, 0x01a20fc1, 0x0fe000bd,
718 0x018f0fc1, 0x0fdb00d5, 0x017b0fc2, 0x0fd500ee,
719 0x01640fc4, 0x0fd20106, 0x014d0fc8, 0x0fce011d,
720 0x01370fc9, 0x0fc90137, 0x011d0fce, 0x0fc8014d,
721 0x01060fd2, 0x0fc40164, 0x00ee0fd5, 0x0fc2017b,
722 0x00d50fdb, 0x0fc1018f, 0x00bd0fe0, 0x0fc101a2,
723 0x00a60fe3, 0x0fc101b6, 0x008f0fe9, 0x0fc201c6,
724 0x007a0fec, 0x0fc301d7, 0x00650ff1, 0x0fc701e3,
725 0x00510ff5, 0x0fcd01ed, 0x00400ff8, 0x0fd201f6,
726 0x002f0ffc, 0x0fd901fc, 0x00200ffd, 0x0fe10202,
727 0x00130000, 0x0fea0203, 0x00080000, 0x0ff50203,
728 0x02000000, 0x00000000, 0x02020ff5, 0x00000009,
729 0x01ff0fea, 0x00000017, 0x01fb0fe2, 0x0ffd0026,
730 0x01f30fda, 0x0ffc0037, 0x01ea0fd3, 0x0ff8004b,
731 0x01df0fce, 0x0ff5005e, 0x01d10fc9, 0x0ff20074,
732 0x01c10fc6, 0x0fed008c, 0x01ae0fc5, 0x0fea00a3,
733 0x019b0fc5, 0x0fe500bb, 0x01850fc6, 0x0fe200d3,
734 0x01700fc6, 0x0fde00ec, 0x015a0fc8, 0x0fd90105,
735 0x01430fca, 0x0fd6011d, 0x012b0fcd, 0x0fd30135,
736 0x01150fcf, 0x0fcf014d, 0x00fc0fd4, 0x0fce0162,
737 0x00e50fd8, 0x0fcc0177, 0x00cf0fdb, 0x0fca018c,
738 0x00b80fe0, 0x0fc9019f, 0x00a20fe5, 0x0fca01af,
739 0x008e0fe8, 0x0fcb01bf, 0x00790fec, 0x0fcb01d0,
740 0x00670fef, 0x0fcd01dd, 0x00550ff4, 0x0fd001e7,
741 0x00440ff7, 0x0fd501f0, 0x00350ffa, 0x0fda01f7,
742 0x00270ffc, 0x0fdf01fe, 0x001b0ffe, 0x0fe70200,
743 0x00100000, 0x0fee0202, 0x00060000, 0x0ff70203,
744 0x02000000, 0x00000000, 0x01ff0ff5, 0x0000000c,
745 0x01f80fea, 0x0000001e, 0x01ef0fe2, 0x0ffd0032,
746 0x01e20fdb, 0x0ffc0047, 0x01d30fd5, 0x0ff9005f,
747 0x01c20fd1, 0x0ff60077, 0x01b00fcd, 0x0ff30090,
748 0x019b0fcb, 0x0fef00ab, 0x01850fcb, 0x0fec00c4,
749 0x016e0fcc, 0x0fe800de, 0x01550fcd, 0x0fe600f8,
750 0x013f0fce, 0x0fe20111, 0x01280fd0, 0x0fdf0129,
751 0x01110fd2, 0x0fdd0140, 0x00f90fd6, 0x0fdb0156,
752 0x00e40fd8, 0x0fd8016c, 0x00cd0fdd, 0x0fd8017e,
753 0x00b80fe0, 0x0fd60192, 0x00a40fe3, 0x0fd601a3,
754 0x00910fe7, 0x0fd501b3, 0x007f0feb, 0x0fd601c0,
755 0x006e0fed, 0x0fd701ce, 0x005d0ff1, 0x0fd701db,
756 0x004f0ff3, 0x0fd901e5, 0x00400ff7, 0x0fdc01ed,
757 0x00330ff9, 0x0fe001f4, 0x00280ffb, 0x0fe301fa,
758 0x001d0ffd, 0x0fe801fe, 0x00140ffe, 0x0fed0201,
759 0x000c0000, 0x0ff20202, 0x00050000, 0x0ff90202,
760 0x02000000, 0x00000000, 0x02040ff7, 0x00000005,
761 0x02070fed, 0x0000000c, 0x02060fe6, 0x0ffe0016,
762 0x02050fdf, 0x0ffc0020, 0x02020fd9, 0x0ff9002c,
763 0x01fe0fd4, 0x0ff60038, 0x01f80fcf, 0x0ff30046,
764 0x01f00fcb, 0x0fef0056, 0x01e70fc8, 0x0feb0066,
765 0x01db0fc7, 0x0fe60078, 0x01cc0fc6, 0x0fe3008b,
766 0x01bf0fc5, 0x0fdd009f, 0x01ae0fc6, 0x0fd800b4,
767 0x019c0fc6, 0x0fd400ca, 0x01880fc9, 0x0fcf00e0,
768 0x01750fc9, 0x0fc900f9, 0x015d0fce, 0x0fc6010f,
769 0x01460fd0, 0x0fc20128, 0x012e0fd3, 0x0fbf0140,
770 0x01140fd8, 0x0fbc0158, 0x00f90fdd, 0x0fbb016f,
771 0x00df0fe0, 0x0fba0187, 0x00c40fe5, 0x0fb9019e,
772 0x00aa0fe9, 0x0fba01b3, 0x008e0fef, 0x0fbd01c6,
773 0x00740ff3, 0x0fc301d6, 0x005d0ff6, 0x0fc801e5,
774 0x00450ffa, 0x0fd001f1, 0x00300ffc, 0x0fda01fa,
775 0x001c0000, 0x0fe40200, 0x000c0000, 0x0ff20202,
776 0x02000000, 0x00000000, 0x02030ff7, 0x00000006,
777 0x02020fee, 0x00000010, 0x02000fe7, 0x0ffe001b,
778 0x01fe0fdf, 0x0ffc0027, 0x01f70fda, 0x0ffa0035,
779 0x01f00fd5, 0x0ff70044, 0x01e70fd0, 0x0ff40055,
780 0x01dd0fcd, 0x0fef0067, 0x01d00fcb, 0x0fec0079,
781 0x01bf0fcb, 0x0fe8008e, 0x01af0fca, 0x0fe500a2,
782 0x019f0fc9, 0x0fe000b8, 0x018c0fca, 0x0fdb00cf,
783 0x01770fcc, 0x0fd800e5, 0x01620fce, 0x0fd400fc,
784 0x014d0fcf, 0x0fcf0115, 0x01350fd3, 0x0fcd012b,
785 0x011d0fd6, 0x0fca0143, 0x01050fd9, 0x0fc8015a,
786 0x00ec0fde, 0x0fc60170, 0x00d30fe2, 0x0fc60185,
787 0x00bb0fe5, 0x0fc5019b, 0x00a30fea, 0x0fc501ae,
788 0x008c0fed, 0x0fc601c1, 0x00740ff2, 0x0fc901d1,
789 0x005e0ff5, 0x0fce01df, 0x004b0ff8, 0x0fd301ea,
790 0x00370ffc, 0x0fda01f3, 0x00260ffd, 0x0fe201fb,
791 0x00170000, 0x0fea01ff, 0x00090000, 0x0ff50202,
792 0x02000000, 0x00000000, 0x02010ff7, 0x00000008,
793 0x01ff0fee, 0x00000013, 0x01fb0fe7, 0x0ffe0020,
794 0x01f60fe0, 0x0ffc002e, 0x01ed0fda, 0x0ffa003f,
795 0x01e40fd6, 0x0ff7004f, 0x01d80fd2, 0x0ff40062,
796 0x01ca0fcf, 0x0ff00077, 0x01bb0fcd, 0x0fed008b,
797 0x01a90fcd, 0x0fe900a1, 0x01960fcd, 0x0fe600b7,
798 0x01830fcd, 0x0fe200ce, 0x016d0fcf, 0x0fde00e6,
799 0x01580fd0, 0x0fdb00fd, 0x01410fd3, 0x0fd80114,
800 0x012c0fd4, 0x0fd4012c, 0x01140fd8, 0x0fd30141,
801 0x00fd0fdb, 0x0fd00158, 0x00e60fde, 0x0fcf016d,
802 0x00ce0fe2, 0x0fcd0183, 0x00b70fe6, 0x0fcd0196,
803 0x00a10fe9, 0x0fcd01a9, 0x008b0fed, 0x0fcd01bb,
804 0x00770ff0, 0x0fcf01ca, 0x00620ff4, 0x0fd201d8,
805 0x004f0ff7, 0x0fd601e4, 0x003f0ffa, 0x0fda01ed,
806 0x002e0ffc, 0x0fe001f6, 0x00200ffe, 0x0fe701fb,
807 0x00130000, 0x0fee01ff, 0x00080000, 0x0ff70201,
808 0x02000000, 0x00000000, 0x01ff0ff7, 0x0000000a,
809 0x01f90fee, 0x00000019, 0x01f10fe7, 0x0ffe002a,
810 0x01e60fe1, 0x0ffd003c, 0x01d90fdc, 0x0ffa0051,
811 0x01cc0fd8, 0x0ff70065, 0x01bb0fd5, 0x0ff5007b,
812 0x01a80fd3, 0x0ff10094, 0x01950fd2, 0x0fef00aa,
813 0x01800fd2, 0x0feb00c3, 0x016a0fd3, 0x0fe900da,
814 0x01540fd3, 0x0fe600f3, 0x013f0fd5, 0x0fe2010a,
815 0x01280fd7, 0x0fe00121, 0x01100fda, 0x0fde0138,
816 0x00fb0fdb, 0x0fdb014f, 0x00e40fdf, 0x0fdb0162,
817 0x00ce0fe2, 0x0fd90177, 0x00b90fe4, 0x0fd8018b,
818 0x00a50fe8, 0x0fd8019b, 0x00910fec, 0x0fd801ab,
819 0x007e0fee, 0x0fd801bc, 0x006c0ff2, 0x0fd901c9,
820 0x005c0ff4, 0x0fda01d6, 0x004b0ff7, 0x0fdd01e1,
821 0x003c0ff9, 0x0fe001eb, 0x002f0ffb, 0x0fe401f2,
822 0x00230ffd, 0x0fe801f8, 0x00180ffe, 0x0fed01fd,
823 0x000e0000, 0x0ff20200, 0x00060000, 0x0ff90201,
824 0x02000000, 0x00000000, 0x02030ff9, 0x00000004,
825 0x02050ff2, 0x00000009, 0x02050fed, 0x0ffe0010,
826 0x02040fe7, 0x0ffd0018, 0x02020fe3, 0x0ffb0020,
827 0x01fe0fdf, 0x0ff9002a, 0x01fa0fdb, 0x0ff70034,
828 0x01f40fd8, 0x0ff30041, 0x01ed0fd6, 0x0ff0004d,
829 0x01e30fd5, 0x0fec005c, 0x01d80fd4, 0x0fea006a,
830 0x01cd0fd3, 0x0fe5007b, 0x01c00fd3, 0x0fe1008c,
831 0x01b10fd3, 0x0fdd009f, 0x01a10fd4, 0x0fd900b2,
832 0x01900fd4, 0x0fd400c8, 0x017b0fd7, 0x0fd100dd,
833 0x01660fd9, 0x0fcd00f4, 0x01500fda, 0x0fca010c,
834 0x01380fde, 0x0fc60124, 0x011e0fe2, 0x0fc5013b,
835 0x01040fe4, 0x0fc30155, 0x00e70fe8, 0x0fc10170,
836 0x00cc0feb, 0x0fc10188, 0x00ad0ff0, 0x0fc301a0,
837 0x00900ff4, 0x0fc701b5, 0x00750ff7, 0x0fcc01c8,
838 0x00580ffb, 0x0fd201db, 0x003e0ffd, 0x0fdb01ea,
839 0x00250000, 0x0fe501f6, 0x000f0000, 0x0ff301fe,
840 0x02000000, 0x00000000, 0x02020ff9, 0x00000005,
841 0x02020ff2, 0x0000000c, 0x02010fed, 0x0ffe0014,
842 0x01fe0fe8, 0x0ffd001d, 0x01fa0fe3, 0x0ffb0028,
843 0x01f40fe0, 0x0ff90033, 0x01ed0fdc, 0x0ff70040,
844 0x01e50fd9, 0x0ff3004f, 0x01db0fd7, 0x0ff1005d,
845 0x01ce0fd7, 0x0fed006e, 0x01c00fd6, 0x0feb007f,
846 0x01b30fd5, 0x0fe70091, 0x01a30fd6, 0x0fe300a4,
847 0x01920fd6, 0x0fe000b8, 0x017e0fd8, 0x0fdd00cd,
848 0x016c0fd8, 0x0fd800e4, 0x01560fdb, 0x0fd600f9,
849 0x01400fdd, 0x0fd20111, 0x01290fdf, 0x0fd00128,
850 0x01110fe2, 0x0fce013f, 0x00f80fe6, 0x0fcd0155,
851 0x00de0fe8, 0x0fcc016e, 0x00c40fec, 0x0fcb0185,
852 0x00ab0fef, 0x0fcb019b, 0x00900ff3, 0x0fcd01b0,
853 0x00770ff6, 0x0fd101c2, 0x005f0ff9, 0x0fd501d3,
854 0x00470ffc, 0x0fdb01e2, 0x00320ffd, 0x0fe201ef,
855 0x001e0000, 0x0fea01f8, 0x000c0000, 0x0ff501ff,
856 0x02000000, 0x00000000, 0x02010ff9, 0x00000006,
857 0x02000ff2, 0x0000000e, 0x01fd0fed, 0x0ffe0018,
858 0x01f80fe8, 0x0ffd0023, 0x01f20fe4, 0x0ffb002f,
859 0x01eb0fe0, 0x0ff9003c, 0x01e10fdd, 0x0ff7004b,
860 0x01d60fda, 0x0ff4005c, 0x01c90fd9, 0x0ff2006c,
861 0x01bc0fd8, 0x0fee007e, 0x01ab0fd8, 0x0fec0091,
862 0x019b0fd8, 0x0fe800a5, 0x018b0fd8, 0x0fe400b9,
863 0x01770fd9, 0x0fe200ce, 0x01620fdb, 0x0fdf00e4,
864 0x014f0fdb, 0x0fdb00fb, 0x01380fde, 0x0fda0110,
865 0x01210fe0, 0x0fd70128, 0x010a0fe2, 0x0fd5013f,
866 0x00f30fe6, 0x0fd30154, 0x00da0fe9, 0x0fd3016a,
867 0x00c30feb, 0x0fd20180, 0x00aa0fef, 0x0fd20195,
868 0x00940ff1, 0x0fd301a8, 0x007b0ff5, 0x0fd501bb,
869 0x00650ff7, 0x0fd801cc, 0x00510ffa, 0x0fdc01d9,
870 0x003c0ffd, 0x0fe101e6, 0x002a0ffe, 0x0fe701f1,
871 0x00190000, 0x0fee01f9, 0x000a0000, 0x0ff701ff,
872 0x02000000, 0x00000000, 0x01ff0ff9, 0x00000008,
873 0x01fb0ff2, 0x00000013, 0x01f50fed, 0x0ffe0020,
874 0x01ed0fe8, 0x0ffd002e, 0x01e30fe4, 0x0ffb003e,
875 0x01d80fe1, 0x0ff9004e, 0x01cb0fde, 0x0ff70060,
876 0x01bc0fdc, 0x0ff40074, 0x01ac0fdb, 0x0ff20087,
877 0x019a0fdb, 0x0fef009c, 0x01870fdb, 0x0fed00b1,
878 0x01740fdb, 0x0fea00c7, 0x01600fdc, 0x0fe700dd,
879 0x014b0fdd, 0x0fe500f3, 0x01350fdf, 0x0fe30109,
880 0x01200fe0, 0x0fe00120, 0x01090fe3, 0x0fdf0135,
881 0x00f30fe5, 0x0fdd014b, 0x00dd0fe7, 0x0fdc0160,
882 0x00c70fea, 0x0fdb0174, 0x00b10fed, 0x0fdb0187,
883 0x009c0fef, 0x0fdb019a, 0x00870ff2, 0x0fdb01ac,
884 0x00740ff4, 0x0fdc01bc, 0x00600ff7, 0x0fde01cb,
885 0x004e0ff9, 0x0fe101d8, 0x003e0ffb, 0x0fe401e3,
886 0x002e0ffd, 0x0fe801ed, 0x00200ffe, 0x0fed01f5,
887 0x00130000, 0x0ff201fb, 0x00080000, 0x0ff901ff
888};
889
890
891#define MDP4_QSEED_TABLE0_OFF 0x8100
892#define MDP4_QSEED_TABLE1_OFF 0x8200
893#define MDP4_QSEED_TABLE2_OFF 0x9000
894
895void mdp4_vg_qseed_init(int vp_num)
896{
897 uint32 *off;
898 int i, voff;
899
900 voff = MDP4_VIDEO_OFF * vp_num;
901 off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
902 MDP4_QSEED_TABLE0_OFF);
903 for (i = 0; i < (sizeof(vg_qseed_table0) / sizeof(uint32)); i++) {
904 outpdw(off, vg_qseed_table0[i]);
905 off++;
906 }
907
908 off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
909 MDP4_QSEED_TABLE1_OFF);
910 for (i = 0; i < (sizeof(vg_qseed_table1) / sizeof(uint32)); i++) {
911 outpdw(off, vg_qseed_table1[i]);
912 off++;
913 }
914
915 off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
916 MDP4_QSEED_TABLE2_OFF);
917 for (i = 0; i < (sizeof(vg_qseed_table2) / sizeof(uint32)); i++) {
918 outpdw(off, vg_qseed_table2[i]);
919 off++;
920 }
921
922}
923
924void mdp4_mixer_blend_init(mixer_num)
925{
926 unsigned char *overlay_base;
927 int off;
928
929 if (mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */
930 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
931 else
932 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
933
934 /* stage 0 to stage 2 */
935 off = 0;
936 outpdw(overlay_base + off + 0x104, 0x010);
937 outpdw(overlay_base + off + 0x108, 0xff);/* FG */
938 outpdw(overlay_base + off + 0x10c, 0x00);/* BG */
939
940 off += 0x20;
941 outpdw(overlay_base + off + 0x104, 0x010);
942 outpdw(overlay_base + off + 0x108, 0xff);/* FG */
943 outpdw(overlay_base + off + 0x10c, 0x00);/* BG */
944
945 off += 0x20;
946 outpdw(overlay_base + off + 0x104, 0x010);
947 outpdw(overlay_base + off + 0x108, 0xff);/* FG */
948 outpdw(overlay_base + off + 0x10c, 0x00);/* BG */
949}
950
951
952static uint32 csc_matrix_tab[9] = {
953 0x0254, 0x0000, 0x0331,
954 0x0254, 0xff37, 0xfe60,
955 0x0254, 0x0409, 0x0000
956};
957
958static uint32 csc_pre_bv_tab[3] = {0xfff0, 0xff80, 0xff80 };
959static uint32 csc_post_bv_tab[3] = {0, 0, 0 };
960
961static uint32 csc_pre_lv_tab[6] = {0, 0xff, 0, 0xff, 0, 0xff };
962static uint32 csc_post_lv_tab[6] = {0, 0xff, 0, 0xff, 0, 0xff };
963
964#define MDP4_CSC_MV_OFF 0x4400
965#define MDP4_CSC_PRE_BV_OFF 0x4500
966#define MDP4_CSC_POST_BV_OFF 0x4580
967#define MDP4_CSC_PRE_LV_OFF 0x4600
968#define MDP4_CSC_POST_LV_OFF 0x4680
969
970void mdp4_vg_csc_mv_setup(int vp_num)
971{
972 uint32 *off;
973 int i, voff;
974
975 voff = MDP4_VIDEO_OFF * vp_num;
976 off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
977 MDP4_CSC_MV_OFF);
978 for (i = 0; i < 9; i++) {
979 outpdw(off, csc_matrix_tab[i]);
980 off++;
981 }
982}
983
984void mdp4_vg_csc_pre_bv_setup(int vp_num)
985{
986 uint32 *off;
987 int i, voff;
988
989 voff = MDP4_VIDEO_OFF * vp_num;
990 off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
991 MDP4_CSC_PRE_BV_OFF);
992 for (i = 0; i < 3; i++) {
993 outpdw(off, csc_pre_bv_tab[i]);
994 off++;
995 }
996}
997
998void mdp4_vg_csc_post_bv_setup(int vp_num)
999{
1000 uint32 *off;
1001 int i, voff;
1002
1003 voff = MDP4_VIDEO_OFF * vp_num;
1004 off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
1005 MDP4_CSC_POST_BV_OFF);
1006 for (i = 0; i < 3; i++) {
1007 outpdw(off, csc_post_bv_tab[i]);
1008 off++;
1009 }
1010}
1011
1012void mdp4_vg_csc_pre_lv_setup(int vp_num)
1013{
1014 uint32 *off;
1015 int i, voff;
1016
1017 voff = MDP4_VIDEO_OFF * vp_num;
1018 off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
1019 MDP4_CSC_PRE_LV_OFF);
1020
1021 for (i = 0; i < 6; i++) {
1022 outpdw(off, csc_pre_lv_tab[i]);
1023 off++;
1024 }
1025}
1026
1027void mdp4_vg_csc_post_lv_setup(int vp_num)
1028{
1029 uint32 *off;
1030 int i, voff;
1031
1032 voff = MDP4_VIDEO_OFF * vp_num;
1033 off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
1034 MDP4_CSC_POST_LV_OFF);
1035
1036 for (i = 0; i < 6; i++) {
1037 outpdw(off, csc_post_lv_tab[i]);
1038 off++;
1039 }
1040}
1041
1042char gc_lut[] = {
1043 0x0, 0x1, 0x2, 0x2, 0x3, 0x4, 0x5, 0x6,
1044 0x6, 0x7, 0x8, 0x9, 0xA, 0xA, 0xB, 0xC,
1045 0xD, 0xD, 0xE, 0xF, 0xF, 0x10, 0x10, 0x11,
1046 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15,
1047 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, 0x19,
1048 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1C,
1049 0x1C, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1F,
1050 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21,
1051 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24,
1052 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26,
1053 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28,
1054 0x28, 0x29, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A,
1055 0x2A, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2C, 0x2C,
1056 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E,
1057 0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x2F, 0x30,
1058 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
1059 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33,
1060 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x34,
1061 0x35, 0x35, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36,
1062 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
1063 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39,
1064 0x39, 0x39, 0x39, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A,
1065 0x3A, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3C,
1066 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3D, 0x3D, 0x3D,
1067 0x3D, 0x3D, 0x3D, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E,
1068 0x3E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x40,
1069 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41,
1070 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42,
1071 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43,
1072 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1073 0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
1074 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x47,
1075 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48,
1076 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49,
1077 0x49, 0x49, 0x49, 0x49, 0x49, 0x4A, 0x4A, 0x4A,
1078 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4B, 0x4B, 0x4B,
1079 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4C, 0x4C, 0x4C,
1080 0x4C, 0x4C, 0x4C, 0x4C, 0x4D, 0x4D, 0x4D, 0x4D,
1081 0x4D, 0x4D, 0x4D, 0x4D, 0x4E, 0x4E, 0x4E, 0x4E,
1082 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F,
1083 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x50, 0x50, 0x50,
1084 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51,
1085 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52,
1086 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53,
1087 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54,
1088 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
1089 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
1090 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
1091 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
1092 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x58,
1093 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59,
1094 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x5A, 0x5A,
1095 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
1096 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B,
1097 0x5B, 0x5B, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
1098 0x5C, 0x5C, 0x5C, 0x5C, 0x5D, 0x5D, 0x5D, 0x5D,
1099 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5E, 0x5E,
1100 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E,
1101 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F,
1102 0x5F, 0x5F, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1103 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61,
1104 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x62,
1105 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62,
1106 0x62, 0x62, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1107 0x63, 0x63, 0x63, 0x63, 0x63, 0x64, 0x64, 0x64,
1108 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
1109 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
1110 0x65, 0x65, 0x65, 0x66, 0x66, 0x66, 0x66, 0x66,
1111 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67,
1112 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67,
1113 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68,
1114 0x68, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69,
1115 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
1116 0x69, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A,
1117 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6B, 0x6B, 0x6B,
1118 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
1119 0x6B, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,
1120 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6D, 0x6D, 0x6D,
1121 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
1122 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E,
1123 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x6F, 0x6F,
1124 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F,
1125 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
1126 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71,
1127 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71,
1128 0x71, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x72,
1129 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
1130 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73,
1131 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74,
1132 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
1133 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
1134 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
1135 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
1136 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
1137 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
1138 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78,
1139 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
1140 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
1141 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7A, 0x7A,
1142 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A,
1143 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B,
1144 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B,
1145 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C,
1146 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C,
1147 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
1148 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
1149 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
1150 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F,
1151 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
1152 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x80, 0x80, 0x80,
1153 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1154 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81,
1155 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
1156 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82,
1157 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
1158 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
1159 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
1160 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
1161 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
1162 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
1163 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
1164 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
1165 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
1166 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
1167 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
1168 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
1169 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
1170 0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
1171 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
1172 0x89, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
1173 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
1174 0x8A, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
1175 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
1176 0x8B, 0x8B, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
1177 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
1178 0x8C, 0x8C, 0x8C, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
1179 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
1180 0x8D, 0x8D, 0x8D, 0x8D, 0x8E, 0x8E, 0x8E, 0x8E,
1181 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
1182 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, 0x8F, 0x8F,
1183 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
1184 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x90, 0x90,
1185 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1186 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x91,
1187 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
1188 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
1189 0x91, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
1190 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
1191 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
1192 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
1193 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94,
1194 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
1195 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x95, 0x95,
1196 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
1197 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
1198 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
1199 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
1200 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, 0x97,
1201 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
1202 0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98,
1203 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
1204 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
1205 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
1206 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
1207 0x99, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
1208 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
1209 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9B, 0x9B, 0x9B,
1210 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B,
1211 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B,
1212 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C,
1213 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C,
1214 0x9C, 0x9C, 0x9C, 0x9C, 0x9D, 0x9D, 0x9D, 0x9D,
1215 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
1216 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9E,
1217 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
1218 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
1219 0x9E, 0x9E, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F,
1220 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F,
1221 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0xA0, 0xA0,
1222 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
1223 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
1224 0xA0, 0xA0, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1,
1225 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1,
1226 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA2, 0xA2,
1227 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2,
1228 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2,
1229 0xA2, 0xA2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
1230 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
1231 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA4, 0xA4,
1232 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
1233 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
1234 0xA4, 0xA4, 0xA4, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
1235 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
1236 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
1237 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
1238 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
1239 0xA6, 0xA6, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA7,
1240 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7,
1241 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7,
1242 0xA7, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
1243 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
1244 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA9,
1245 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9,
1246 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9,
1247 0xA9, 0xA9, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA,
1248 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
1249 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
1250 0xAA, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
1251 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
1252 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAC,
1253 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
1254 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
1255 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD,
1256 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD,
1257 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD,
1258 0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE,
1259 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE,
1260 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE,
1261 0xAE, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF,
1262 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF,
1263 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xB0,
1264 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0,
1265 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0,
1266 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB1, 0xB1,
1267 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1,
1268 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1,
1269 0xB1, 0xB1, 0xB1, 0xB1, 0xB2, 0xB2, 0xB2, 0xB2,
1270 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
1271 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
1272 0xB2, 0xB2, 0xB2, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3,
1273 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3,
1274 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3,
1275 0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4,
1276 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4,
1277 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4,
1278 0xB4, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5,
1279 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5,
1280 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5,
1281 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
1282 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
1283 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
1284 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7,
1285 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7,
1286 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB8,
1287 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8,
1288 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8,
1289 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB9,
1290 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9,
1291 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9,
1292 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xBA,
1293 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA,
1294 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA,
1295 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBB,
1296 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
1297 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
1298 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
1299 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC,
1300 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC,
1301 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC,
1302 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD,
1303 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD,
1304 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD,
1305 0xBD, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE,
1306 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE,
1307 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE,
1308 0xBE, 0xBE, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF,
1309 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF,
1310 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF,
1311 0xBF, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
1312 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
1313 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
1314 0xC0, 0xC0, 0xC0, 0xC0, 0xC1, 0xC1, 0xC1, 0xC1,
1315 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1,
1316 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1,
1317 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC2, 0xC2, 0xC2,
1318 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
1319 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
1320 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC3, 0xC3,
1321 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
1322 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
1323 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
1324 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4,
1325 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4,
1326 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4,
1327 0xC4, 0xC4, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5,
1328 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5,
1329 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5,
1330 0xC5, 0xC5, 0xC5, 0xC5, 0xC6, 0xC6, 0xC6, 0xC6,
1331 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
1332 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
1333 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, 0xC7,
1334 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7,
1335 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7,
1336 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7,
1337 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
1338 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
1339 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
1340 0xC8, 0xC8, 0xC8, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9,
1341 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9,
1342 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9,
1343 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xCA, 0xCA,
1344 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA,
1345 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA,
1346 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA,
1347 0xCA, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB,
1348 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB,
1349 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB,
1350 0xCB, 0xCB, 0xCB, 0xCB, 0xCC, 0xCC, 0xCC, 0xCC,
1351 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
1352 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
1353 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCD,
1354 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
1355 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
1356 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
1357 0xCD, 0xCD, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE,
1358 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE,
1359 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE,
1360 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCF, 0xCF,
1361 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF,
1362 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF,
1363 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF,
1364 0xCF, 0xCF, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0,
1365 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0,
1366 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0,
1367 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD1, 0xD1, 0xD1,
1368 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1,
1369 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1,
1370 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1,
1371 0xD1, 0xD1, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
1372 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
1373 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
1374 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD3, 0xD3,
1375 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3,
1376 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3,
1377 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3,
1378 0xD3, 0xD3, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4,
1379 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4,
1380 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4,
1381 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD5,
1382 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
1383 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
1384 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
1385 0xD5, 0xD5, 0xD5, 0xD5, 0xD6, 0xD6, 0xD6, 0xD6,
1386 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
1387 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
1388 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
1389 0xD6, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
1390 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
1391 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
1392 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD8, 0xD8,
1393 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
1394 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
1395 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
1396 0xD8, 0xD8, 0xD8, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
1397 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
1398 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
1399 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
1400 0xD9, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
1401 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
1402 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
1403 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDB, 0xDB,
1404 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
1405 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
1406 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
1407 0xDB, 0xDB, 0xDB, 0xDB, 0xDC, 0xDC, 0xDC, 0xDC,
1408 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
1409 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
1410 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
1411 0xDC, 0xDC, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
1412 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
1413 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
1414 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
1415 0xDD, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
1416 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
1417 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
1418 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDF,
1419 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
1420 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
1421 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
1422 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE0, 0xE0,
1423 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
1424 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
1425 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
1426 0xE0, 0xE0, 0xE0, 0xE0, 0xE1, 0xE1, 0xE1, 0xE1,
1427 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1,
1428 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1,
1429 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1,
1430 0xE1, 0xE1, 0xE1, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
1431 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
1432 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
1433 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
1434 0xE2, 0xE2, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
1435 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
1436 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
1437 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
1438 0xE3, 0xE3, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
1439 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
1440 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
1441 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
1442 0xE4, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
1443 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
1444 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
1445 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
1446 0xE5, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
1447 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
1448 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
1449 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
1450 0xE6, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
1451 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
1452 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
1453 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
1454 0xE7, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
1455 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
1456 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
1457 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
1458 0xE8, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
1459 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
1460 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
1461 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
1462 0xE9, 0xE9, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA,
1463 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA,
1464 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA,
1465 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA,
1466 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
1467 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
1468 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
1469 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
1470 0xEB, 0xEB, 0xEB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
1471 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
1472 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
1473 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
1474 0xEC, 0xEC, 0xEC, 0xEC, 0xED, 0xED, 0xED, 0xED,
1475 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
1476 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
1477 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
1478 0xED, 0xED, 0xED, 0xED, 0xED, 0xEE, 0xEE, 0xEE,
1479 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
1480 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
1481 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
1482 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEF, 0xEF,
1483 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
1484 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
1485 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
1486 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
1487 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
1488 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
1489 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
1490 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
1491 0xF0, 0xF0, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
1492 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
1493 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
1494 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
1495 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, 0xF2, 0xF2,
1496 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
1497 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
1498 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
1499 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF3, 0xF3,
1500 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
1501 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
1502 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
1503 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
1504 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
1505 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
1506 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
1507 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
1508 0xF4, 0xF4, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
1509 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
1510 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
1511 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
1512 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6, 0xF6,
1513 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6,
1514 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6,
1515 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6,
1516 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6,
1517 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
1518 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
1519 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
1520 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
1521 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
1522 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
1523 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
1524 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
1525 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF9, 0xF9,
1526 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9,
1527 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9,
1528 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9,
1529 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9,
1530 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
1531 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
1532 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
1533 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
1534 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB,
1535 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
1536 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
1537 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
1538 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
1539 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
1540 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
1541 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
1542 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
1543 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD,
1544 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
1545 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
1546 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
1547 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
1548 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
1549 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
1550 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
1551 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
1552 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
1553 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1554 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1555};
1556
1557void mdp4_mixer_gc_lut_setup(int mixer_num)
1558{
1559 unsigned char *base;
1560 uint32 data;
1561 char val;
1562 int i, off;
1563
1564 if (mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */
1565 base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
1566 else
1567 base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
1568
1569 base += 0x4000; /* GC_LUT offset */
1570
1571 off = 0;
1572 for (i = 0; i < 4096; i++) {
1573 val = gc_lut[i];
1574 data = (val << 16 | val << 8 | val); /* R, B, and G are same */
1575 outpdw(base + off, data);
1576 off += 4;
1577 }
1578}
1579
1580uint32 igc_video_lut[] = { /* non linear */
1581 0x0, 0x1, 0x2, 0x4, 0x5, 0x6, 0x7, 0x9,
1582 0xA, 0xB, 0xC, 0xE, 0xF, 0x10, 0x12, 0x14,
1583 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F, 0x21, 0x23,
1584 0x25, 0x28, 0x2A, 0x2D, 0x30, 0x32, 0x35, 0x38,
1585 0x3B, 0x3E, 0x42, 0x45, 0x48, 0x4C, 0x4F, 0x53,
1586 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x70, 0x74,
1587 0x79, 0x7E, 0x83, 0x88, 0x8D, 0x92, 0x97, 0x9C,
1588 0xA2, 0xA8, 0xAD, 0xB3, 0xB9, 0xBF, 0xC5, 0xCC,
1589 0xD2, 0xD8, 0xDF, 0xE6, 0xED, 0xF4, 0xFB, 0x102,
1590 0x109, 0x111, 0x118, 0x120, 0x128, 0x130, 0x138, 0x140,
1591 0x149, 0x151, 0x15A, 0x162, 0x16B, 0x174, 0x17D, 0x186,
1592 0x190, 0x199, 0x1A3, 0x1AC, 0x1B6, 0x1C0, 0x1CA, 0x1D5,
1593 0x1DF, 0x1EA, 0x1F4, 0x1FF, 0x20A, 0x215, 0x220, 0x22B,
1594 0x237, 0x242, 0x24E, 0x25A, 0x266, 0x272, 0x27F, 0x28B,
1595 0x298, 0x2A4, 0x2B1, 0x2BE, 0x2CB, 0x2D8, 0x2E6, 0x2F3,
1596 0x301, 0x30F, 0x31D, 0x32B, 0x339, 0x348, 0x356, 0x365,
1597 0x374, 0x383, 0x392, 0x3A1, 0x3B1, 0x3C0, 0x3D0, 0x3E0,
1598 0x3F0, 0x400, 0x411, 0x421, 0x432, 0x443, 0x454, 0x465,
1599 0x476, 0x487, 0x499, 0x4AB, 0x4BD, 0x4CF, 0x4E1, 0x4F3,
1600 0x506, 0x518, 0x52B, 0x53E, 0x551, 0x565, 0x578, 0x58C,
1601 0x5A0, 0x5B3, 0x5C8, 0x5DC, 0x5F0, 0x605, 0x61A, 0x62E,
1602 0x643, 0x659, 0x66E, 0x684, 0x699, 0x6AF, 0x6C5, 0x6DB,
1603 0x6F2, 0x708, 0x71F, 0x736, 0x74D, 0x764, 0x77C, 0x793,
1604 0x7AB, 0x7C3, 0x7DB, 0x7F3, 0x80B, 0x824, 0x83D, 0x855,
1605 0x86F, 0x888, 0x8A1, 0x8BB, 0x8D4, 0x8EE, 0x908, 0x923,
1606 0x93D, 0x958, 0x973, 0x98E, 0x9A9, 0x9C4, 0x9DF, 0x9FB,
1607 0xA17, 0xA33, 0xA4F, 0xA6C, 0xA88, 0xAA5, 0xAC2, 0xADF,
1608 0xAFC, 0xB19, 0xB37, 0xB55, 0xB73, 0xB91, 0xBAF, 0xBCE,
1609 0xBEC, 0xC0B, 0xC2A, 0xC4A, 0xC69, 0xC89, 0xCA8, 0xCC8,
1610 0xCE8, 0xD09, 0xD29, 0xD4A, 0xD6B, 0xD8C, 0xDAD, 0xDCF,
1611 0xDF0, 0xE12, 0xE34, 0xE56, 0xE79, 0xE9B, 0xEBE, 0xEE1,
1612 0xF04, 0xF27, 0xF4B, 0xF6E, 0xF92, 0xFB6, 0xFDB, 0xFFF,
1613};
1614
1615void mdp4_vg_igc_lut_setup(int vp_num)
1616{
1617 unsigned char *base;
1618 int i, voff, off;
1619 uint32 data, val;
1620
1621 voff = MDP4_VIDEO_OFF * vp_num;
1622 base = MDP_BASE + MDP4_VIDEO_BASE + voff + 0x5000;
1623
1624 off = 0;
1625 for (i = 0; i < 256; i++) {
1626 val = igc_video_lut[i];
1627 data = (val << 16 | val); /* color 0 and 1 */
1628 outpdw(base + off, data);
1629 outpdw(base + off + 0x800, val); /* color 2 */
1630 off += 4;
1631 }
1632}
1633
1634uint32 igc_rgb_lut[] = { /* linear */
1635 0x0, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
1636 0x80, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
1637 0x101, 0x111, 0x121, 0x131, 0x141, 0x151, 0x161, 0x171,
1638 0x181, 0x191, 0x1A2, 0x1B2, 0x1C2, 0x1D2, 0x1E2, 0x1F2,
1639 0x202, 0x212, 0x222, 0x232, 0x242, 0x252, 0x262, 0x272,
1640 0x282, 0x292, 0x2A2, 0x2B3, 0x2C3, 0x2D3, 0x2E3, 0x2F3,
1641 0x303, 0x313, 0x323, 0x333, 0x343, 0x353, 0x363, 0x373,
1642 0x383, 0x393, 0x3A3, 0x3B3, 0x3C4, 0x3D4, 0x3E4, 0x3F4,
1643 0x404, 0x414, 0x424, 0x434, 0x444, 0x454, 0x464, 0x474,
1644 0x484, 0x494, 0x4A4, 0x4B4, 0x4C4, 0x4D5, 0x4E5, 0x4F5,
1645 0x505, 0x515, 0x525, 0x535, 0x545, 0x555, 0x565, 0x575,
1646 0x585, 0x595, 0x5A5, 0x5B5, 0x5C5, 0x5D5, 0x5E6, 0x5F6,
1647 0x606, 0x616, 0x626, 0x636, 0x646, 0x656, 0x666, 0x676,
1648 0x686, 0x696, 0x6A6, 0x6B6, 0x6C6, 0x6D6, 0x6E6, 0x6F7,
1649 0x707, 0x717, 0x727, 0x737, 0x747, 0x757, 0x767, 0x777,
1650 0x787, 0x797, 0x7A7, 0x7B7, 0x7C7, 0x7D7, 0x7E7, 0x7F7,
1651 0x808, 0x818, 0x828, 0x838, 0x848, 0x858, 0x868, 0x878,
1652 0x888, 0x898, 0x8A8, 0x8B8, 0x8C8, 0x8D8, 0x8E8, 0x8F8,
1653 0x908, 0x919, 0x929, 0x939, 0x949, 0x959, 0x969, 0x979,
1654 0x989, 0x999, 0x9A9, 0x9B9, 0x9C9, 0x9D9, 0x9E9, 0x9F9,
1655 0xA09, 0xA19, 0xA2A, 0xA3A, 0xA4A, 0xA5A, 0xA6A, 0xA7A,
1656 0xA8A, 0xA9A, 0xAAA, 0xABA, 0xACA, 0xADA, 0xAEA, 0xAFA,
1657 0xB0A, 0xB1A, 0xB2A, 0xB3B, 0xB4B, 0xB5B, 0xB6B, 0xB7B,
1658 0xB8B, 0xB9B, 0xBAB, 0xBBB, 0xBCB, 0xBDB, 0xBEB, 0xBFB,
1659 0xC0B, 0xC1B, 0xC2B, 0xC3B, 0xC4C, 0xC5C, 0xC6C, 0xC7C,
1660 0xC8C, 0xC9C, 0xCAC, 0xCBC, 0xCCC, 0xCDC, 0xCEC, 0xCFC,
1661 0xD0C, 0xD1C, 0xD2C, 0xD3C, 0xD4C, 0xD5D, 0xD6D, 0xD7D,
1662 0xD8D, 0xD9D, 0xDAD, 0xDBD, 0xDCD, 0xDDD, 0xDED, 0xDFD,
1663 0xE0D, 0xE1D, 0xE2D, 0xE3D, 0xE4D, 0xE5D, 0xE6E, 0xE7E,
1664 0xE8E, 0xE9E, 0xEAE, 0xEBE, 0xECE, 0xEDE, 0xEEE, 0xEFE,
1665 0xF0E, 0xF1E, 0xF2E, 0xF3E, 0xF4E, 0xF5E, 0xF6E, 0xF7F,
1666 0xF8F, 0xF9F, 0xFAF, 0xFBF, 0xFCF, 0xFDF, 0xFEF, 0xFFF,
1667};
1668
1669void mdp4_rgb_igc_lut_setup(int num)
1670{
1671 unsigned char *base;
1672 int i, voff, off;
1673 uint32 data, val;
1674
1675 voff = MDP4_RGB_OFF * num;
1676 base = MDP_BASE + MDP4_RGB_BASE + voff + 0x5000;
1677
1678 off = 0;
1679 for (i = 0; i < 256; i++) {
1680 val = igc_rgb_lut[i];
1681 data = (val << 16 | val); /* color 0 and 1 */
1682 outpdw(base + off, data);
1683 outpdw(base + off + 0x800, val); /* color 2 */
1684 off += 4;
1685 }
1686}
diff --git a/drivers/staging/msm/mdp_cursor.c b/drivers/staging/msm/mdp_cursor.c
new file mode 100644
index 000000000000..7d28f30d9313
--- /dev/null
+++ b/drivers/staging/msm/mdp_cursor.c
@@ -0,0 +1,104 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/hrtimer.h>
25
26#include <mach/hardware.h>
27#include <asm/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/spinlock.h>
33
34#include <linux/fb.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38
39static int cursor_enabled;
40
41int mdp_hw_cursor_update(struct fb_info *info, struct fb_cursor *cursor)
42{
43 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
44 struct fb_image *img = &cursor->image;
45 int calpha_en, transp_en;
46 int alpha;
47 int ret = 0;
48
49 if ((img->width > MDP_CURSOR_WIDTH) ||
50 (img->height > MDP_CURSOR_HEIGHT) ||
51 (img->depth != 32))
52 return -EINVAL;
53
54 if (cursor->set & FB_CUR_SETPOS)
55 MDP_OUTP(MDP_BASE + 0x9004c, (img->dy << 16) | img->dx);
56
57 if (cursor->set & FB_CUR_SETIMAGE) {
58 ret = copy_from_user(mfd->cursor_buf, img->data,
59 img->width*img->height*4);
60 if (ret)
61 return ret;
62
63 if (img->bg_color == 0xffffffff)
64 transp_en = 0;
65 else
66 transp_en = 1;
67
68 alpha = (img->fg_color & 0xff000000) >> 24;
69
70 if (alpha)
71 calpha_en = 0x2; /* xrgb */
72 else
73 calpha_en = 0x1; /* argb */
74
75 MDP_OUTP(MDP_BASE + 0x90044, (img->height << 16) | img->width);
76 MDP_OUTP(MDP_BASE + 0x90048, mfd->cursor_buf_phys);
77 /* order the writes the cursor_buf before updating the
78 * hardware */
79// dma_coherent_pre_ops();
80 MDP_OUTP(MDP_BASE + 0x90060,
81 (transp_en << 3) | (calpha_en << 1) |
82 (inp32(MDP_BASE + 0x90060) & 0x1));
83#ifdef CONFIG_FB_MSM_MDP40
84 MDP_OUTP(MDP_BASE + 0x90064, (alpha << 24));
85 MDP_OUTP(MDP_BASE + 0x90068, (0xffffff & img->bg_color));
86 MDP_OUTP(MDP_BASE + 0x9006C, (0xffffff & img->bg_color));
87#else
88 MDP_OUTP(MDP_BASE + 0x90064,
89 (alpha << 24) | (0xffffff & img->bg_color));
90 MDP_OUTP(MDP_BASE + 0x90068, 0);
91#endif
92 }
93
94 if ((cursor->enable) && (!cursor_enabled)) {
95 cursor_enabled = 1;
96 MDP_OUTP(MDP_BASE + 0x90060, inp32(MDP_BASE + 0x90060) | 0x1);
97 } else if ((!cursor->enable) && (cursor_enabled)) {
98 cursor_enabled = 0;
99 MDP_OUTP(MDP_BASE + 0x90060,
100 inp32(MDP_BASE + 0x90060) & (~0x1));
101 }
102
103 return 0;
104}
diff --git a/drivers/staging/msm/mdp_dma.c b/drivers/staging/msm/mdp_dma.c
new file mode 100644
index 000000000000..639918b143b4
--- /dev/null
+++ b/drivers/staging/msm/mdp_dma.c
@@ -0,0 +1,561 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/hrtimer.h>
25
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/spinlock.h>
33
34#include <linux/fb.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38#include "mddihost.h"
39
40static uint32 mdp_last_dma2_update_width;
41static uint32 mdp_last_dma2_update_height;
42static uint32 mdp_curr_dma2_update_width;
43static uint32 mdp_curr_dma2_update_height;
44
45ktime_t mdp_dma2_last_update_time = { 0 };
46
47int mdp_lcd_rd_cnt_offset_slow = 20;
48int mdp_lcd_rd_cnt_offset_fast = 20;
49int mdp_vsync_usec_wait_line_too_short = 5;
50uint32 mdp_dma2_update_time_in_usec;
51uint32 mdp_total_vdopkts;
52
53extern u32 msm_fb_debug_enabled;
54extern struct workqueue_struct *mdp_dma_wq;
55
56int vsync_start_y_adjust = 4;
57
58static void mdp_dma2_update_lcd(struct msm_fb_data_type *mfd)
59{
60 MDPIBUF *iBuf = &mfd->ibuf;
61 int mddi_dest = FALSE;
62 uint32 outBpp = iBuf->bpp;
63 uint32 dma2_cfg_reg;
64 uint8 *src;
65 uint32 mddi_ld_param;
66 uint16 mddi_vdo_packet_reg;
67 struct msm_fb_panel_data *pdata =
68 (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
69 uint32 ystride = mfd->fbi->fix.line_length;
70
71 dma2_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB |
72 DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS;
73
74#ifdef CONFIG_FB_MSM_MDP30
75 /*
76 * Software workaround: On 7x25/7x27, the MDP will not
77 * respond if dma_w is 1 pixel. Set the update width to
78 * 2 pixels and adjust the x offset if needed.
79 */
80 if (iBuf->dma_w == 1) {
81 iBuf->dma_w = 2;
82 if (iBuf->dma_x == (iBuf->ibuf_width - 2))
83 iBuf->dma_x--;
84 }
85#endif
86
87 if (mfd->fb_imgType == MDP_BGR_565)
88 dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
89 else
90 dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
91
92 if (outBpp == 4)
93 dma2_cfg_reg |= DMA_IBUF_C3ALPHA_EN;
94
95 if (outBpp == 2)
96 dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
97
98 mddi_ld_param = 0;
99 mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
100
101 if ((mfd->panel_info.type == MDDI_PANEL) ||
102 (mfd->panel_info.type == EXT_MDDI_PANEL)) {
103 dma2_cfg_reg |= DMA_OUT_SEL_MDDI;
104 mddi_dest = TRUE;
105
106 if (mfd->panel_info.type == MDDI_PANEL) {
107 mdp_total_vdopkts++;
108 if (mfd->panel_info.pdest == DISPLAY_1) {
109 dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
110 mddi_ld_param = 0;
111#ifdef MDDI_HOST_WINDOW_WORKAROUND
112 mddi_window_adjust(mfd, iBuf->dma_x,
113 iBuf->dma_w - 1, iBuf->dma_y,
114 iBuf->dma_h - 1);
115#endif
116 } else {
117 dma2_cfg_reg |=
118 DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY;
119 mddi_ld_param = 1;
120#ifdef MDDI_HOST_WINDOW_WORKAROUND
121 mddi_window_adjust(mfd, iBuf->dma_x,
122 iBuf->dma_w - 1, iBuf->dma_y,
123 iBuf->dma_h - 1);
124#endif
125 }
126 } else {
127 dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL;
128 mddi_ld_param = 2;
129 }
130 } else {
131 if (mfd->panel_info.pdest == DISPLAY_1) {
132 dma2_cfg_reg |= DMA_AHBM_LCD_SEL_PRIMARY;
133 outp32(MDP_EBI2_LCD0, mfd->data_port_phys);
134 } else {
135 dma2_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY;
136 outp32(MDP_EBI2_LCD1, mfd->data_port_phys);
137 }
138 }
139
140 dma2_cfg_reg |= DMA_DITHER_EN;
141
142 src = (uint8 *) iBuf->buf;
143 /* starting input address */
144 src += iBuf->dma_x * outBpp + iBuf->dma_y * ystride;
145
146 mdp_curr_dma2_update_width = iBuf->dma_w;
147 mdp_curr_dma2_update_height = iBuf->dma_h;
148
149 /* MDP cmd block enable */
150 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
151
152#ifdef CONFIG_FB_MSM_MDP22
153 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0184,
154 (iBuf->dma_h << 16 | iBuf->dma_w));
155 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0188, src);
156 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x018C, ystride);
157#else
158 MDP_OUTP(MDP_BASE + 0x90004, (iBuf->dma_h << 16 | iBuf->dma_w));
159 MDP_OUTP(MDP_BASE + 0x90008, src);
160 MDP_OUTP(MDP_BASE + 0x9000c, ystride);
161#endif
162
163 if (mfd->panel_info.bpp == 18) {
164 dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
165 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
166 } else {
167 dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
168 DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
169 }
170
171 if (mddi_dest) {
172#ifdef CONFIG_FB_MSM_MDP22
173 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0194,
174 (iBuf->dma_y << 16) | iBuf->dma_x);
175 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0, mddi_ld_param);
176 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4,
177 (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
178#else
179 MDP_OUTP(MDP_BASE + 0x90010, (iBuf->dma_y << 16) | iBuf->dma_x);
180 MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param);
181 MDP_OUTP(MDP_BASE + 0x00094,
182 (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
183#endif
184 } else {
185 /* setting EBI2 LCDC write window */
186 pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
187 iBuf->dma_h);
188 }
189
190 /* dma2 config register */
191#ifdef MDP_HW_VSYNC
192 MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
193
194 if ((mfd->use_mdp_vsync) &&
195 (mfd->ibuf.vsync_enable) && (mfd->panel_info.lcd.vsync_enable)) {
196 uint32 start_y;
197
198 if (vsync_start_y_adjust <= iBuf->dma_y)
199 start_y = iBuf->dma_y - vsync_start_y_adjust;
200 else
201 start_y =
202 (mfd->total_lcd_lines - 1) - (vsync_start_y_adjust -
203 iBuf->dma_y);
204
205 /*
206 * MDP VSYNC clock must be On by now so, we don't have to
207 * re-enable it
208 */
209 MDP_OUTP(MDP_BASE + 0x210, start_y);
210 MDP_OUTP(MDP_BASE + 0x20c, 1); /* enable prim vsync */
211 } else {
212 MDP_OUTP(MDP_BASE + 0x20c, 0); /* disable prim vsync */
213 }
214#else
215#ifdef CONFIG_FB_MSM_MDP22
216 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0180, dma2_cfg_reg);
217#else
218 MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
219#endif
220#endif /* MDP_HW_VSYNC */
221
222 /* MDP cmd block disable */
223 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
224}
225
226static ktime_t vt = { 0 };
227int mdp_usec_diff_threshold = 100;
228int mdp_expected_usec_wait;
229
230enum hrtimer_restart mdp_dma2_vsync_hrtimer_handler(struct hrtimer *ht)
231{
232 struct msm_fb_data_type *mfd = NULL;
233
234 mfd = container_of(ht, struct msm_fb_data_type, dma_hrtimer);
235
236 mdp_pipe_kickoff(MDP_DMA2_TERM, mfd);
237
238 if (msm_fb_debug_enabled) {
239 ktime_t t;
240 int usec_diff;
241 int actual_wait;
242
243 t = ktime_get_real();
244
245 actual_wait =
246 (t.tv.sec - vt.tv.sec) * 1000000 + (t.tv.nsec -
247 vt.tv.nsec) / 1000;
248 usec_diff = actual_wait - mdp_expected_usec_wait;
249
250 if ((mdp_usec_diff_threshold < usec_diff) || (usec_diff < 0))
251 MSM_FB_DEBUG
252 ("HRT Diff = %d usec Exp=%d usec Act=%d usec\n",
253 usec_diff, mdp_expected_usec_wait, actual_wait);
254 }
255
256 return HRTIMER_NORESTART;
257}
258
259static void mdp_dma_schedule(struct msm_fb_data_type *mfd, uint32 term)
260{
261 /*
262 * dma2 configure VSYNC block
263 * vsync supported on Primary LCD only for now
264 */
265 int32 mdp_lcd_rd_cnt;
266 uint32 usec_wait_time;
267 uint32 start_y;
268
269 /*
270 * ToDo: if we can move HRT timer callback to workqueue, we can
271 * move DMA2 power on under mdp_pipe_kickoff().
272 * This will save a power for hrt time wait.
273 * However if the latency for context switch (hrt irq -> workqueue)
274 * is too big, we will miss the vsync timing.
275 */
276 if (term == MDP_DMA2_TERM)
277 mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
278
279 mdp_dma2_update_time_in_usec =
280 MDP_KTIME2USEC(mdp_dma2_last_update_time);
281
282 if ((!mfd->ibuf.vsync_enable) || (!mfd->panel_info.lcd.vsync_enable)
283 || (mfd->use_mdp_vsync)) {
284 mdp_pipe_kickoff(term, mfd);
285 return;
286 }
287 /* SW vsync logic starts here */
288
289 /* get current rd counter */
290 mdp_lcd_rd_cnt = mdp_get_lcd_line_counter(mfd);
291 if (mdp_dma2_update_time_in_usec != 0) {
292 uint32 num, den;
293
294 /*
295 * roi width boundary calculation to know the size of pixel
296 * width that MDP can send faster or slower than LCD read
297 * pointer
298 */
299
300 num = mdp_last_dma2_update_width * mdp_last_dma2_update_height;
301 den =
302 (((mfd->panel_info.lcd.refx100 * mfd->total_lcd_lines) /
303 1000) * (mdp_dma2_update_time_in_usec / 100)) / 1000;
304
305 if (den == 0)
306 mfd->vsync_width_boundary[mdp_last_dma2_update_width] =
307 mfd->panel_info.xres + 1;
308 else
309 mfd->vsync_width_boundary[mdp_last_dma2_update_width] =
310 (int)(num / den);
311 }
312
313 if (mfd->vsync_width_boundary[mdp_last_dma2_update_width] >
314 mdp_curr_dma2_update_width) {
315 /* MDP wrp is faster than LCD rdp */
316 mdp_lcd_rd_cnt += mdp_lcd_rd_cnt_offset_fast;
317 } else {
318 /* MDP wrp is slower than LCD rdp */
319 mdp_lcd_rd_cnt -= mdp_lcd_rd_cnt_offset_slow;
320 }
321
322 if (mdp_lcd_rd_cnt < 0)
323 mdp_lcd_rd_cnt = mfd->total_lcd_lines + mdp_lcd_rd_cnt;
324 else if (mdp_lcd_rd_cnt > mfd->total_lcd_lines)
325 mdp_lcd_rd_cnt = mdp_lcd_rd_cnt - mfd->total_lcd_lines - 1;
326
327 /* get wrt pointer position */
328 start_y = mfd->ibuf.dma_y;
329
330 /* measure line difference between start_y and rd counter */
331 if (start_y > mdp_lcd_rd_cnt) {
332 /*
333 * *100 for lcd_ref_hzx100 was already multiplied by 100
334 * *1000000 is for usec conversion
335 */
336
337 if ((start_y - mdp_lcd_rd_cnt) <=
338 mdp_vsync_usec_wait_line_too_short)
339 usec_wait_time = 0;
340 else
341 usec_wait_time =
342 ((start_y -
343 mdp_lcd_rd_cnt) * 1000000) /
344 ((mfd->total_lcd_lines *
345 mfd->panel_info.lcd.refx100) / 100);
346 } else {
347 if ((start_y + (mfd->total_lcd_lines - mdp_lcd_rd_cnt)) <=
348 mdp_vsync_usec_wait_line_too_short)
349 usec_wait_time = 0;
350 else
351 usec_wait_time =
352 ((start_y +
353 (mfd->total_lcd_lines -
354 mdp_lcd_rd_cnt)) * 1000000) /
355 ((mfd->total_lcd_lines *
356 mfd->panel_info.lcd.refx100) / 100);
357 }
358
359 mdp_last_dma2_update_width = mdp_curr_dma2_update_width;
360 mdp_last_dma2_update_height = mdp_curr_dma2_update_height;
361
362 if (usec_wait_time == 0) {
363 mdp_pipe_kickoff(term, mfd);
364 } else {
365 ktime_t wait_time;
366
367 wait_time.tv.sec = 0;
368 wait_time.tv.nsec = usec_wait_time * 1000;
369
370 if (msm_fb_debug_enabled) {
371 vt = ktime_get_real();
372 mdp_expected_usec_wait = usec_wait_time;
373 }
374 hrtimer_start(&mfd->dma_hrtimer, wait_time, HRTIMER_MODE_REL);
375 }
376}
377
378#ifdef MDDI_HOST_WINDOW_WORKAROUND
379void mdp_dma2_update(struct msm_fb_data_type *mfd)
380{
381 MDPIBUF *iBuf;
382 uint32 upper_height;
383
384 if (mfd->panel.type == EXT_MDDI_PANEL) {
385 mdp_dma2_update_sub(mfd);
386 return;
387 }
388
389 iBuf = &mfd->ibuf;
390
391 upper_height =
392 (uint32) mddi_assign_pkt_height((uint16) iBuf->dma_w,
393 (uint16) iBuf->dma_h, 18);
394
395 if (upper_height >= iBuf->dma_h) {
396 mdp_dma2_update_sub(mfd);
397 } else {
398 MDPIBUF lower_height;
399
400 /* sending the upper region first */
401 lower_height = iBuf->dma_h - upper_height;
402 iBuf->dma_h = upper_height;
403 mdp_dma2_update_sub(mfd);
404
405 /* sending the lower region second */
406 iBuf->dma_h = lower_height;
407 iBuf->dma_y += lower_height;
408 iBuf->vsync_enable = FALSE;
409 mdp_dma2_update_sub(mfd);
410 }
411}
412
413void mdp_dma2_update_sub(struct msm_fb_data_type *mfd)
414#else
415void mdp_dma2_update(struct msm_fb_data_type *mfd)
416#endif
417{
418 down(&mfd->dma->mutex);
419 if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
420 down(&mfd->sem);
421 mfd->ibuf_flushed = TRUE;
422 mdp_dma2_update_lcd(mfd);
423
424 mdp_enable_irq(MDP_DMA2_TERM);
425 mfd->dma->busy = TRUE;
426 INIT_COMPLETION(mfd->dma->comp);
427
428 /* schedule DMA to start */
429 mdp_dma_schedule(mfd, MDP_DMA2_TERM);
430 up(&mfd->sem);
431
432 /* wait until DMA finishes the current job */
433 wait_for_completion_killable(&mfd->dma->comp);
434 mdp_disable_irq(MDP_DMA2_TERM);
435
436 /* signal if pan function is waiting for the update completion */
437 if (mfd->pan_waiting) {
438 mfd->pan_waiting = FALSE;
439 complete(&mfd->pan_comp);
440 }
441 }
442 up(&mfd->dma->mutex);
443}
444
445void mdp_lcd_update_workqueue_handler(struct work_struct *work)
446{
447 struct msm_fb_data_type *mfd = NULL;
448
449 mfd = container_of(work, struct msm_fb_data_type, dma_update_worker);
450 if (mfd)
451 mfd->dma_fnc(mfd);
452}
453
454void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
455 boolean sync)
456{
457 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
458 MDPIBUF *iBuf;
459 int bpp = info->var.bits_per_pixel / 8;
460
461 down(&mfd->sem);
462 iBuf = &mfd->ibuf;
463 iBuf->buf = (uint8 *) info->fix.smem_start;
464 iBuf->buf += info->var.xoffset * bpp +
465 info->var.yoffset * info->fix.line_length;
466
467 iBuf->ibuf_width = info->var.xres_virtual;
468 iBuf->bpp = bpp;
469
470 iBuf->vsync_enable = sync;
471
472 if (dirty) {
473 /*
474 * ToDo: dirty region check inside var.xoffset+xres
475 * <-> var.yoffset+yres
476 */
477 iBuf->dma_x = dirty->xoffset % info->var.xres;
478 iBuf->dma_y = dirty->yoffset % info->var.yres;
479 iBuf->dma_w = dirty->width;
480 iBuf->dma_h = dirty->height;
481 } else {
482 iBuf->dma_x = 0;
483 iBuf->dma_y = 0;
484 iBuf->dma_w = info->var.xres;
485 iBuf->dma_h = info->var.yres;
486 }
487 mfd->ibuf_flushed = FALSE;
488 up(&mfd->sem);
489}
490
491void mdp_set_offset_info(struct fb_info *info, uint32 addr, uint32 sync)
492{
493 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
494 MDPIBUF *iBuf;
495
496 int bpp = info->var.bits_per_pixel / 8;
497
498 down(&mfd->sem);
499 iBuf = &mfd->ibuf;
500 iBuf->ibuf_width = info->var.xres_virtual;
501 iBuf->bpp = bpp;
502 iBuf->vsync_enable = sync;
503 iBuf->dma_x = 0;
504 iBuf->dma_y = 0;
505 iBuf->dma_w = info->var.xres;
506 iBuf->dma_h = info->var.yres;
507 iBuf->buf = (uint8 *) addr;
508
509 mfd->ibuf_flushed = FALSE;
510 up(&mfd->sem);
511}
512
513void mdp_dma_pan_update(struct fb_info *info)
514{
515 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
516 MDPIBUF *iBuf;
517
518 iBuf = &mfd->ibuf;
519
520 if (mfd->sw_currently_refreshing) {
521 /* we need to wait for the pending update */
522 mfd->pan_waiting = TRUE;
523 if (!mfd->ibuf_flushed) {
524 wait_for_completion_killable(&mfd->pan_comp);
525 }
526 /* waiting for this update to complete */
527 mfd->pan_waiting = TRUE;
528 wait_for_completion_killable(&mfd->pan_comp);
529 } else
530 mfd->dma_fnc(mfd);
531}
532
533void mdp_refresh_screen(unsigned long data)
534{
535 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
536
537 if ((mfd->sw_currently_refreshing) && (mfd->sw_refreshing_enable)) {
538 init_timer(&mfd->refresh_timer);
539 mfd->refresh_timer.function = mdp_refresh_screen;
540 mfd->refresh_timer.data = data;
541
542 if (mfd->dma->busy)
543 /* come back in 1 msec */
544 mfd->refresh_timer.expires = jiffies + (HZ / 1000);
545 else
546 mfd->refresh_timer.expires =
547 jiffies + mfd->refresh_timer_duration;
548
549 add_timer(&mfd->refresh_timer);
550
551 if (!mfd->dma->busy) {
552 if (!queue_work(mdp_dma_wq, &mfd->dma_update_worker)) {
553 MSM_FB_DEBUG("mdp_dma: can't queue_work! -> \
554 MDP/MDDI/LCD clock speed needs to be increased\n");
555 }
556 }
557 } else {
558 if (!mfd->hw_refresh)
559 complete(&mfd->refresher_comp);
560 }
561}
diff --git a/drivers/staging/msm/mdp_dma_lcdc.c b/drivers/staging/msm/mdp_dma_lcdc.c
new file mode 100644
index 000000000000..b57fa1a0ceb0
--- /dev/null
+++ b/drivers/staging/msm/mdp_dma_lcdc.c
@@ -0,0 +1,379 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/hrtimer.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/spinlock.h>
33
34#include <linux/fb.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38#include "mdp4.h"
39
40#ifdef CONFIG_FB_MSM_MDP40
41#define LCDC_BASE 0xC0000
42#define DTV_BASE 0xD0000
43#define DMA_E_BASE 0xB0000
44#else
45#define LCDC_BASE 0xE0000
46#endif
47
48#define DMA_P_BASE 0x90000
49
50extern spinlock_t mdp_spin_lock;
51#ifndef CONFIG_FB_MSM_MDP40
52extern uint32 mdp_intr_mask;
53#endif
54
55int first_pixel_start_x;
56int first_pixel_start_y;
57
58int mdp_lcdc_on(struct platform_device *pdev)
59{
60 int lcdc_width;
61 int lcdc_height;
62 int lcdc_bpp;
63 int lcdc_border_clr;
64 int lcdc_underflow_clr;
65 int lcdc_hsync_skew;
66
67 int hsync_period;
68 int hsync_ctrl;
69 int vsync_period;
70 int display_hctl;
71 int display_v_start;
72 int display_v_end;
73 int active_hctl;
74 int active_h_start;
75 int active_h_end;
76 int active_v_start;
77 int active_v_end;
78 int ctrl_polarity;
79 int h_back_porch;
80 int h_front_porch;
81 int v_back_porch;
82 int v_front_porch;
83 int hsync_pulse_width;
84 int vsync_pulse_width;
85 int hsync_polarity;
86 int vsync_polarity;
87 int data_en_polarity;
88 int hsync_start_x;
89 int hsync_end_x;
90 uint8 *buf;
91 int bpp;
92 uint32 dma2_cfg_reg;
93 struct fb_info *fbi;
94 struct fb_var_screeninfo *var;
95 struct msm_fb_data_type *mfd;
96 uint32 dma_base;
97 uint32 timer_base = LCDC_BASE;
98 uint32 block = MDP_DMA2_BLOCK;
99 int ret;
100
101 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
102
103 if (!mfd)
104 return -ENODEV;
105
106 if (mfd->key != MFD_KEY)
107 return -EINVAL;
108
109 fbi = mfd->fbi;
110 var = &fbi->var;
111
112 /* MDP cmd block enable */
113 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
114
115 bpp = fbi->var.bits_per_pixel / 8;
116 buf = (uint8 *) fbi->fix.smem_start;
117 buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length;
118
119 dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_DITHER_EN | DMA_OUT_SEL_LCDC;
120
121 if (mfd->fb_imgType == MDP_BGR_565)
122 dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
123 else
124 dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
125
126 if (bpp == 2)
127 dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
128 else if (bpp == 3)
129 dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888;
130 else
131 dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888;
132
133 switch (mfd->panel_info.bpp) {
134 case 24:
135 dma2_cfg_reg |= DMA_DSTC0G_8BITS |
136 DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
137 break;
138
139 case 18:
140 dma2_cfg_reg |= DMA_DSTC0G_6BITS |
141 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
142 break;
143
144 case 16:
145 dma2_cfg_reg |= DMA_DSTC0G_6BITS |
146 DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
147 break;
148
149 default:
150 printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n",
151 mfd->panel_info.bpp);
152 return -ENODEV;
153 }
154
155 /* DMA register config */
156
157 dma_base = DMA_P_BASE;
158
159#ifdef CONFIG_FB_MSM_MDP40
160 if (mfd->panel.type == HDMI_PANEL)
161 dma_base = DMA_E_BASE;
162#endif
163
164 /* starting address */
165 MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf);
166 /* active window width and height */
167 MDP_OUTP(MDP_BASE + dma_base + 0x4, ((fbi->var.yres) << 16) |
168 (fbi->var.xres));
169 /* buffer ystride */
170 MDP_OUTP(MDP_BASE + dma_base + 0xc, fbi->fix.line_length);
171 /* x/y coordinate = always 0 for lcdc */
172 MDP_OUTP(MDP_BASE + dma_base + 0x10, 0);
173 /* dma config */
174 MDP_OUTP(MDP_BASE + dma_base, dma2_cfg_reg);
175
176 /*
177 * LCDC timing setting
178 */
179 h_back_porch = var->left_margin;
180 h_front_porch = var->right_margin;
181 v_back_porch = var->upper_margin;
182 v_front_porch = var->lower_margin;
183 hsync_pulse_width = var->hsync_len;
184 vsync_pulse_width = var->vsync_len;
185 lcdc_border_clr = mfd->panel_info.lcdc.border_clr;
186 lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
187 lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
188
189 lcdc_width = mfd->panel_info.xres;
190 lcdc_height = mfd->panel_info.yres;
191 lcdc_bpp = mfd->panel_info.bpp;
192
193 hsync_period =
194 hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch;
195 hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
196 hsync_start_x = hsync_pulse_width + h_back_porch;
197 hsync_end_x = hsync_period - h_front_porch - 1;
198 display_hctl = (hsync_end_x << 16) | hsync_start_x;
199
200 vsync_period =
201 (vsync_pulse_width + v_back_porch + lcdc_height +
202 v_front_porch) * hsync_period;
203 display_v_start =
204 (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew;
205 display_v_end =
206 vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1;
207
208 if (lcdc_width != var->xres) {
209 active_h_start = hsync_start_x + first_pixel_start_x;
210 active_h_end = active_h_start + var->xres - 1;
211 active_hctl =
212 ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
213 } else {
214 active_hctl = 0;
215 }
216
217 if (lcdc_height != var->yres) {
218 active_v_start =
219 display_v_start + first_pixel_start_y * hsync_period;
220 active_v_end = active_v_start + (var->yres) * hsync_period - 1;
221 active_v_start |= ACTIVE_START_Y_EN;
222 } else {
223 active_v_start = 0;
224 active_v_end = 0;
225 }
226
227
228#ifdef CONFIG_FB_MSM_MDP40
229 if (mfd->panel.type == HDMI_PANEL) {
230 block = MDP_DMA_E_BLOCK;
231 timer_base = DTV_BASE;
232 hsync_polarity = 0;
233 vsync_polarity = 0;
234 } else {
235 hsync_polarity = 1;
236 vsync_polarity = 1;
237 }
238
239 lcdc_underflow_clr |= 0x80000000; /* enable recovery */
240#else
241 hsync_polarity = 0;
242 vsync_polarity = 0;
243#endif
244 data_en_polarity = 0;
245
246 ctrl_polarity =
247 (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);
248
249 MDP_OUTP(MDP_BASE + timer_base + 0x4, hsync_ctrl);
250 MDP_OUTP(MDP_BASE + timer_base + 0x8, vsync_period);
251 MDP_OUTP(MDP_BASE + timer_base + 0xc, vsync_pulse_width * hsync_period);
252 if (timer_base == LCDC_BASE) {
253 MDP_OUTP(MDP_BASE + timer_base + 0x10, display_hctl);
254 MDP_OUTP(MDP_BASE + timer_base + 0x14, display_v_start);
255 MDP_OUTP(MDP_BASE + timer_base + 0x18, display_v_end);
256 MDP_OUTP(MDP_BASE + timer_base + 0x28, lcdc_border_clr);
257 MDP_OUTP(MDP_BASE + timer_base + 0x2c, lcdc_underflow_clr);
258 MDP_OUTP(MDP_BASE + timer_base + 0x30, lcdc_hsync_skew);
259 MDP_OUTP(MDP_BASE + timer_base + 0x38, ctrl_polarity);
260 MDP_OUTP(MDP_BASE + timer_base + 0x1c, active_hctl);
261 MDP_OUTP(MDP_BASE + timer_base + 0x20, active_v_start);
262 MDP_OUTP(MDP_BASE + timer_base + 0x24, active_v_end);
263 } else {
264 MDP_OUTP(MDP_BASE + timer_base + 0x18, display_hctl);
265 MDP_OUTP(MDP_BASE + timer_base + 0x1c, display_v_start);
266 MDP_OUTP(MDP_BASE + timer_base + 0x20, display_v_end);
267 MDP_OUTP(MDP_BASE + timer_base + 0x40, lcdc_border_clr);
268 MDP_OUTP(MDP_BASE + timer_base + 0x44, lcdc_underflow_clr);
269 MDP_OUTP(MDP_BASE + timer_base + 0x48, lcdc_hsync_skew);
270 MDP_OUTP(MDP_BASE + timer_base + 0x50, ctrl_polarity);
271 MDP_OUTP(MDP_BASE + timer_base + 0x2c, active_hctl);
272 MDP_OUTP(MDP_BASE + timer_base + 0x30, active_v_start);
273 MDP_OUTP(MDP_BASE + timer_base + 0x38, active_v_end);
274 }
275
276 ret = panel_next_on(pdev);
277 if (ret == 0) {
278 /* enable LCDC block */
279 MDP_OUTP(MDP_BASE + timer_base, 1);
280 mdp_pipe_ctrl(block, MDP_BLOCK_POWER_ON, FALSE);
281 }
282 /* MDP cmd block disable */
283 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
284
285 return ret;
286}
287
288int mdp_lcdc_off(struct platform_device *pdev)
289{
290 int ret = 0;
291 struct msm_fb_data_type *mfd;
292 uint32 timer_base = LCDC_BASE;
293 uint32 block = MDP_DMA2_BLOCK;
294
295 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
296
297#ifdef CONFIG_FB_MSM_MDP40
298 if (mfd->panel.type == HDMI_PANEL) {
299 block = MDP_DMA_E_BLOCK;
300 timer_base = DTV_BASE;
301 }
302#endif
303
304 /* MDP cmd block enable */
305 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
306 MDP_OUTP(MDP_BASE + timer_base, 0);
307 /* MDP cmd block disable */
308 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
309 mdp_pipe_ctrl(block, MDP_BLOCK_POWER_OFF, FALSE);
310
311 ret = panel_next_off(pdev);
312
313 /* delay to make sure the last frame finishes */
314 mdelay(100);
315
316 return ret;
317}
318
319void mdp_lcdc_update(struct msm_fb_data_type *mfd)
320{
321 struct fb_info *fbi = mfd->fbi;
322 uint8 *buf;
323 int bpp;
324 unsigned long flag;
325 uint32 dma_base;
326 int irq_block = MDP_DMA2_TERM;
327#ifdef CONFIG_FB_MSM_MDP40
328 int intr = INTR_DMA_P_DONE;
329#endif
330
331 if (!mfd->panel_power_on)
332 return;
333
334 /* no need to power on cmd block since it's lcdc mode */
335
336 if (!mfd->ibuf.visible_swapped) {
337 bpp = fbi->var.bits_per_pixel / 8;
338 buf = (uint8 *) fbi->fix.smem_start;
339 buf += fbi->var.xoffset * bpp +
340 fbi->var.yoffset * fbi->fix.line_length;
341 } else {
342 /* we've done something to update the pointer. */
343 bpp = mfd->ibuf.bpp;
344 buf = mfd->ibuf.buf;
345 }
346
347 dma_base = DMA_P_BASE;
348
349#ifdef CONFIG_FB_MSM_MDP40
350 if (mfd->panel.type == HDMI_PANEL) {
351 intr = INTR_DMA_E_DONE;
352 irq_block = MDP_DMA_E_TERM;
353 dma_base = DMA_E_BASE;
354 }
355#endif
356
357 /* starting address */
358 MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf);
359
360 /* enable LCDC irq */
361 spin_lock_irqsave(&mdp_spin_lock, flag);
362 mdp_enable_irq(irq_block);
363 INIT_COMPLETION(mfd->dma->comp);
364 mfd->dma->waiting = TRUE;
365#ifdef CONFIG_FB_MSM_MDP40
366 outp32(MDP_INTR_CLEAR, intr);
367 mdp_intr_mask |= intr;
368 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
369#else
370 outp32(MDP_INTR_CLEAR, LCDC_FRAME_START);
371 mdp_intr_mask |= LCDC_FRAME_START;
372 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
373#endif
374 spin_unlock_irqrestore(&mdp_spin_lock, flag);
375
376 if (mfd->ibuf.vsync_enable)
377 wait_for_completion_killable(&mfd->dma->comp);
378 mdp_disable_irq(irq_block);
379}
diff --git a/drivers/staging/msm/mdp_dma_s.c b/drivers/staging/msm/mdp_dma_s.c
new file mode 100644
index 000000000000..0c34a1010f17
--- /dev/null
+++ b/drivers/staging/msm/mdp_dma_s.c
@@ -0,0 +1,139 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/hrtimer.h>
25
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/spinlock.h>
33
34#include <linux/fb.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38
39static void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd)
40{
41 MDPIBUF *iBuf = &mfd->ibuf;
42 int mddi_dest = FALSE;
43 uint32 outBpp = iBuf->bpp;
44 uint32 dma_s_cfg_reg;
45 uint8 *src;
46 struct msm_fb_panel_data *pdata =
47 (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
48
49 dma_s_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB |
50 DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS;
51
52 if (mfd->fb_imgType == MDP_BGR_565)
53 dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR;
54 else
55 dma_s_cfg_reg |= DMA_PACK_PATTERN_RGB;
56
57 if (outBpp == 4)
58 dma_s_cfg_reg |= DMA_IBUF_C3ALPHA_EN;
59
60 if (outBpp == 2)
61 dma_s_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
62
63 if (mfd->panel_info.pdest != DISPLAY_2) {
64 printk(KERN_ERR "error: non-secondary type through dma_s!\n");
65 return;
66 }
67
68 if (mfd->panel_info.type == MDDI_PANEL) {
69 dma_s_cfg_reg |= DMA_OUT_SEL_MDDI;
70 mddi_dest = TRUE;
71 } else {
72 dma_s_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY;
73 outp32(MDP_EBI2_LCD1, mfd->data_port_phys);
74 }
75
76 dma_s_cfg_reg |= DMA_DITHER_EN;
77
78 src = (uint8 *) iBuf->buf;
79 /* starting input address */
80 src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * outBpp;
81
82 /* MDP cmd block enable */
83 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
84 /* PIXELSIZE */
85 MDP_OUTP(MDP_BASE + 0xa0004, (iBuf->dma_h << 16 | iBuf->dma_w));
86 MDP_OUTP(MDP_BASE + 0xa0008, src); /* ibuf address */
87 MDP_OUTP(MDP_BASE + 0xa000c, iBuf->ibuf_width * outBpp);/* ystride */
88
89 if (mfd->panel_info.bpp == 18) {
90 dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
91 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
92 } else {
93 dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
94 DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
95 }
96
97 if (mddi_dest) {
98 MDP_OUTP(MDP_BASE + 0xa0010, (iBuf->dma_y << 16) | iBuf->dma_x);
99 MDP_OUTP(MDP_BASE + 0x00090, 1);
100 MDP_OUTP(MDP_BASE + 0x00094,
101 (MDDI_VDO_PACKET_DESC << 16) |
102 mfd->panel_info.mddi.vdopkt);
103 } else {
104 /* setting LCDC write window */
105 pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
106 iBuf->dma_h);
107 }
108
109 MDP_OUTP(MDP_BASE + 0xa0000, dma_s_cfg_reg);
110
111 /* MDP cmd block disable */
112 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
113 mdp_pipe_kickoff(MDP_DMA_S_TERM, mfd);
114}
115
116void mdp_dma_s_update(struct msm_fb_data_type *mfd)
117{
118 down(&mfd->dma->mutex);
119 if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
120 down(&mfd->sem);
121 mdp_enable_irq(MDP_DMA_S_TERM);
122 mfd->dma->busy = TRUE;
123 INIT_COMPLETION(mfd->dma->comp);
124 mfd->ibuf_flushed = TRUE;
125 mdp_dma_s_update_lcd(mfd);
126 up(&mfd->sem);
127
128 /* wait until DMA finishes the current job */
129 wait_for_completion_killable(&mfd->dma->comp);
130 mdp_disable_irq(MDP_DMA_S_TERM);
131
132 /* signal if pan function is waiting for the update completion */
133 if (mfd->pan_waiting) {
134 mfd->pan_waiting = FALSE;
135 complete(&mfd->pan_comp);
136 }
137 }
138 up(&mfd->dma->mutex);
139}
diff --git a/drivers/staging/msm/mdp_dma_tv.c b/drivers/staging/msm/mdp_dma_tv.c
new file mode 100644
index 000000000000..70989fb32c1d
--- /dev/null
+++ b/drivers/staging/msm/mdp_dma_tv.c
@@ -0,0 +1,142 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/hrtimer.h>
25#include <linux/delay.h>
26
27#include <mach/hardware.h>
28#include <linux/io.h>
29
30#include <asm/system.h>
31#include <asm/mach-types.h>
32#include <linux/semaphore.h>
33#include <linux/spinlock.h>
34
35#include <linux/fb.h>
36
37#include "mdp.h"
38#include "msm_fb.h"
39
40extern spinlock_t mdp_spin_lock;
41extern uint32 mdp_intr_mask;
42
43int mdp_dma3_on(struct platform_device *pdev)
44{
45 struct msm_fb_data_type *mfd;
46 struct fb_info *fbi;
47 uint8 *buf;
48 int bpp;
49 int ret = 0;
50
51 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
52
53 if (!mfd)
54 return -ENODEV;
55
56 if (mfd->key != MFD_KEY)
57 return -EINVAL;
58
59 fbi = mfd->fbi;
60 /* MDP cmd block enable */
61 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
62
63 bpp = fbi->var.bits_per_pixel / 8;
64 buf = (uint8 *) fbi->fix.smem_start;
65 buf += fbi->var.xoffset * bpp +
66 fbi->var.yoffset * fbi->fix.line_length;
67
68 /* starting address[31..8] of Video frame buffer is CS0 */
69 MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3);
70
71 mdp_pipe_ctrl(MDP_DMA3_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
72
73 MDP_OUTP(MDP_BASE + 0xC0004, 0x4c60674); /* flicker filter enabled */
74 MDP_OUTP(MDP_BASE + 0xC0010, 0x20); /* sobel treshold */
75
76 MDP_OUTP(MDP_BASE + 0xC0018, 0xeb0010); /* Y Max, Y min */
77 MDP_OUTP(MDP_BASE + 0xC001C, 0xf00010); /* Cb Max, Cb min */
78 MDP_OUTP(MDP_BASE + 0xC0020, 0xf00010); /* Cb Max, Cb min */
79
80 MDP_OUTP(MDP_BASE + 0xC000C, 0x67686970); /* add a few chars for CC */
81 MDP_OUTP(MDP_BASE + 0xC0000, 0x1); /* MDP tv out enable */
82
83 /* MDP cmd block disable */
84 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
85
86 ret = panel_next_on(pdev);
87
88 return ret;
89}
90
91int mdp_dma3_off(struct platform_device *pdev)
92{
93 int ret = 0;
94
95 ret = panel_next_off(pdev);
96 if (ret)
97 return ret;
98
99 /* MDP cmd block enable */
100 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
101 MDP_OUTP(MDP_BASE + 0xC0000, 0x0);
102 /* MDP cmd block disable */
103 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
104
105 mdp_pipe_ctrl(MDP_DMA3_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
106
107 /* delay to make sure the last frame finishes */
108 mdelay(100);
109
110 return ret;
111}
112
113void mdp_dma3_update(struct msm_fb_data_type *mfd)
114{
115 struct fb_info *fbi = mfd->fbi;
116 uint8 *buf;
117 int bpp;
118 unsigned long flag;
119
120 if (!mfd->panel_power_on)
121 return;
122
123 /* no need to power on cmd block since dma3 is running */
124 bpp = fbi->var.bits_per_pixel / 8;
125 buf = (uint8 *) fbi->fix.smem_start;
126 buf += fbi->var.xoffset * bpp +
127 fbi->var.yoffset * fbi->fix.line_length;
128 MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3);
129
130 spin_lock_irqsave(&mdp_spin_lock, flag);
131 mdp_enable_irq(MDP_DMA3_TERM);
132 INIT_COMPLETION(mfd->dma->comp);
133 mfd->dma->waiting = TRUE;
134
135 outp32(MDP_INTR_CLEAR, TV_OUT_DMA3_START);
136 mdp_intr_mask |= TV_OUT_DMA3_START;
137 outp32(MDP_INTR_ENABLE, mdp_intr_mask);
138 spin_unlock_irqrestore(&mdp_spin_lock, flag);
139
140 wait_for_completion_killable(&mfd->dma->comp);
141 mdp_disable_irq(MDP_DMA3_TERM);
142}
diff --git a/drivers/staging/msm/mdp_hw_init.c b/drivers/staging/msm/mdp_hw_init.c
new file mode 100644
index 000000000000..807362ac592c
--- /dev/null
+++ b/drivers/staging/msm/mdp_hw_init.c
@@ -0,0 +1,720 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "mdp.h"
19
20/* mdp primary csc limit vector */
21uint32 mdp_plv[] = { 0x10, 0xeb, 0x10, 0xf0 };
22
23/* Color Coefficient matrix for YUV -> RGB */
24struct mdp_ccs mdp_ccs_yuv2rgb = {
25 MDP_CCS_YUV2RGB,
26 {
27 0x254,
28 0x000,
29 0x331,
30 0x254,
31 0xff38,
32 0xfe61,
33 0x254,
34 0x409,
35 0x000,
36 },
37 {
38#ifdef CONFIG_FB_MSM_MDP31
39 0x1f0,
40 0x180,
41 0x180
42#else
43 0x10,
44 0x80,
45 0x80
46#endif
47 }
48};
49
50/* Color Coefficient matrix for RGB -> YUV */
51struct mdp_ccs mdp_ccs_rgb2yuv = {
52 MDP_CCS_RGB2YUV,
53 {
54 0x83,
55 0x102,
56 0x32,
57 0xffb5,
58 0xff6c,
59 0xe1,
60 0xe1,
61 0xff45,
62 0xffdc,
63 },
64#ifdef CONFIG_FB_MSM_MDP31
65 {
66 0x10,
67 0x80,
68 0x80
69 }
70#endif
71};
72
73static void mdp_load_lut_param(void)
74{
75 outpdw(MDP_BASE + 0x40800, 0x0);
76 outpdw(MDP_BASE + 0x40804, 0x151515);
77 outpdw(MDP_BASE + 0x40808, 0x1d1d1d);
78 outpdw(MDP_BASE + 0x4080c, 0x232323);
79 outpdw(MDP_BASE + 0x40810, 0x272727);
80 outpdw(MDP_BASE + 0x40814, 0x2b2b2b);
81 outpdw(MDP_BASE + 0x40818, 0x2f2f2f);
82 outpdw(MDP_BASE + 0x4081c, 0x333333);
83 outpdw(MDP_BASE + 0x40820, 0x363636);
84 outpdw(MDP_BASE + 0x40824, 0x393939);
85 outpdw(MDP_BASE + 0x40828, 0x3b3b3b);
86 outpdw(MDP_BASE + 0x4082c, 0x3e3e3e);
87 outpdw(MDP_BASE + 0x40830, 0x404040);
88 outpdw(MDP_BASE + 0x40834, 0x434343);
89 outpdw(MDP_BASE + 0x40838, 0x454545);
90 outpdw(MDP_BASE + 0x4083c, 0x474747);
91 outpdw(MDP_BASE + 0x40840, 0x494949);
92 outpdw(MDP_BASE + 0x40844, 0x4b4b4b);
93 outpdw(MDP_BASE + 0x40848, 0x4d4d4d);
94 outpdw(MDP_BASE + 0x4084c, 0x4f4f4f);
95 outpdw(MDP_BASE + 0x40850, 0x515151);
96 outpdw(MDP_BASE + 0x40854, 0x535353);
97 outpdw(MDP_BASE + 0x40858, 0x555555);
98 outpdw(MDP_BASE + 0x4085c, 0x565656);
99 outpdw(MDP_BASE + 0x40860, 0x585858);
100 outpdw(MDP_BASE + 0x40864, 0x5a5a5a);
101 outpdw(MDP_BASE + 0x40868, 0x5b5b5b);
102 outpdw(MDP_BASE + 0x4086c, 0x5d5d5d);
103 outpdw(MDP_BASE + 0x40870, 0x5e5e5e);
104 outpdw(MDP_BASE + 0x40874, 0x606060);
105 outpdw(MDP_BASE + 0x40878, 0x616161);
106 outpdw(MDP_BASE + 0x4087c, 0x636363);
107 outpdw(MDP_BASE + 0x40880, 0x646464);
108 outpdw(MDP_BASE + 0x40884, 0x666666);
109 outpdw(MDP_BASE + 0x40888, 0x676767);
110 outpdw(MDP_BASE + 0x4088c, 0x686868);
111 outpdw(MDP_BASE + 0x40890, 0x6a6a6a);
112 outpdw(MDP_BASE + 0x40894, 0x6b6b6b);
113 outpdw(MDP_BASE + 0x40898, 0x6c6c6c);
114 outpdw(MDP_BASE + 0x4089c, 0x6e6e6e);
115 outpdw(MDP_BASE + 0x408a0, 0x6f6f6f);
116 outpdw(MDP_BASE + 0x408a4, 0x707070);
117 outpdw(MDP_BASE + 0x408a8, 0x717171);
118 outpdw(MDP_BASE + 0x408ac, 0x727272);
119 outpdw(MDP_BASE + 0x408b0, 0x747474);
120 outpdw(MDP_BASE + 0x408b4, 0x757575);
121 outpdw(MDP_BASE + 0x408b8, 0x767676);
122 outpdw(MDP_BASE + 0x408bc, 0x777777);
123 outpdw(MDP_BASE + 0x408c0, 0x787878);
124 outpdw(MDP_BASE + 0x408c4, 0x797979);
125 outpdw(MDP_BASE + 0x408c8, 0x7a7a7a);
126 outpdw(MDP_BASE + 0x408cc, 0x7c7c7c);
127 outpdw(MDP_BASE + 0x408d0, 0x7d7d7d);
128 outpdw(MDP_BASE + 0x408d4, 0x7e7e7e);
129 outpdw(MDP_BASE + 0x408d8, 0x7f7f7f);
130 outpdw(MDP_BASE + 0x408dc, 0x808080);
131 outpdw(MDP_BASE + 0x408e0, 0x818181);
132 outpdw(MDP_BASE + 0x408e4, 0x828282);
133 outpdw(MDP_BASE + 0x408e8, 0x838383);
134 outpdw(MDP_BASE + 0x408ec, 0x848484);
135 outpdw(MDP_BASE + 0x408f0, 0x858585);
136 outpdw(MDP_BASE + 0x408f4, 0x868686);
137 outpdw(MDP_BASE + 0x408f8, 0x878787);
138 outpdw(MDP_BASE + 0x408fc, 0x888888);
139 outpdw(MDP_BASE + 0x40900, 0x898989);
140 outpdw(MDP_BASE + 0x40904, 0x8a8a8a);
141 outpdw(MDP_BASE + 0x40908, 0x8b8b8b);
142 outpdw(MDP_BASE + 0x4090c, 0x8c8c8c);
143 outpdw(MDP_BASE + 0x40910, 0x8d8d8d);
144 outpdw(MDP_BASE + 0x40914, 0x8e8e8e);
145 outpdw(MDP_BASE + 0x40918, 0x8f8f8f);
146 outpdw(MDP_BASE + 0x4091c, 0x8f8f8f);
147 outpdw(MDP_BASE + 0x40920, 0x909090);
148 outpdw(MDP_BASE + 0x40924, 0x919191);
149 outpdw(MDP_BASE + 0x40928, 0x929292);
150 outpdw(MDP_BASE + 0x4092c, 0x939393);
151 outpdw(MDP_BASE + 0x40930, 0x949494);
152 outpdw(MDP_BASE + 0x40934, 0x959595);
153 outpdw(MDP_BASE + 0x40938, 0x969696);
154 outpdw(MDP_BASE + 0x4093c, 0x969696);
155 outpdw(MDP_BASE + 0x40940, 0x979797);
156 outpdw(MDP_BASE + 0x40944, 0x989898);
157 outpdw(MDP_BASE + 0x40948, 0x999999);
158 outpdw(MDP_BASE + 0x4094c, 0x9a9a9a);
159 outpdw(MDP_BASE + 0x40950, 0x9b9b9b);
160 outpdw(MDP_BASE + 0x40954, 0x9c9c9c);
161 outpdw(MDP_BASE + 0x40958, 0x9c9c9c);
162 outpdw(MDP_BASE + 0x4095c, 0x9d9d9d);
163 outpdw(MDP_BASE + 0x40960, 0x9e9e9e);
164 outpdw(MDP_BASE + 0x40964, 0x9f9f9f);
165 outpdw(MDP_BASE + 0x40968, 0xa0a0a0);
166 outpdw(MDP_BASE + 0x4096c, 0xa0a0a0);
167 outpdw(MDP_BASE + 0x40970, 0xa1a1a1);
168 outpdw(MDP_BASE + 0x40974, 0xa2a2a2);
169 outpdw(MDP_BASE + 0x40978, 0xa3a3a3);
170 outpdw(MDP_BASE + 0x4097c, 0xa4a4a4);
171 outpdw(MDP_BASE + 0x40980, 0xa4a4a4);
172 outpdw(MDP_BASE + 0x40984, 0xa5a5a5);
173 outpdw(MDP_BASE + 0x40988, 0xa6a6a6);
174 outpdw(MDP_BASE + 0x4098c, 0xa7a7a7);
175 outpdw(MDP_BASE + 0x40990, 0xa7a7a7);
176 outpdw(MDP_BASE + 0x40994, 0xa8a8a8);
177 outpdw(MDP_BASE + 0x40998, 0xa9a9a9);
178 outpdw(MDP_BASE + 0x4099c, 0xaaaaaa);
179 outpdw(MDP_BASE + 0x409a0, 0xaaaaaa);
180 outpdw(MDP_BASE + 0x409a4, 0xababab);
181 outpdw(MDP_BASE + 0x409a8, 0xacacac);
182 outpdw(MDP_BASE + 0x409ac, 0xadadad);
183 outpdw(MDP_BASE + 0x409b0, 0xadadad);
184 outpdw(MDP_BASE + 0x409b4, 0xaeaeae);
185 outpdw(MDP_BASE + 0x409b8, 0xafafaf);
186 outpdw(MDP_BASE + 0x409bc, 0xafafaf);
187 outpdw(MDP_BASE + 0x409c0, 0xb0b0b0);
188 outpdw(MDP_BASE + 0x409c4, 0xb1b1b1);
189 outpdw(MDP_BASE + 0x409c8, 0xb2b2b2);
190 outpdw(MDP_BASE + 0x409cc, 0xb2b2b2);
191 outpdw(MDP_BASE + 0x409d0, 0xb3b3b3);
192 outpdw(MDP_BASE + 0x409d4, 0xb4b4b4);
193 outpdw(MDP_BASE + 0x409d8, 0xb4b4b4);
194 outpdw(MDP_BASE + 0x409dc, 0xb5b5b5);
195 outpdw(MDP_BASE + 0x409e0, 0xb6b6b6);
196 outpdw(MDP_BASE + 0x409e4, 0xb6b6b6);
197 outpdw(MDP_BASE + 0x409e8, 0xb7b7b7);
198 outpdw(MDP_BASE + 0x409ec, 0xb8b8b8);
199 outpdw(MDP_BASE + 0x409f0, 0xb8b8b8);
200 outpdw(MDP_BASE + 0x409f4, 0xb9b9b9);
201 outpdw(MDP_BASE + 0x409f8, 0xbababa);
202 outpdw(MDP_BASE + 0x409fc, 0xbababa);
203 outpdw(MDP_BASE + 0x40a00, 0xbbbbbb);
204 outpdw(MDP_BASE + 0x40a04, 0xbcbcbc);
205 outpdw(MDP_BASE + 0x40a08, 0xbcbcbc);
206 outpdw(MDP_BASE + 0x40a0c, 0xbdbdbd);
207 outpdw(MDP_BASE + 0x40a10, 0xbebebe);
208 outpdw(MDP_BASE + 0x40a14, 0xbebebe);
209 outpdw(MDP_BASE + 0x40a18, 0xbfbfbf);
210 outpdw(MDP_BASE + 0x40a1c, 0xc0c0c0);
211 outpdw(MDP_BASE + 0x40a20, 0xc0c0c0);
212 outpdw(MDP_BASE + 0x40a24, 0xc1c1c1);
213 outpdw(MDP_BASE + 0x40a28, 0xc1c1c1);
214 outpdw(MDP_BASE + 0x40a2c, 0xc2c2c2);
215 outpdw(MDP_BASE + 0x40a30, 0xc3c3c3);
216 outpdw(MDP_BASE + 0x40a34, 0xc3c3c3);
217 outpdw(MDP_BASE + 0x40a38, 0xc4c4c4);
218 outpdw(MDP_BASE + 0x40a3c, 0xc5c5c5);
219 outpdw(MDP_BASE + 0x40a40, 0xc5c5c5);
220 outpdw(MDP_BASE + 0x40a44, 0xc6c6c6);
221 outpdw(MDP_BASE + 0x40a48, 0xc6c6c6);
222 outpdw(MDP_BASE + 0x40a4c, 0xc7c7c7);
223 outpdw(MDP_BASE + 0x40a50, 0xc8c8c8);
224 outpdw(MDP_BASE + 0x40a54, 0xc8c8c8);
225 outpdw(MDP_BASE + 0x40a58, 0xc9c9c9);
226 outpdw(MDP_BASE + 0x40a5c, 0xc9c9c9);
227 outpdw(MDP_BASE + 0x40a60, 0xcacaca);
228 outpdw(MDP_BASE + 0x40a64, 0xcbcbcb);
229 outpdw(MDP_BASE + 0x40a68, 0xcbcbcb);
230 outpdw(MDP_BASE + 0x40a6c, 0xcccccc);
231 outpdw(MDP_BASE + 0x40a70, 0xcccccc);
232 outpdw(MDP_BASE + 0x40a74, 0xcdcdcd);
233 outpdw(MDP_BASE + 0x40a78, 0xcecece);
234 outpdw(MDP_BASE + 0x40a7c, 0xcecece);
235 outpdw(MDP_BASE + 0x40a80, 0xcfcfcf);
236 outpdw(MDP_BASE + 0x40a84, 0xcfcfcf);
237 outpdw(MDP_BASE + 0x40a88, 0xd0d0d0);
238 outpdw(MDP_BASE + 0x40a8c, 0xd0d0d0);
239 outpdw(MDP_BASE + 0x40a90, 0xd1d1d1);
240 outpdw(MDP_BASE + 0x40a94, 0xd2d2d2);
241 outpdw(MDP_BASE + 0x40a98, 0xd2d2d2);
242 outpdw(MDP_BASE + 0x40a9c, 0xd3d3d3);
243 outpdw(MDP_BASE + 0x40aa0, 0xd3d3d3);
244 outpdw(MDP_BASE + 0x40aa4, 0xd4d4d4);
245 outpdw(MDP_BASE + 0x40aa8, 0xd4d4d4);
246 outpdw(MDP_BASE + 0x40aac, 0xd5d5d5);
247 outpdw(MDP_BASE + 0x40ab0, 0xd6d6d6);
248 outpdw(MDP_BASE + 0x40ab4, 0xd6d6d6);
249 outpdw(MDP_BASE + 0x40ab8, 0xd7d7d7);
250 outpdw(MDP_BASE + 0x40abc, 0xd7d7d7);
251 outpdw(MDP_BASE + 0x40ac0, 0xd8d8d8);
252 outpdw(MDP_BASE + 0x40ac4, 0xd8d8d8);
253 outpdw(MDP_BASE + 0x40ac8, 0xd9d9d9);
254 outpdw(MDP_BASE + 0x40acc, 0xd9d9d9);
255 outpdw(MDP_BASE + 0x40ad0, 0xdadada);
256 outpdw(MDP_BASE + 0x40ad4, 0xdbdbdb);
257 outpdw(MDP_BASE + 0x40ad8, 0xdbdbdb);
258 outpdw(MDP_BASE + 0x40adc, 0xdcdcdc);
259 outpdw(MDP_BASE + 0x40ae0, 0xdcdcdc);
260 outpdw(MDP_BASE + 0x40ae4, 0xdddddd);
261 outpdw(MDP_BASE + 0x40ae8, 0xdddddd);
262 outpdw(MDP_BASE + 0x40aec, 0xdedede);
263 outpdw(MDP_BASE + 0x40af0, 0xdedede);
264 outpdw(MDP_BASE + 0x40af4, 0xdfdfdf);
265 outpdw(MDP_BASE + 0x40af8, 0xdfdfdf);
266 outpdw(MDP_BASE + 0x40afc, 0xe0e0e0);
267 outpdw(MDP_BASE + 0x40b00, 0xe0e0e0);
268 outpdw(MDP_BASE + 0x40b04, 0xe1e1e1);
269 outpdw(MDP_BASE + 0x40b08, 0xe1e1e1);
270 outpdw(MDP_BASE + 0x40b0c, 0xe2e2e2);
271 outpdw(MDP_BASE + 0x40b10, 0xe3e3e3);
272 outpdw(MDP_BASE + 0x40b14, 0xe3e3e3);
273 outpdw(MDP_BASE + 0x40b18, 0xe4e4e4);
274 outpdw(MDP_BASE + 0x40b1c, 0xe4e4e4);
275 outpdw(MDP_BASE + 0x40b20, 0xe5e5e5);
276 outpdw(MDP_BASE + 0x40b24, 0xe5e5e5);
277 outpdw(MDP_BASE + 0x40b28, 0xe6e6e6);
278 outpdw(MDP_BASE + 0x40b2c, 0xe6e6e6);
279 outpdw(MDP_BASE + 0x40b30, 0xe7e7e7);
280 outpdw(MDP_BASE + 0x40b34, 0xe7e7e7);
281 outpdw(MDP_BASE + 0x40b38, 0xe8e8e8);
282 outpdw(MDP_BASE + 0x40b3c, 0xe8e8e8);
283 outpdw(MDP_BASE + 0x40b40, 0xe9e9e9);
284 outpdw(MDP_BASE + 0x40b44, 0xe9e9e9);
285 outpdw(MDP_BASE + 0x40b48, 0xeaeaea);
286 outpdw(MDP_BASE + 0x40b4c, 0xeaeaea);
287 outpdw(MDP_BASE + 0x40b50, 0xebebeb);
288 outpdw(MDP_BASE + 0x40b54, 0xebebeb);
289 outpdw(MDP_BASE + 0x40b58, 0xececec);
290 outpdw(MDP_BASE + 0x40b5c, 0xececec);
291 outpdw(MDP_BASE + 0x40b60, 0xededed);
292 outpdw(MDP_BASE + 0x40b64, 0xededed);
293 outpdw(MDP_BASE + 0x40b68, 0xeeeeee);
294 outpdw(MDP_BASE + 0x40b6c, 0xeeeeee);
295 outpdw(MDP_BASE + 0x40b70, 0xefefef);
296 outpdw(MDP_BASE + 0x40b74, 0xefefef);
297 outpdw(MDP_BASE + 0x40b78, 0xf0f0f0);
298 outpdw(MDP_BASE + 0x40b7c, 0xf0f0f0);
299 outpdw(MDP_BASE + 0x40b80, 0xf1f1f1);
300 outpdw(MDP_BASE + 0x40b84, 0xf1f1f1);
301 outpdw(MDP_BASE + 0x40b88, 0xf2f2f2);
302 outpdw(MDP_BASE + 0x40b8c, 0xf2f2f2);
303 outpdw(MDP_BASE + 0x40b90, 0xf2f2f2);
304 outpdw(MDP_BASE + 0x40b94, 0xf3f3f3);
305 outpdw(MDP_BASE + 0x40b98, 0xf3f3f3);
306 outpdw(MDP_BASE + 0x40b9c, 0xf4f4f4);
307 outpdw(MDP_BASE + 0x40ba0, 0xf4f4f4);
308 outpdw(MDP_BASE + 0x40ba4, 0xf5f5f5);
309 outpdw(MDP_BASE + 0x40ba8, 0xf5f5f5);
310 outpdw(MDP_BASE + 0x40bac, 0xf6f6f6);
311 outpdw(MDP_BASE + 0x40bb0, 0xf6f6f6);
312 outpdw(MDP_BASE + 0x40bb4, 0xf7f7f7);
313 outpdw(MDP_BASE + 0x40bb8, 0xf7f7f7);
314 outpdw(MDP_BASE + 0x40bbc, 0xf8f8f8);
315 outpdw(MDP_BASE + 0x40bc0, 0xf8f8f8);
316 outpdw(MDP_BASE + 0x40bc4, 0xf9f9f9);
317 outpdw(MDP_BASE + 0x40bc8, 0xf9f9f9);
318 outpdw(MDP_BASE + 0x40bcc, 0xfafafa);
319 outpdw(MDP_BASE + 0x40bd0, 0xfafafa);
320 outpdw(MDP_BASE + 0x40bd4, 0xfafafa);
321 outpdw(MDP_BASE + 0x40bd8, 0xfbfbfb);
322 outpdw(MDP_BASE + 0x40bdc, 0xfbfbfb);
323 outpdw(MDP_BASE + 0x40be0, 0xfcfcfc);
324 outpdw(MDP_BASE + 0x40be4, 0xfcfcfc);
325 outpdw(MDP_BASE + 0x40be8, 0xfdfdfd);
326 outpdw(MDP_BASE + 0x40bec, 0xfdfdfd);
327 outpdw(MDP_BASE + 0x40bf0, 0xfefefe);
328 outpdw(MDP_BASE + 0x40bf4, 0xfefefe);
329 outpdw(MDP_BASE + 0x40bf8, 0xffffff);
330 outpdw(MDP_BASE + 0x40bfc, 0xffffff);
331 outpdw(MDP_BASE + 0x40c00, 0x0);
332 outpdw(MDP_BASE + 0x40c04, 0x0);
333 outpdw(MDP_BASE + 0x40c08, 0x0);
334 outpdw(MDP_BASE + 0x40c0c, 0x0);
335 outpdw(MDP_BASE + 0x40c10, 0x0);
336 outpdw(MDP_BASE + 0x40c14, 0x0);
337 outpdw(MDP_BASE + 0x40c18, 0x0);
338 outpdw(MDP_BASE + 0x40c1c, 0x0);
339 outpdw(MDP_BASE + 0x40c20, 0x0);
340 outpdw(MDP_BASE + 0x40c24, 0x0);
341 outpdw(MDP_BASE + 0x40c28, 0x0);
342 outpdw(MDP_BASE + 0x40c2c, 0x0);
343 outpdw(MDP_BASE + 0x40c30, 0x0);
344 outpdw(MDP_BASE + 0x40c34, 0x0);
345 outpdw(MDP_BASE + 0x40c38, 0x0);
346 outpdw(MDP_BASE + 0x40c3c, 0x0);
347 outpdw(MDP_BASE + 0x40c40, 0x10101);
348 outpdw(MDP_BASE + 0x40c44, 0x10101);
349 outpdw(MDP_BASE + 0x40c48, 0x10101);
350 outpdw(MDP_BASE + 0x40c4c, 0x10101);
351 outpdw(MDP_BASE + 0x40c50, 0x10101);
352 outpdw(MDP_BASE + 0x40c54, 0x10101);
353 outpdw(MDP_BASE + 0x40c58, 0x10101);
354 outpdw(MDP_BASE + 0x40c5c, 0x10101);
355 outpdw(MDP_BASE + 0x40c60, 0x10101);
356 outpdw(MDP_BASE + 0x40c64, 0x10101);
357 outpdw(MDP_BASE + 0x40c68, 0x20202);
358 outpdw(MDP_BASE + 0x40c6c, 0x20202);
359 outpdw(MDP_BASE + 0x40c70, 0x20202);
360 outpdw(MDP_BASE + 0x40c74, 0x20202);
361 outpdw(MDP_BASE + 0x40c78, 0x20202);
362 outpdw(MDP_BASE + 0x40c7c, 0x20202);
363 outpdw(MDP_BASE + 0x40c80, 0x30303);
364 outpdw(MDP_BASE + 0x40c84, 0x30303);
365 outpdw(MDP_BASE + 0x40c88, 0x30303);
366 outpdw(MDP_BASE + 0x40c8c, 0x30303);
367 outpdw(MDP_BASE + 0x40c90, 0x30303);
368 outpdw(MDP_BASE + 0x40c94, 0x40404);
369 outpdw(MDP_BASE + 0x40c98, 0x40404);
370 outpdw(MDP_BASE + 0x40c9c, 0x40404);
371 outpdw(MDP_BASE + 0x40ca0, 0x40404);
372 outpdw(MDP_BASE + 0x40ca4, 0x40404);
373 outpdw(MDP_BASE + 0x40ca8, 0x50505);
374 outpdw(MDP_BASE + 0x40cac, 0x50505);
375 outpdw(MDP_BASE + 0x40cb0, 0x50505);
376 outpdw(MDP_BASE + 0x40cb4, 0x50505);
377 outpdw(MDP_BASE + 0x40cb8, 0x60606);
378 outpdw(MDP_BASE + 0x40cbc, 0x60606);
379 outpdw(MDP_BASE + 0x40cc0, 0x60606);
380 outpdw(MDP_BASE + 0x40cc4, 0x70707);
381 outpdw(MDP_BASE + 0x40cc8, 0x70707);
382 outpdw(MDP_BASE + 0x40ccc, 0x70707);
383 outpdw(MDP_BASE + 0x40cd0, 0x70707);
384 outpdw(MDP_BASE + 0x40cd4, 0x80808);
385 outpdw(MDP_BASE + 0x40cd8, 0x80808);
386 outpdw(MDP_BASE + 0x40cdc, 0x80808);
387 outpdw(MDP_BASE + 0x40ce0, 0x90909);
388 outpdw(MDP_BASE + 0x40ce4, 0x90909);
389 outpdw(MDP_BASE + 0x40ce8, 0xa0a0a);
390 outpdw(MDP_BASE + 0x40cec, 0xa0a0a);
391 outpdw(MDP_BASE + 0x40cf0, 0xa0a0a);
392 outpdw(MDP_BASE + 0x40cf4, 0xb0b0b);
393 outpdw(MDP_BASE + 0x40cf8, 0xb0b0b);
394 outpdw(MDP_BASE + 0x40cfc, 0xb0b0b);
395 outpdw(MDP_BASE + 0x40d00, 0xc0c0c);
396 outpdw(MDP_BASE + 0x40d04, 0xc0c0c);
397 outpdw(MDP_BASE + 0x40d08, 0xd0d0d);
398 outpdw(MDP_BASE + 0x40d0c, 0xd0d0d);
399 outpdw(MDP_BASE + 0x40d10, 0xe0e0e);
400 outpdw(MDP_BASE + 0x40d14, 0xe0e0e);
401 outpdw(MDP_BASE + 0x40d18, 0xe0e0e);
402 outpdw(MDP_BASE + 0x40d1c, 0xf0f0f);
403 outpdw(MDP_BASE + 0x40d20, 0xf0f0f);
404 outpdw(MDP_BASE + 0x40d24, 0x101010);
405 outpdw(MDP_BASE + 0x40d28, 0x101010);
406 outpdw(MDP_BASE + 0x40d2c, 0x111111);
407 outpdw(MDP_BASE + 0x40d30, 0x111111);
408 outpdw(MDP_BASE + 0x40d34, 0x121212);
409 outpdw(MDP_BASE + 0x40d38, 0x121212);
410 outpdw(MDP_BASE + 0x40d3c, 0x131313);
411 outpdw(MDP_BASE + 0x40d40, 0x131313);
412 outpdw(MDP_BASE + 0x40d44, 0x141414);
413 outpdw(MDP_BASE + 0x40d48, 0x151515);
414 outpdw(MDP_BASE + 0x40d4c, 0x151515);
415 outpdw(MDP_BASE + 0x40d50, 0x161616);
416 outpdw(MDP_BASE + 0x40d54, 0x161616);
417 outpdw(MDP_BASE + 0x40d58, 0x171717);
418 outpdw(MDP_BASE + 0x40d5c, 0x171717);
419 outpdw(MDP_BASE + 0x40d60, 0x181818);
420 outpdw(MDP_BASE + 0x40d64, 0x191919);
421 outpdw(MDP_BASE + 0x40d68, 0x191919);
422 outpdw(MDP_BASE + 0x40d6c, 0x1a1a1a);
423 outpdw(MDP_BASE + 0x40d70, 0x1b1b1b);
424 outpdw(MDP_BASE + 0x40d74, 0x1b1b1b);
425 outpdw(MDP_BASE + 0x40d78, 0x1c1c1c);
426 outpdw(MDP_BASE + 0x40d7c, 0x1c1c1c);
427 outpdw(MDP_BASE + 0x40d80, 0x1d1d1d);
428 outpdw(MDP_BASE + 0x40d84, 0x1e1e1e);
429 outpdw(MDP_BASE + 0x40d88, 0x1f1f1f);
430 outpdw(MDP_BASE + 0x40d8c, 0x1f1f1f);
431 outpdw(MDP_BASE + 0x40d90, 0x202020);
432 outpdw(MDP_BASE + 0x40d94, 0x212121);
433 outpdw(MDP_BASE + 0x40d98, 0x212121);
434 outpdw(MDP_BASE + 0x40d9c, 0x222222);
435 outpdw(MDP_BASE + 0x40da0, 0x232323);
436 outpdw(MDP_BASE + 0x40da4, 0x242424);
437 outpdw(MDP_BASE + 0x40da8, 0x242424);
438 outpdw(MDP_BASE + 0x40dac, 0x252525);
439 outpdw(MDP_BASE + 0x40db0, 0x262626);
440 outpdw(MDP_BASE + 0x40db4, 0x272727);
441 outpdw(MDP_BASE + 0x40db8, 0x272727);
442 outpdw(MDP_BASE + 0x40dbc, 0x282828);
443 outpdw(MDP_BASE + 0x40dc0, 0x292929);
444 outpdw(MDP_BASE + 0x40dc4, 0x2a2a2a);
445 outpdw(MDP_BASE + 0x40dc8, 0x2b2b2b);
446 outpdw(MDP_BASE + 0x40dcc, 0x2c2c2c);
447 outpdw(MDP_BASE + 0x40dd0, 0x2c2c2c);
448 outpdw(MDP_BASE + 0x40dd4, 0x2d2d2d);
449 outpdw(MDP_BASE + 0x40dd8, 0x2e2e2e);
450 outpdw(MDP_BASE + 0x40ddc, 0x2f2f2f);
451 outpdw(MDP_BASE + 0x40de0, 0x303030);
452 outpdw(MDP_BASE + 0x40de4, 0x313131);
453 outpdw(MDP_BASE + 0x40de8, 0x323232);
454 outpdw(MDP_BASE + 0x40dec, 0x333333);
455 outpdw(MDP_BASE + 0x40df0, 0x333333);
456 outpdw(MDP_BASE + 0x40df4, 0x343434);
457 outpdw(MDP_BASE + 0x40df8, 0x353535);
458 outpdw(MDP_BASE + 0x40dfc, 0x363636);
459 outpdw(MDP_BASE + 0x40e00, 0x373737);
460 outpdw(MDP_BASE + 0x40e04, 0x383838);
461 outpdw(MDP_BASE + 0x40e08, 0x393939);
462 outpdw(MDP_BASE + 0x40e0c, 0x3a3a3a);
463 outpdw(MDP_BASE + 0x40e10, 0x3b3b3b);
464 outpdw(MDP_BASE + 0x40e14, 0x3c3c3c);
465 outpdw(MDP_BASE + 0x40e18, 0x3d3d3d);
466 outpdw(MDP_BASE + 0x40e1c, 0x3e3e3e);
467 outpdw(MDP_BASE + 0x40e20, 0x3f3f3f);
468 outpdw(MDP_BASE + 0x40e24, 0x404040);
469 outpdw(MDP_BASE + 0x40e28, 0x414141);
470 outpdw(MDP_BASE + 0x40e2c, 0x424242);
471 outpdw(MDP_BASE + 0x40e30, 0x434343);
472 outpdw(MDP_BASE + 0x40e34, 0x444444);
473 outpdw(MDP_BASE + 0x40e38, 0x464646);
474 outpdw(MDP_BASE + 0x40e3c, 0x474747);
475 outpdw(MDP_BASE + 0x40e40, 0x484848);
476 outpdw(MDP_BASE + 0x40e44, 0x494949);
477 outpdw(MDP_BASE + 0x40e48, 0x4a4a4a);
478 outpdw(MDP_BASE + 0x40e4c, 0x4b4b4b);
479 outpdw(MDP_BASE + 0x40e50, 0x4c4c4c);
480 outpdw(MDP_BASE + 0x40e54, 0x4d4d4d);
481 outpdw(MDP_BASE + 0x40e58, 0x4f4f4f);
482 outpdw(MDP_BASE + 0x40e5c, 0x505050);
483 outpdw(MDP_BASE + 0x40e60, 0x515151);
484 outpdw(MDP_BASE + 0x40e64, 0x525252);
485 outpdw(MDP_BASE + 0x40e68, 0x535353);
486 outpdw(MDP_BASE + 0x40e6c, 0x545454);
487 outpdw(MDP_BASE + 0x40e70, 0x565656);
488 outpdw(MDP_BASE + 0x40e74, 0x575757);
489 outpdw(MDP_BASE + 0x40e78, 0x585858);
490 outpdw(MDP_BASE + 0x40e7c, 0x595959);
491 outpdw(MDP_BASE + 0x40e80, 0x5b5b5b);
492 outpdw(MDP_BASE + 0x40e84, 0x5c5c5c);
493 outpdw(MDP_BASE + 0x40e88, 0x5d5d5d);
494 outpdw(MDP_BASE + 0x40e8c, 0x5e5e5e);
495 outpdw(MDP_BASE + 0x40e90, 0x606060);
496 outpdw(MDP_BASE + 0x40e94, 0x616161);
497 outpdw(MDP_BASE + 0x40e98, 0x626262);
498 outpdw(MDP_BASE + 0x40e9c, 0x646464);
499 outpdw(MDP_BASE + 0x40ea0, 0x656565);
500 outpdw(MDP_BASE + 0x40ea4, 0x666666);
501 outpdw(MDP_BASE + 0x40ea8, 0x686868);
502 outpdw(MDP_BASE + 0x40eac, 0x696969);
503 outpdw(MDP_BASE + 0x40eb0, 0x6a6a6a);
504 outpdw(MDP_BASE + 0x40eb4, 0x6c6c6c);
505 outpdw(MDP_BASE + 0x40eb8, 0x6d6d6d);
506 outpdw(MDP_BASE + 0x40ebc, 0x6f6f6f);
507 outpdw(MDP_BASE + 0x40ec0, 0x707070);
508 outpdw(MDP_BASE + 0x40ec4, 0x717171);
509 outpdw(MDP_BASE + 0x40ec8, 0x737373);
510 outpdw(MDP_BASE + 0x40ecc, 0x747474);
511 outpdw(MDP_BASE + 0x40ed0, 0x767676);
512 outpdw(MDP_BASE + 0x40ed4, 0x777777);
513 outpdw(MDP_BASE + 0x40ed8, 0x797979);
514 outpdw(MDP_BASE + 0x40edc, 0x7a7a7a);
515 outpdw(MDP_BASE + 0x40ee0, 0x7c7c7c);
516 outpdw(MDP_BASE + 0x40ee4, 0x7d7d7d);
517 outpdw(MDP_BASE + 0x40ee8, 0x7f7f7f);
518 outpdw(MDP_BASE + 0x40eec, 0x808080);
519 outpdw(MDP_BASE + 0x40ef0, 0x828282);
520 outpdw(MDP_BASE + 0x40ef4, 0x838383);
521 outpdw(MDP_BASE + 0x40ef8, 0x858585);
522 outpdw(MDP_BASE + 0x40efc, 0x868686);
523 outpdw(MDP_BASE + 0x40f00, 0x888888);
524 outpdw(MDP_BASE + 0x40f04, 0x898989);
525 outpdw(MDP_BASE + 0x40f08, 0x8b8b8b);
526 outpdw(MDP_BASE + 0x40f0c, 0x8d8d8d);
527 outpdw(MDP_BASE + 0x40f10, 0x8e8e8e);
528 outpdw(MDP_BASE + 0x40f14, 0x909090);
529 outpdw(MDP_BASE + 0x40f18, 0x919191);
530 outpdw(MDP_BASE + 0x40f1c, 0x939393);
531 outpdw(MDP_BASE + 0x40f20, 0x959595);
532 outpdw(MDP_BASE + 0x40f24, 0x969696);
533 outpdw(MDP_BASE + 0x40f28, 0x989898);
534 outpdw(MDP_BASE + 0x40f2c, 0x9a9a9a);
535 outpdw(MDP_BASE + 0x40f30, 0x9b9b9b);
536 outpdw(MDP_BASE + 0x40f34, 0x9d9d9d);
537 outpdw(MDP_BASE + 0x40f38, 0x9f9f9f);
538 outpdw(MDP_BASE + 0x40f3c, 0xa1a1a1);
539 outpdw(MDP_BASE + 0x40f40, 0xa2a2a2);
540 outpdw(MDP_BASE + 0x40f44, 0xa4a4a4);
541 outpdw(MDP_BASE + 0x40f48, 0xa6a6a6);
542 outpdw(MDP_BASE + 0x40f4c, 0xa7a7a7);
543 outpdw(MDP_BASE + 0x40f50, 0xa9a9a9);
544 outpdw(MDP_BASE + 0x40f54, 0xababab);
545 outpdw(MDP_BASE + 0x40f58, 0xadadad);
546 outpdw(MDP_BASE + 0x40f5c, 0xafafaf);
547 outpdw(MDP_BASE + 0x40f60, 0xb0b0b0);
548 outpdw(MDP_BASE + 0x40f64, 0xb2b2b2);
549 outpdw(MDP_BASE + 0x40f68, 0xb4b4b4);
550 outpdw(MDP_BASE + 0x40f6c, 0xb6b6b6);
551 outpdw(MDP_BASE + 0x40f70, 0xb8b8b8);
552 outpdw(MDP_BASE + 0x40f74, 0xbababa);
553 outpdw(MDP_BASE + 0x40f78, 0xbbbbbb);
554 outpdw(MDP_BASE + 0x40f7c, 0xbdbdbd);
555 outpdw(MDP_BASE + 0x40f80, 0xbfbfbf);
556 outpdw(MDP_BASE + 0x40f84, 0xc1c1c1);
557 outpdw(MDP_BASE + 0x40f88, 0xc3c3c3);
558 outpdw(MDP_BASE + 0x40f8c, 0xc5c5c5);
559 outpdw(MDP_BASE + 0x40f90, 0xc7c7c7);
560 outpdw(MDP_BASE + 0x40f94, 0xc9c9c9);
561 outpdw(MDP_BASE + 0x40f98, 0xcbcbcb);
562 outpdw(MDP_BASE + 0x40f9c, 0xcdcdcd);
563 outpdw(MDP_BASE + 0x40fa0, 0xcfcfcf);
564 outpdw(MDP_BASE + 0x40fa4, 0xd1d1d1);
565 outpdw(MDP_BASE + 0x40fa8, 0xd3d3d3);
566 outpdw(MDP_BASE + 0x40fac, 0xd5d5d5);
567 outpdw(MDP_BASE + 0x40fb0, 0xd7d7d7);
568 outpdw(MDP_BASE + 0x40fb4, 0xd9d9d9);
569 outpdw(MDP_BASE + 0x40fb8, 0xdbdbdb);
570 outpdw(MDP_BASE + 0x40fbc, 0xdddddd);
571 outpdw(MDP_BASE + 0x40fc0, 0xdfdfdf);
572 outpdw(MDP_BASE + 0x40fc4, 0xe1e1e1);
573 outpdw(MDP_BASE + 0x40fc8, 0xe3e3e3);
574 outpdw(MDP_BASE + 0x40fcc, 0xe5e5e5);
575 outpdw(MDP_BASE + 0x40fd0, 0xe7e7e7);
576 outpdw(MDP_BASE + 0x40fd4, 0xe9e9e9);
577 outpdw(MDP_BASE + 0x40fd8, 0xebebeb);
578 outpdw(MDP_BASE + 0x40fdc, 0xeeeeee);
579 outpdw(MDP_BASE + 0x40fe0, 0xf0f0f0);
580 outpdw(MDP_BASE + 0x40fe4, 0xf2f2f2);
581 outpdw(MDP_BASE + 0x40fe8, 0xf4f4f4);
582 outpdw(MDP_BASE + 0x40fec, 0xf6f6f6);
583 outpdw(MDP_BASE + 0x40ff0, 0xf8f8f8);
584 outpdw(MDP_BASE + 0x40ff4, 0xfbfbfb);
585 outpdw(MDP_BASE + 0x40ff8, 0xfdfdfd);
586 outpdw(MDP_BASE + 0x40ffc, 0xffffff);
587}
588
589#define IRQ_EN_1__MDP_IRQ___M 0x00000800
590
591void mdp_hw_init(void)
592{
593 int i;
594
595 /* MDP cmd block enable */
596 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
597
598 /* debug interface write access */
599 outpdw(MDP_BASE + 0x60, 1);
600
601 outp32(MDP_INTR_ENABLE, MDP_ANY_INTR_MASK);
602 outp32(MDP_EBI2_PORTMAP_MODE, 0x3);
603 outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8, 0x0);
604 outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc, 0x0);
605 outpdw(MDP_BASE + 0x60, 0x1);
606 mdp_load_lut_param();
607
608 /*
609 * clear up unused fg/main registers
610 */
611 /* comp.plane 2&3 ystride */
612 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0120, 0x0);
613 /* unpacked pattern */
614 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x012c, 0x0);
615 /* unpacked pattern */
616 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0130, 0x0);
617 /* unpacked pattern */
618 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0134, 0x0);
619 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0158, 0x0);
620 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x15c, 0x0);
621 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0160, 0x0);
622 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0170, 0x0);
623 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0174, 0x0);
624 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x017c, 0x0);
625
626 /* comp.plane 2 */
627 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0114, 0x0);
628 /* comp.plane 3 */
629 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0118, 0x0);
630
631 /* clear up unused bg registers */
632 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8, 0);
633 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0, 0);
634 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc, 0);
635 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0, 0);
636 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4, 0);
637
638#ifndef CONFIG_FB_MSM_MDP22
639 MDP_OUTP(MDP_BASE + 0xE0000, 0);
640 MDP_OUTP(MDP_BASE + 0x100, 0xffffffff);
641 MDP_OUTP(MDP_BASE + 0x90070, 0);
642 MDP_OUTP(MDP_BASE + 0x94010, 1);
643 MDP_OUTP(MDP_BASE + 0x9401c, 2);
644#endif
645
646 /*
647 * limit vector
648 * pre gets applied before color matrix conversion
649 * post is after ccs
650 */
651 writel(mdp_plv[0], MDP_CSC_PRE_LV1n(0));
652 writel(mdp_plv[1], MDP_CSC_PRE_LV1n(1));
653 writel(mdp_plv[2], MDP_CSC_PRE_LV1n(2));
654 writel(mdp_plv[3], MDP_CSC_PRE_LV1n(3));
655
656#ifdef CONFIG_FB_MSM_MDP31
657 writel(mdp_plv[2], MDP_CSC_PRE_LV1n(4));
658 writel(mdp_plv[3], MDP_CSC_PRE_LV1n(5));
659
660 writel(0, MDP_CSC_POST_LV1n(0));
661 writel(0xff, MDP_CSC_POST_LV1n(1));
662 writel(0, MDP_CSC_POST_LV1n(2));
663 writel(0xff, MDP_CSC_POST_LV1n(3));
664 writel(0, MDP_CSC_POST_LV1n(4));
665 writel(0xff, MDP_CSC_POST_LV1n(5));
666
667 writel(0, MDP_CSC_PRE_LV2n(0));
668 writel(0xff, MDP_CSC_PRE_LV2n(1));
669 writel(0, MDP_CSC_PRE_LV2n(2));
670 writel(0xff, MDP_CSC_PRE_LV2n(3));
671 writel(0, MDP_CSC_PRE_LV2n(4));
672 writel(0xff, MDP_CSC_PRE_LV2n(5));
673
674 writel(mdp_plv[0], MDP_CSC_POST_LV2n(0));
675 writel(mdp_plv[1], MDP_CSC_POST_LV2n(1));
676 writel(mdp_plv[2], MDP_CSC_POST_LV2n(2));
677 writel(mdp_plv[3], MDP_CSC_POST_LV2n(3));
678 writel(mdp_plv[2], MDP_CSC_POST_LV2n(4));
679 writel(mdp_plv[3], MDP_CSC_POST_LV2n(5));
680#endif
681
682 /* primary forward matrix */
683 for (i = 0; i < MDP_CCS_SIZE; i++)
684 writel(mdp_ccs_rgb2yuv.ccs[i], MDP_CSC_PFMVn(i));
685
686#ifdef CONFIG_FB_MSM_MDP31
687 for (i = 0; i < MDP_BV_SIZE; i++)
688 writel(mdp_ccs_rgb2yuv.bv[i], MDP_CSC_POST_BV2n(i));
689
690 writel(0, MDP_CSC_PRE_BV2n(0));
691 writel(0, MDP_CSC_PRE_BV2n(1));
692 writel(0, MDP_CSC_PRE_BV2n(2));
693#endif
694 /* primary reverse matrix */
695 for (i = 0; i < MDP_CCS_SIZE; i++)
696 writel(mdp_ccs_yuv2rgb.ccs[i], MDP_CSC_PRMVn(i));
697
698 for (i = 0; i < MDP_BV_SIZE; i++)
699 writel(mdp_ccs_yuv2rgb.bv[i], MDP_CSC_PRE_BV1n(i));
700
701#ifdef CONFIG_FB_MSM_MDP31
702 writel(0, MDP_CSC_POST_BV1n(0));
703 writel(0, MDP_CSC_POST_BV1n(1));
704 writel(0, MDP_CSC_POST_BV1n(2));
705
706 outpdw(MDP_BASE + 0x30010, 0x03e0);
707 outpdw(MDP_BASE + 0x30014, 0x0360);
708 outpdw(MDP_BASE + 0x30018, 0x0120);
709 outpdw(MDP_BASE + 0x3001c, 0x0140);
710#endif
711 mdp_init_scale_table();
712
713#ifndef CONFIG_FB_MSM_MDP31
714 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0104,
715 ((16 << 6) << 16) | (16) << 6);
716#endif
717
718 /* MDP cmd block disable */
719 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
720} \ No newline at end of file
diff --git a/drivers/staging/msm/mdp_ppp.c b/drivers/staging/msm/mdp_ppp.c
new file mode 100644
index 000000000000..c35a6aebca14
--- /dev/null
+++ b/drivers/staging/msm/mdp_ppp.c
@@ -0,0 +1,1502 @@
1/* drivers/video/msm/src/drv/mdp/mdp_ppp.c
2 *
3 * Copyright (C) 2007 Google Incorporated
4 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
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
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/time.h>
20#include <linux/init.h>
21#include <linux/interrupt.h>
22#include <linux/fb.h>
23#include <msm_mdp.h>
24#include <linux/file.h>
25#include <linux/major.h>
26
27#include "linux/proc_fs.h"
28
29#include <mach/hardware.h>
30#include <linux/io.h>
31
32#include <asm/system.h>
33#include <asm/mach-types.h>
34#include <linux/semaphore.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38
39#define MDP_IS_IMGTYPE_BAD(x) (((x) >= MDP_IMGTYPE_LIMIT) && \
40 (((x) < MDP_IMGTYPE2_START) || \
41 ((x) >= MDP_IMGTYPE_LIMIT2)))
42
43static uint32_t bytes_per_pixel[] = {
44 [MDP_RGB_565] = 2,
45 [MDP_RGB_888] = 3,
46 [MDP_XRGB_8888] = 4,
47 [MDP_ARGB_8888] = 4,
48 [MDP_RGBA_8888] = 4,
49 [MDP_BGRA_8888] = 4,
50 [MDP_Y_CBCR_H2V1] = 1,
51 [MDP_Y_CBCR_H2V2] = 1,
52 [MDP_Y_CRCB_H2V1] = 1,
53 [MDP_Y_CRCB_H2V2] = 1,
54 [MDP_YCRYCB_H2V1] = 2,
55 [MDP_BGR_565] = 2
56};
57
58extern uint32 mdp_plv[];
59extern struct semaphore mdp_ppp_mutex;
60
61uint32_t mdp_get_bytes_per_pixel(uint32_t format)
62{
63 uint32_t bpp = 0;
64 if (format < ARRAY_SIZE(bytes_per_pixel))
65 bpp = bytes_per_pixel[format];
66
67 BUG_ON(!bpp);
68 return bpp;
69}
70
71static uint32 mdp_conv_matx_rgb2yuv(uint32 input_pixel,
72 uint16 *matrix_and_bias_vector,
73 uint32 *clamp_vector,
74 uint32 *look_up_table)
75{
76 uint8 input_C2, input_C0, input_C1;
77 uint32 output;
78 int32 comp_C2, comp_C1, comp_C0, temp;
79 int32 temp1, temp2, temp3;
80 int32 matrix[9];
81 int32 bias_vector[3];
82 int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
83 int32 i;
84 uint32 _is_lookup_table_enabled;
85
86 input_C2 = (input_pixel >> 16) & 0xFF;
87 input_C1 = (input_pixel >> 8) & 0xFF;
88 input_C0 = (input_pixel >> 0) & 0xFF;
89
90 comp_C0 = input_C0;
91 comp_C1 = input_C1;
92 comp_C2 = input_C2;
93
94 for (i = 0; i < 9; i++)
95 matrix[i] =
96 ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20;
97
98 bias_vector[0] = (int32) (matrix_and_bias_vector[9] & 0xFF);
99 bias_vector[1] = (int32) (matrix_and_bias_vector[10] & 0xFF);
100 bias_vector[2] = (int32) (matrix_and_bias_vector[11] & 0xFF);
101
102 Y_low_limit = (int32) clamp_vector[0];
103 Y_high_limit = (int32) clamp_vector[1];
104 C_low_limit = (int32) clamp_vector[2];
105 C_high_limit = (int32) clamp_vector[3];
106
107 if (look_up_table == 0) /* check for NULL point */
108 _is_lookup_table_enabled = 0;
109 else
110 _is_lookup_table_enabled = 1;
111
112 if (_is_lookup_table_enabled == 1) {
113 comp_C2 = (look_up_table[comp_C2] >> 16) & 0xFF;
114 comp_C1 = (look_up_table[comp_C1] >> 8) & 0xFF;
115 comp_C0 = (look_up_table[comp_C0] >> 0) & 0xFF;
116 }
117 /*
118 * Color Conversion
119 * reorder input colors
120 */
121 temp = comp_C2;
122 comp_C2 = comp_C1;
123 comp_C1 = comp_C0;
124 comp_C0 = temp;
125
126 /* matrix multiplication */
127 temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2];
128 temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5];
129 temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8];
130
131 comp_C0 = temp1 + 0x100;
132 comp_C1 = temp2 + 0x100;
133 comp_C2 = temp3 + 0x100;
134
135 /* take interger part */
136 comp_C0 >>= 9;
137 comp_C1 >>= 9;
138 comp_C2 >>= 9;
139
140 /* post bias (+) */
141 comp_C0 += bias_vector[0];
142 comp_C1 += bias_vector[1];
143 comp_C2 += bias_vector[2];
144
145 /* limit pixel to 8-bit */
146 if (comp_C0 < 0)
147 comp_C0 = 0;
148
149 if (comp_C0 > 255)
150 comp_C0 = 255;
151
152 if (comp_C1 < 0)
153 comp_C1 = 0;
154
155 if (comp_C1 > 255)
156 comp_C1 = 255;
157
158 if (comp_C2 < 0)
159 comp_C2 = 0;
160
161 if (comp_C2 > 255)
162 comp_C2 = 255;
163
164 /* clamp */
165 if (comp_C0 < Y_low_limit)
166 comp_C0 = Y_low_limit;
167
168 if (comp_C0 > Y_high_limit)
169 comp_C0 = Y_high_limit;
170
171 if (comp_C1 < C_low_limit)
172 comp_C1 = C_low_limit;
173
174 if (comp_C1 > C_high_limit)
175 comp_C1 = C_high_limit;
176
177 if (comp_C2 < C_low_limit)
178 comp_C2 = C_low_limit;
179
180 if (comp_C2 > C_high_limit)
181 comp_C2 = C_high_limit;
182
183 output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0;
184 return output;
185}
186
187uint32 mdp_conv_matx_yuv2rgb(uint32 input_pixel,
188 uint16 *matrix_and_bias_vector,
189 uint32 *clamp_vector, uint32 *look_up_table)
190{
191 uint8 input_C2, input_C0, input_C1;
192 uint32 output;
193 int32 comp_C2, comp_C1, comp_C0, temp;
194 int32 temp1, temp2, temp3;
195 int32 matrix[9];
196 int32 bias_vector[3];
197 int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
198 int32 i;
199 uint32 _is_lookup_table_enabled;
200
201 input_C2 = (input_pixel >> 16) & 0xFF;
202 input_C1 = (input_pixel >> 8) & 0xFF;
203 input_C0 = (input_pixel >> 0) & 0xFF;
204
205 comp_C0 = input_C0;
206 comp_C1 = input_C1;
207 comp_C2 = input_C2;
208
209 for (i = 0; i < 9; i++)
210 matrix[i] =
211 ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20;
212
213 bias_vector[0] = (int32) (matrix_and_bias_vector[9] & 0xFF);
214 bias_vector[1] = (int32) (matrix_and_bias_vector[10] & 0xFF);
215 bias_vector[2] = (int32) (matrix_and_bias_vector[11] & 0xFF);
216
217 Y_low_limit = (int32) clamp_vector[0];
218 Y_high_limit = (int32) clamp_vector[1];
219 C_low_limit = (int32) clamp_vector[2];
220 C_high_limit = (int32) clamp_vector[3];
221
222 if (look_up_table == 0) /* check for NULL point */
223 _is_lookup_table_enabled = 0;
224 else
225 _is_lookup_table_enabled = 1;
226
227 /* clamp */
228 if (comp_C0 < Y_low_limit)
229 comp_C0 = Y_low_limit;
230
231 if (comp_C0 > Y_high_limit)
232 comp_C0 = Y_high_limit;
233
234 if (comp_C1 < C_low_limit)
235 comp_C1 = C_low_limit;
236
237 if (comp_C1 > C_high_limit)
238 comp_C1 = C_high_limit;
239
240 if (comp_C2 < C_low_limit)
241 comp_C2 = C_low_limit;
242
243 if (comp_C2 > C_high_limit)
244 comp_C2 = C_high_limit;
245
246 /*
247 * Color Conversion
248 * pre bias (-)
249 */
250 comp_C0 -= bias_vector[0];
251 comp_C1 -= bias_vector[1];
252 comp_C2 -= bias_vector[2];
253
254 /* matrix multiplication */
255 temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2];
256 temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5];
257 temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8];
258
259 comp_C0 = temp1 + 0x100;
260 comp_C1 = temp2 + 0x100;
261 comp_C2 = temp3 + 0x100;
262
263 /* take interger part */
264 comp_C0 >>= 9;
265 comp_C1 >>= 9;
266 comp_C2 >>= 9;
267
268 /* reorder output colors */
269 temp = comp_C0;
270 comp_C0 = comp_C1;
271 comp_C1 = comp_C2;
272 comp_C2 = temp;
273
274 /* limit pixel to 8-bit */
275 if (comp_C0 < 0)
276 comp_C0 = 0;
277
278 if (comp_C0 > 255)
279 comp_C0 = 255;
280
281 if (comp_C1 < 0)
282 comp_C1 = 0;
283
284 if (comp_C1 > 255)
285 comp_C1 = 255;
286
287 if (comp_C2 < 0)
288 comp_C2 = 0;
289
290 if (comp_C2 > 255)
291 comp_C2 = 255;
292
293 /* Look-up table */
294 if (_is_lookup_table_enabled == 1) {
295 comp_C2 = (look_up_table[comp_C2] >> 16) & 0xFF;
296 comp_C1 = (look_up_table[comp_C1] >> 8) & 0xFF;
297 comp_C0 = (look_up_table[comp_C0] >> 0) & 0xFF;
298 }
299
300 output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0;
301 return output;
302}
303
304static uint32 mdp_calc_tpval(MDPIMG *mdpImg)
305{
306 uint32 tpVal;
307 uint8 plane_tp;
308
309 tpVal = 0;
310 if ((mdpImg->imgType == MDP_RGB_565)
311 || (mdpImg->imgType == MDP_BGR_565)) {
312 /*
313 * transparent color conversion into 24 bpp
314 *
315 * C2R_8BIT
316 * left shift the entire bit and or it with the upper most bits
317 */
318 plane_tp = (uint8) ((mdpImg->tpVal & 0xF800) >> 11);
319 tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 16;
320
321 /* C1B_8BIT */
322 plane_tp = (uint8) (mdpImg->tpVal & 0x1F);
323 tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 8;
324
325 /* C0G_8BIT */
326 plane_tp = (uint8) ((mdpImg->tpVal & 0x7E0) >> 5);
327 tpVal |= ((plane_tp << 2) | ((plane_tp & 0x30) >> 4));
328 } else {
329 /* 24bit RGB to RBG conversion */
330
331 tpVal = (mdpImg->tpVal & 0xFF00) >> 8;
332 tpVal |= (mdpImg->tpVal & 0xFF) << 8;
333 tpVal |= (mdpImg->tpVal & 0xFF0000);
334 }
335
336 return tpVal;
337}
338
339static uint8 *mdp_get_chroma_addr(MDPIBUF *iBuf)
340{
341 uint8 *dest1;
342
343 dest1 = NULL;
344 switch (iBuf->ibuf_type) {
345 case MDP_Y_CBCR_H2V2:
346 case MDP_Y_CRCB_H2V2:
347 case MDP_Y_CBCR_H2V1:
348 case MDP_Y_CRCB_H2V1:
349 dest1 = (uint8 *) iBuf->buf;
350 dest1 += iBuf->ibuf_width * iBuf->ibuf_height * iBuf->bpp;
351 break;
352
353 default:
354 break;
355 }
356
357 return dest1;
358}
359
360static void mdp_ppp_setbg(MDPIBUF *iBuf)
361{
362 uint8 *bg0_addr;
363 uint8 *bg1_addr;
364 uint32 bg0_ystride, bg1_ystride;
365 uint32 ppp_src_cfg_reg, unpack_pattern;
366 int v_slice, h_slice;
367
368 v_slice = h_slice = 1;
369 bg0_addr = (uint8 *) iBuf->buf;
370 bg1_addr = mdp_get_chroma_addr(iBuf);
371
372 bg0_ystride = iBuf->ibuf_width * iBuf->bpp;
373 bg1_ystride = iBuf->ibuf_width * iBuf->bpp;
374
375 switch (iBuf->ibuf_type) {
376 case MDP_BGR_565:
377 case MDP_RGB_565:
378 /* 888 = 3bytes
379 * RGB = 3Components
380 * RGB interleaved
381 */
382 ppp_src_cfg_reg = PPP_SRC_C2R_5BITS | PPP_SRC_C0G_6BITS |
383 PPP_SRC_C1B_5BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
384 PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
385 PPP_SRC_UNPACK_ALIGN_LSB |
386 PPP_SRC_FETCH_PLANES_INTERLVD;
387
388 if (iBuf->ibuf_type == MDP_RGB_565)
389 unpack_pattern =
390 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
391 else
392 unpack_pattern =
393 MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
394 break;
395
396 case MDP_RGB_888:
397 /*
398 * 888 = 3bytes
399 * RGB = 3Components
400 * RGB interleaved
401 */
402 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
403 PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_3BYTES |
404 PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
405 PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_INTERLVD;
406
407 unpack_pattern =
408 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
409 break;
410
411 case MDP_BGRA_8888:
412 case MDP_RGBA_8888:
413 case MDP_ARGB_8888:
414 case MDP_XRGB_8888:
415 /*
416 * 8888 = 4bytes
417 * ARGB = 4Components
418 * ARGB interleaved
419 */
420 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
421 PPP_SRC_C1B_8BITS | PPP_SRC_C3A_8BITS | PPP_SRC_C3_ALPHA_EN |
422 PPP_SRC_BPP_INTERLVD_4BYTES | PPP_SRC_INTERLVD_4COMPONENTS |
423 PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB |
424 PPP_SRC_FETCH_PLANES_INTERLVD;
425
426 if (iBuf->ibuf_type == MDP_BGRA_8888)
427 unpack_pattern =
428 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
429 8);
430 else if (iBuf->ibuf_type == MDP_RGBA_8888)
431 unpack_pattern =
432 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
433 8);
434 else
435 unpack_pattern =
436 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
437 8);
438 break;
439
440 case MDP_Y_CBCR_H2V2:
441 case MDP_Y_CRCB_H2V2:
442 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
443 PPP_SRC_C0G_8BITS |
444 PPP_SRC_C1B_8BITS |
445 PPP_SRC_C3A_8BITS |
446 PPP_SRC_BPP_INTERLVD_2BYTES |
447 PPP_SRC_INTERLVD_2COMPONENTS |
448 PPP_SRC_UNPACK_TIGHT |
449 PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
450
451 if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
452 unpack_pattern =
453 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
454 else
455 unpack_pattern =
456 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
457 v_slice = h_slice = 2;
458 break;
459
460 case MDP_YCRYCB_H2V1:
461 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
462 PPP_SRC_C0G_8BITS |
463 PPP_SRC_C1B_8BITS |
464 PPP_SRC_C3A_8BITS |
465 PPP_SRC_BPP_INTERLVD_2BYTES |
466 PPP_SRC_INTERLVD_4COMPONENTS |
467 PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB;
468
469 unpack_pattern =
470 MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
471 h_slice = 2;
472 break;
473
474 case MDP_Y_CBCR_H2V1:
475 case MDP_Y_CRCB_H2V1:
476 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
477 PPP_SRC_C0G_8BITS |
478 PPP_SRC_C1B_8BITS |
479 PPP_SRC_C3A_8BITS |
480 PPP_SRC_BPP_INTERLVD_2BYTES |
481 PPP_SRC_INTERLVD_2COMPONENTS |
482 PPP_SRC_UNPACK_TIGHT |
483 PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
484
485 if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
486 unpack_pattern =
487 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
488 else
489 unpack_pattern =
490 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
491 h_slice = 2;
492 break;
493
494 default:
495 return;
496 }
497
498 /* starting input address adjustment */
499 mdp_adjust_start_addr(&bg0_addr, &bg1_addr, v_slice, h_slice,
500 iBuf->roi.lcd_x, iBuf->roi.lcd_y,
501 iBuf->ibuf_width, iBuf->ibuf_height, iBuf->bpp,
502 iBuf, 1);
503
504 /*
505 * 0x01c0: background plane 0 addr
506 * 0x01c4: background plane 1 addr
507 * 0x01c8: background plane 2 addr
508 * 0x01cc: bg y stride for plane 0 and 1
509 * 0x01d0: bg y stride for plane 2
510 * 0x01d4: bg src PPP config
511 * 0x01d8: unpack pattern
512 */
513 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c0, bg0_addr);
514 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c4, bg1_addr);
515
516 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01cc,
517 (bg1_ystride << 16) | bg0_ystride);
518 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d4, ppp_src_cfg_reg);
519
520 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d8, unpack_pattern);
521}
522
523#define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \
524 (img == MDP_Y_CBCR_H2V2) | \
525 (img == MDP_Y_CRCB_H2V1) | \
526 (img == MDP_Y_CBCR_H2V1))
527
528#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
529
530#define Y_TO_CRCB_RATIO(format) \
531 ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\
532 (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1)
533
534static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp,
535 uint32_t *len0, uint32_t *len1)
536{
537 *len0 = IMG_LEN(rect->h, img->width, rect->w, bpp);
538 if (IS_PSEUDOPLNR(img->format))
539 *len1 = *len0/Y_TO_CRCB_RATIO(img->format);
540 else
541 *len1 = 0;
542}
543
544static void flush_imgs(struct mdp_blit_req *req, int src_bpp, int dst_bpp,
545 struct file *p_src_file, struct file *p_dst_file)
546{
547#ifdef CONFIG_ANDROID_PMEM
548 uint32_t src0_len, src1_len, dst0_len, dst1_len;
549
550 /* flush src images to memory before dma to mdp */
551 get_len(&req->src, &req->src_rect, src_bpp,
552 &src0_len, &src1_len);
553
554 flush_pmem_file(p_src_file,
555 req->src.offset, src0_len);
556
557 if (IS_PSEUDOPLNR(req->src.format))
558 flush_pmem_file(p_src_file,
559 req->src.offset + src0_len, src1_len);
560
561 get_len(&req->dst, &req->dst_rect, dst_bpp, &dst0_len, &dst1_len);
562 flush_pmem_file(p_dst_file, req->dst.offset, dst0_len);
563
564 if (IS_PSEUDOPLNR(req->dst.format))
565 flush_pmem_file(p_dst_file,
566 req->dst.offset + dst0_len, dst1_len);
567#endif
568}
569
570static void mdp_start_ppp(struct msm_fb_data_type *mfd, MDPIBUF *iBuf,
571struct mdp_blit_req *req, struct file *p_src_file, struct file *p_dst_file)
572{
573 uint8 *src0, *src1;
574 uint8 *dest0, *dest1;
575 uint16 inpBpp;
576 uint32 dest0_ystride;
577 uint32 src_width;
578 uint32 src_height;
579 uint32 src0_ystride;
580 uint32 dst_roi_width;
581 uint32 dst_roi_height;
582 uint32 ppp_src_cfg_reg, ppp_operation_reg, ppp_dst_cfg_reg;
583 uint32 alpha, tpVal;
584 uint32 packPattern;
585 uint32 dst_packPattern;
586 boolean inputRGB, outputRGB, pseudoplanr_output;
587 int sv_slice, sh_slice;
588 int dv_slice, dh_slice;
589 boolean perPixelAlpha = FALSE;
590 boolean ppp_lookUp_enable = FALSE;
591
592 sv_slice = sh_slice = dv_slice = dh_slice = 1;
593 alpha = tpVal = 0;
594 src_width = iBuf->mdpImg.width;
595 src_height = iBuf->roi.y + iBuf->roi.height;
596 src1 = NULL;
597 dest1 = NULL;
598
599 inputRGB = outputRGB = TRUE;
600 pseudoplanr_output = FALSE;
601 ppp_operation_reg = 0;
602 ppp_dst_cfg_reg = 0;
603 ppp_src_cfg_reg = 0;
604
605 /* Wait for the pipe to clear */
606 do { } while (mdp_ppp_pipe_wait() <= 0);
607
608 /*
609 * destination config
610 */
611 switch (iBuf->ibuf_type) {
612 case MDP_RGB_888:
613 dst_packPattern =
614 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
615 ppp_dst_cfg_reg =
616 PPP_DST_C0G_8BIT | PPP_DST_C1B_8BIT | PPP_DST_C2R_8BIT |
617 PPP_DST_PACKET_CNT_INTERLVD_3ELEM | PPP_DST_PACK_TIGHT |
618 PPP_DST_PACK_ALIGN_LSB | PPP_DST_OUT_SEL_AXI |
619 PPP_DST_BPP_3BYTES | PPP_DST_PLANE_INTERLVD;
620 break;
621
622 case MDP_XRGB_8888:
623 case MDP_ARGB_8888:
624 case MDP_RGBA_8888:
625 if (iBuf->ibuf_type == MDP_BGRA_8888)
626 dst_packPattern =
627 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
628 8);
629 else if (iBuf->ibuf_type == MDP_RGBA_8888)
630 dst_packPattern =
631 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
632 8);
633 else
634 dst_packPattern =
635 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
636 8);
637
638 ppp_dst_cfg_reg = PPP_DST_C0G_8BIT |
639 PPP_DST_C1B_8BIT |
640 PPP_DST_C2R_8BIT |
641 PPP_DST_C3A_8BIT |
642 PPP_DST_C3ALPHA_EN |
643 PPP_DST_PACKET_CNT_INTERLVD_4ELEM |
644 PPP_DST_PACK_TIGHT |
645 PPP_DST_PACK_ALIGN_LSB |
646 PPP_DST_OUT_SEL_AXI |
647 PPP_DST_BPP_4BYTES | PPP_DST_PLANE_INTERLVD;
648 break;
649
650 case MDP_Y_CBCR_H2V2:
651 case MDP_Y_CRCB_H2V2:
652 if (iBuf->ibuf_type == MDP_Y_CBCR_H2V2)
653 dst_packPattern =
654 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
655 else
656 dst_packPattern =
657 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
658
659 ppp_dst_cfg_reg = PPP_DST_C2R_8BIT |
660 PPP_DST_C0G_8BIT |
661 PPP_DST_C1B_8BIT |
662 PPP_DST_C3A_8BIT |
663 PPP_DST_PACKET_CNT_INTERLVD_2ELEM |
664 PPP_DST_PACK_TIGHT |
665 PPP_DST_PACK_ALIGN_LSB |
666 PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES;
667
668 ppp_operation_reg |= PPP_OP_DST_CHROMA_420;
669 outputRGB = FALSE;
670 pseudoplanr_output = TRUE;
671 /*
672 * vertically (y direction) and horizontally (x direction)
673 * sample reduction by 2
674 */
675
676 /*
677 * H2V2(YUV420) Cosite
678 *
679 * Y Y Y Y
680 * CbCr CbCr
681 * Y Y Y Y
682 * Y Y Y Y
683 * CbCr CbCr
684 * Y Y Y Y
685 */
686 dv_slice = dh_slice = 2;
687
688 /* (x,y) and (width,height) must be even numbern */
689 iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
690 iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
691 iBuf->roi.x = (iBuf->roi.x / 2) * 2;
692 iBuf->roi.width = (iBuf->roi.width / 2) * 2;
693
694 iBuf->roi.lcd_y = (iBuf->roi.lcd_y / 2) * 2;
695 iBuf->roi.dst_height = (iBuf->roi.dst_height / 2) * 2;
696 iBuf->roi.y = (iBuf->roi.y / 2) * 2;
697 iBuf->roi.height = (iBuf->roi.height / 2) * 2;
698 break;
699
700 case MDP_YCRYCB_H2V1:
701 dst_packPattern =
702 MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
703 ppp_dst_cfg_reg =
704 PPP_DST_C2R_8BIT | PPP_DST_C0G_8BIT | PPP_DST_C1B_8BIT |
705 PPP_DST_C3A_8BIT | PPP_DST_PACKET_CNT_INTERLVD_4ELEM |
706 PPP_DST_PACK_TIGHT | PPP_DST_PACK_ALIGN_LSB |
707 PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES |
708 PPP_DST_PLANE_INTERLVD;
709
710 ppp_operation_reg |= PPP_OP_DST_CHROMA_H2V1;
711 outputRGB = FALSE;
712 /*
713 * horizontally (x direction) sample reduction by 2
714 *
715 * H2V1(YUV422) Cosite
716 *
717 * YCbCr Y YCbCr Y
718 * YCbCr Y YCbCr Y
719 * YCbCr Y YCbCr Y
720 * YCbCr Y YCbCr Y
721 */
722 dh_slice = 2;
723
724 /*
725 * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the
726 * preloaded gamma setting of 2.2 when the content is
727 * non-linear ppp_lookUp_enable = TRUE;
728 */
729
730 /* x and width must be even number */
731 iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
732 iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
733 iBuf->roi.x = (iBuf->roi.x / 2) * 2;
734 iBuf->roi.width = (iBuf->roi.width / 2) * 2;
735 break;
736
737 case MDP_Y_CBCR_H2V1:
738 case MDP_Y_CRCB_H2V1:
739 if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
740 dst_packPattern =
741 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
742 else
743 dst_packPattern =
744 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
745
746 ppp_dst_cfg_reg = PPP_DST_C2R_8BIT |
747 PPP_DST_C0G_8BIT |
748 PPP_DST_C1B_8BIT |
749 PPP_DST_C3A_8BIT |
750 PPP_DST_PACKET_CNT_INTERLVD_2ELEM |
751 PPP_DST_PACK_TIGHT |
752 PPP_DST_PACK_ALIGN_LSB |
753 PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES;
754
755 ppp_operation_reg |= PPP_OP_DST_CHROMA_H2V1;
756 outputRGB = FALSE;
757 pseudoplanr_output = TRUE;
758 /* horizontally (x direction) sample reduction by 2 */
759 dh_slice = 2;
760
761 /* x and width must be even number */
762 iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
763 iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
764 iBuf->roi.x = (iBuf->roi.x / 2) * 2;
765 iBuf->roi.width = (iBuf->roi.width / 2) * 2;
766 break;
767
768 case MDP_BGR_565:
769 case MDP_RGB_565:
770 default:
771 if (iBuf->ibuf_type == MDP_RGB_565)
772 dst_packPattern =
773 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
774 else
775 dst_packPattern =
776 MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
777
778 ppp_dst_cfg_reg = PPP_DST_C0G_6BIT |
779 PPP_DST_C1B_5BIT |
780 PPP_DST_C2R_5BIT |
781 PPP_DST_PACKET_CNT_INTERLVD_3ELEM |
782 PPP_DST_PACK_TIGHT |
783 PPP_DST_PACK_ALIGN_LSB |
784 PPP_DST_OUT_SEL_AXI |
785 PPP_DST_BPP_2BYTES | PPP_DST_PLANE_INTERLVD;
786 break;
787 }
788
789 /* source config */
790 switch (iBuf->mdpImg.imgType) {
791 case MDP_RGB_888:
792 inpBpp = 3;
793 /*
794 * 565 = 2bytes
795 * RGB = 3Components
796 * RGB interleaved
797 */
798 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
799 PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_3BYTES |
800 PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
801 PPP_SRC_UNPACK_ALIGN_LSB |
802 PPP_SRC_FETCH_PLANES_INTERLVD;
803
804 packPattern = MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
805
806 ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
807 PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
808 break;
809
810 case MDP_BGRA_8888:
811 case MDP_RGBA_8888:
812 case MDP_ARGB_8888:
813 perPixelAlpha = TRUE;
814 case MDP_XRGB_8888:
815 inpBpp = 4;
816 /*
817 * 8888 = 4bytes
818 * ARGB = 4Components
819 * ARGB interleaved
820 */
821 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
822 PPP_SRC_C1B_8BITS | PPP_SRC_C3A_8BITS |
823 PPP_SRC_C3_ALPHA_EN | PPP_SRC_BPP_INTERLVD_4BYTES |
824 PPP_SRC_INTERLVD_4COMPONENTS | PPP_SRC_UNPACK_TIGHT |
825 PPP_SRC_UNPACK_ALIGN_LSB |
826 PPP_SRC_FETCH_PLANES_INTERLVD;
827
828 if (iBuf->mdpImg.imgType == MDP_BGRA_8888)
829 packPattern =
830 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
831 8);
832 else if (iBuf->mdpImg.imgType == MDP_RGBA_8888)
833 packPattern =
834 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
835 8);
836 else
837 packPattern =
838 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
839 8);
840
841 ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
842 PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
843 break;
844
845 case MDP_Y_CBCR_H2V2:
846 case MDP_Y_CRCB_H2V2:
847 inpBpp = 1;
848 src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
849
850 /*
851 * CbCr = 2bytes
852 * CbCr = 2Components
853 * Y+CbCr
854 */
855 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
856 PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
857 PPP_SRC_INTERLVD_2COMPONENTS | PPP_SRC_UNPACK_TIGHT |
858 PPP_SRC_UNPACK_ALIGN_LSB |
859 PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
860
861 if (iBuf->mdpImg.imgType == MDP_Y_CRCB_H2V2)
862 packPattern =
863 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
864 else
865 packPattern =
866 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
867
868 ppp_operation_reg |= PPP_OP_COLOR_SPACE_YCBCR |
869 PPP_OP_SRC_CHROMA_420 |
870 PPP_OP_SRC_CHROMA_COSITE |
871 PPP_OP_DST_CHROMA_RGB | PPP_OP_DST_CHROMA_COSITE;
872
873 inputRGB = FALSE;
874 sh_slice = sv_slice = 2;
875 break;
876
877 case MDP_YCRYCB_H2V1:
878 inpBpp = 2;
879 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
880 PPP_SRC_C0G_8BITS |
881 PPP_SRC_C1B_8BITS |
882 PPP_SRC_C3A_8BITS |
883 PPP_SRC_BPP_INTERLVD_2BYTES |
884 PPP_SRC_INTERLVD_4COMPONENTS |
885 PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB;
886
887 packPattern =
888 MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
889
890 ppp_operation_reg |= PPP_OP_SRC_CHROMA_H2V1 |
891 PPP_OP_SRC_CHROMA_COSITE | PPP_OP_DST_CHROMA_COSITE;
892
893 /*
894 * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the
895 * preloaded inverse gamma setting of 2.2 since they're
896 * symetric when the content is non-linear
897 * ppp_lookUp_enable = TRUE;
898 */
899
900 /* x and width must be even number */
901 iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
902 iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
903 iBuf->roi.x = (iBuf->roi.x / 2) * 2;
904 iBuf->roi.width = (iBuf->roi.width / 2) * 2;
905
906 inputRGB = FALSE;
907 sh_slice = 2;
908 break;
909
910 case MDP_Y_CBCR_H2V1:
911 case MDP_Y_CRCB_H2V1:
912 inpBpp = 1;
913 src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
914
915 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
916 PPP_SRC_C0G_8BITS |
917 PPP_SRC_C1B_8BITS |
918 PPP_SRC_C3A_8BITS |
919 PPP_SRC_BPP_INTERLVD_2BYTES |
920 PPP_SRC_INTERLVD_2COMPONENTS |
921 PPP_SRC_UNPACK_TIGHT |
922 PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
923
924 if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V1)
925 packPattern =
926 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
927 else
928 packPattern =
929 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
930
931 ppp_operation_reg |= PPP_OP_SRC_CHROMA_H2V1 |
932 PPP_OP_SRC_CHROMA_COSITE | PPP_OP_DST_CHROMA_COSITE;
933 inputRGB = FALSE;
934 sh_slice = 2;
935 break;
936
937 case MDP_BGR_565:
938 case MDP_RGB_565:
939 default:
940 inpBpp = 2;
941 /*
942 * 565 = 2bytes
943 * RGB = 3Components
944 * RGB interleaved
945 */
946 ppp_src_cfg_reg = PPP_SRC_C2R_5BITS | PPP_SRC_C0G_6BITS |
947 PPP_SRC_C1B_5BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
948 PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
949 PPP_SRC_UNPACK_ALIGN_LSB |
950 PPP_SRC_FETCH_PLANES_INTERLVD;
951
952 if (iBuf->mdpImg.imgType == MDP_RGB_565)
953 packPattern =
954 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
955 else
956 packPattern =
957 MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
958
959 ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
960 PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
961 break;
962
963 }
964
965 if (pseudoplanr_output)
966 ppp_dst_cfg_reg |= PPP_DST_PLANE_PSEUDOPLN;
967
968 /* YCbCr to RGB color conversion flag */
969 if ((!inputRGB) && (outputRGB)) {
970 ppp_operation_reg |= PPP_OP_CONVERT_YCBCR2RGB |
971 PPP_OP_CONVERT_ON;
972
973 /*
974 * primary/secondary is sort of misleading term...but
975 * in mdp2.2/3.0 we only use primary matrix (forward/rev)
976 * in mdp3.1 we use set1(prim) and set2(secd)
977 */
978#ifdef CONFIG_FB_MSM_MDP31
979 ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_SECONDARY |
980 PPP_OP_DST_RGB;
981 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0);
982#endif
983
984 if (ppp_lookUp_enable) {
985 ppp_operation_reg |= PPP_OP_LUT_C0_ON |
986 PPP_OP_LUT_C1_ON | PPP_OP_LUT_C2_ON;
987 }
988 }
989 /* RGB to YCbCr color conversion flag */
990 if ((inputRGB) && (!outputRGB)) {
991 ppp_operation_reg |= PPP_OP_CONVERT_RGB2YCBCR |
992 PPP_OP_CONVERT_ON;
993
994#ifdef CONFIG_FB_MSM_MDP31
995 ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_PRIMARY |
996 PPP_OP_DST_YCBCR;
997 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0x1e);
998#endif
999
1000 if (ppp_lookUp_enable) {
1001 ppp_operation_reg |= PPP_OP_LUT_C0_ON |
1002 PPP_OP_LUT_C1_ON | PPP_OP_LUT_C2_ON;
1003 }
1004 }
1005 /* YCbCr to YCbCr color conversion flag */
1006 if ((!inputRGB) && (!outputRGB)) {
1007 if ((ppp_lookUp_enable) &&
1008 (iBuf->mdpImg.imgType != iBuf->ibuf_type)) {
1009 ppp_operation_reg |= PPP_OP_LUT_C0_ON;
1010 }
1011 }
1012
1013 ppp_src_cfg_reg |= (iBuf->roi.x % 2) ? PPP_SRC_BPP_ROI_ODD_X : 0;
1014 ppp_src_cfg_reg |= (iBuf->roi.y % 2) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
1015
1016 if (req->flags & MDP_DEINTERLACE)
1017 ppp_operation_reg |= PPP_OP_DEINT_EN;
1018
1019 /* Dither at DMA side only since iBuf format is RGB888 */
1020 if (iBuf->mdpImg.mdpOp & MDPOP_DITHER)
1021 ppp_operation_reg |= PPP_OP_DITHER_EN;
1022
1023 if (iBuf->mdpImg.mdpOp & MDPOP_ROTATION) {
1024 ppp_operation_reg |= PPP_OP_ROT_ON;
1025
1026 if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
1027 ppp_operation_reg |= PPP_OP_ROT_90;
1028 }
1029 if (iBuf->mdpImg.mdpOp & MDPOP_LR) {
1030 ppp_operation_reg |= PPP_OP_FLIP_LR;
1031 }
1032 if (iBuf->mdpImg.mdpOp & MDPOP_UD) {
1033 ppp_operation_reg |= PPP_OP_FLIP_UD;
1034 }
1035 }
1036
1037 src0_ystride = src_width * inpBpp;
1038 dest0_ystride = iBuf->ibuf_width * iBuf->bpp;
1039
1040 /* no need to care about rotation since it's the real-XY. */
1041 dst_roi_width = iBuf->roi.dst_width;
1042 dst_roi_height = iBuf->roi.dst_height;
1043
1044 src0 = (uint8 *) iBuf->mdpImg.bmy_addr;
1045 dest0 = (uint8 *) iBuf->buf;
1046
1047 /* Jumping from Y-Plane to Chroma Plane */
1048 dest1 = mdp_get_chroma_addr(iBuf);
1049
1050 /* first pixel addr calculation */
1051 mdp_adjust_start_addr(&src0, &src1, sv_slice, sh_slice, iBuf->roi.x,
1052 iBuf->roi.y, src_width, src_height, inpBpp, iBuf,
1053 0);
1054 mdp_adjust_start_addr(&dest0, &dest1, dv_slice, dh_slice,
1055 iBuf->roi.lcd_x, iBuf->roi.lcd_y,
1056 iBuf->ibuf_width, iBuf->ibuf_height, iBuf->bpp,
1057 iBuf, 2);
1058
1059 /* set scale operation */
1060 mdp_set_scale(iBuf, dst_roi_width, dst_roi_height,
1061 inputRGB, outputRGB, &ppp_operation_reg);
1062
1063 /*
1064 * setting background source for blending
1065 */
1066 mdp_set_blend_attr(iBuf, &alpha, &tpVal, perPixelAlpha,
1067 &ppp_operation_reg);
1068
1069 if (ppp_operation_reg & PPP_OP_BLEND_ON) {
1070 mdp_ppp_setbg(iBuf);
1071
1072 if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
1073 ppp_operation_reg |= PPP_OP_BG_CHROMA_H2V1;
1074
1075 if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) {
1076 tpVal = mdp_conv_matx_rgb2yuv(tpVal,
1077 (uint16 *) &
1078 mdp_ccs_rgb2yuv,
1079 &mdp_plv[0], NULL);
1080 }
1081 }
1082 }
1083
1084 /*
1085 * 0x0004: enable dbg bus
1086 * 0x0100: "don't care" Edge Condit until scaling is on
1087 * 0x0104: xrc tile x&y size u7.6 format = 7bit.6bit
1088 * 0x0108: src pixel size
1089 * 0x010c: component plane 0 starting address
1090 * 0x011c: component plane 0 ystride
1091 * 0x0124: PPP source config register
1092 * 0x0128: unpacked pattern from lsb to msb (eg. RGB->BGR)
1093 */
1094 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0108, (iBuf->roi.height << 16 |
1095 iBuf->roi.width));
1096 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x010c, src0); /* comp.plane 0 */
1097 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0110, src1); /* comp.plane 1 */
1098 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x011c,
1099 (src0_ystride << 16 | src0_ystride));
1100
1101 /* setup for rgb 565 */
1102 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0124, ppp_src_cfg_reg);
1103 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0128, packPattern);
1104 /*
1105 * 0x0138: PPP destination operation register
1106 * 0x014c: constant_alpha|transparent_color
1107 * 0x0150: PPP destination config register
1108 * 0x0154: PPP packing pattern
1109 */
1110 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0138, ppp_operation_reg);
1111 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x014c, alpha << 24 | tpVal);
1112 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0150, ppp_dst_cfg_reg);
1113 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0154, dst_packPattern);
1114
1115 /*
1116 * 0x0164: ROI height and width
1117 * 0x0168: Component Plane 0 starting addr
1118 * 0x016c: Component Plane 1 starting addr
1119 * 0x0178: Component Plane 1/0 y stride
1120 */
1121 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0164,
1122 (dst_roi_height << 16 | dst_roi_width));
1123 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0168, dest0);
1124 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x016c, dest1);
1125 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0178,
1126 (dest0_ystride << 16 | dest0_ystride));
1127
1128 flush_imgs(req, inpBpp, iBuf->bpp, p_src_file, p_dst_file);
1129#ifdef CONFIG_MDP_PPP_ASYNC_OP
1130 mdp_ppp_process_curr_djob();
1131#else
1132 mdp_pipe_kickoff(MDP_PPP_TERM, mfd);
1133#endif
1134}
1135
1136static int mdp_ppp_verify_req(struct mdp_blit_req *req)
1137{
1138 u32 src_width, src_height, dst_width, dst_height;
1139
1140 if (req == NULL)
1141 return -1;
1142
1143 if (MDP_IS_IMGTYPE_BAD(req->src.format) ||
1144 MDP_IS_IMGTYPE_BAD(req->dst.format))
1145 return -1;
1146
1147 if ((req->src.width == 0) || (req->src.height == 0) ||
1148 (req->src_rect.w == 0) || (req->src_rect.h == 0) ||
1149 (req->dst.width == 0) || (req->dst.height == 0) ||
1150 (req->dst_rect.w == 0) || (req->dst_rect.h == 0))
1151
1152 return -1;
1153
1154 if (((req->src_rect.x + req->src_rect.w) > req->src.width) ||
1155 ((req->src_rect.y + req->src_rect.h) > req->src.height))
1156 return -1;
1157
1158 if (((req->dst_rect.x + req->dst_rect.w) > req->dst.width) ||
1159 ((req->dst_rect.y + req->dst_rect.h) > req->dst.height))
1160 return -1;
1161
1162 /*
1163 * scaling range check
1164 */
1165 src_width = req->src_rect.w;
1166 src_height = req->src_rect.h;
1167
1168 if (req->flags & MDP_ROT_90) {
1169 dst_width = req->dst_rect.h;
1170 dst_height = req->dst_rect.w;
1171 } else {
1172 dst_width = req->dst_rect.w;
1173 dst_height = req->dst_rect.h;
1174 }
1175
1176 switch (req->dst.format) {
1177 case MDP_Y_CRCB_H2V2:
1178 case MDP_Y_CBCR_H2V2:
1179 src_width = (src_width / 2) * 2;
1180 src_height = (src_height / 2) * 2;
1181 dst_width = (src_width / 2) * 2;
1182 dst_height = (src_height / 2) * 2;
1183 break;
1184
1185 case MDP_Y_CRCB_H2V1:
1186 case MDP_Y_CBCR_H2V1:
1187 case MDP_YCRYCB_H2V1:
1188 src_width = (src_width / 2) * 2;
1189 dst_width = (src_width / 2) * 2;
1190 break;
1191
1192 default:
1193 break;
1194 }
1195
1196 if (((MDP_SCALE_Q_FACTOR * dst_width) / src_width >
1197 MDP_MAX_X_SCALE_FACTOR)
1198 || ((MDP_SCALE_Q_FACTOR * dst_width) / src_width <
1199 MDP_MIN_X_SCALE_FACTOR))
1200 return -1;
1201
1202 if (((MDP_SCALE_Q_FACTOR * dst_height) / src_height >
1203 MDP_MAX_Y_SCALE_FACTOR)
1204 || ((MDP_SCALE_Q_FACTOR * dst_height) / src_height <
1205 MDP_MIN_Y_SCALE_FACTOR))
1206 return -1;
1207
1208 return 0;
1209}
1210
1211/**
1212 * get_gem_img() - retrieve drm obj's start address and size
1213 * @img: contains drm file descriptor and gem handle
1214 * @start: repository of starting address of drm obj allocated memory
1215 * @len: repository of size of drm obj alloacted memory
1216 *
1217 **/
1218int get_gem_img(struct mdp_img *img, unsigned long *start, unsigned long *len)
1219{
1220 panic("waaaaaaaah");
1221 //return kgsl_gem_obj_addr(img->memory_id, (int)img->priv, start, len);
1222}
1223
1224int get_img(struct mdp_img *img, struct fb_info *info, unsigned long *start,
1225 unsigned long *len, struct file **pp_file)
1226{
1227 int put_needed, ret = 0;
1228 struct file *file;
1229 unsigned long vstart;
1230#ifdef CONFIG_ANDROID_PMEM
1231 if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
1232 return 0;
1233#endif
1234 file = fget_light(img->memory_id, &put_needed);
1235 if (file == NULL)
1236 return -1;
1237
1238 if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
1239 *start = info->fix.smem_start;
1240 *len = info->fix.smem_len;
1241 *pp_file = file;
1242 } else {
1243 ret = -1;
1244 fput_light(file, put_needed);
1245 }
1246 return ret;
1247}
1248
1249int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req,
1250 struct file **pp_src_file, struct file **pp_dst_file)
1251{
1252 unsigned long src_start, dst_start;
1253 unsigned long src_len = 0;
1254 unsigned long dst_len = 0;
1255 MDPIBUF iBuf;
1256 u32 dst_width, dst_height;
1257 struct file *p_src_file = 0 , *p_dst_file = 0;
1258 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1259
1260 if (req->dst.format == MDP_FB_FORMAT)
1261 req->dst.format = mfd->fb_imgType;
1262 if (req->src.format == MDP_FB_FORMAT)
1263 req->src.format = mfd->fb_imgType;
1264
1265 if (req->flags & MDP_BLIT_SRC_GEM) {
1266 if (get_gem_img(&req->src, &src_start, &src_len) < 0)
1267 return -1;
1268 } else {
1269 get_img(&req->src, info, &src_start, &src_len, &p_src_file);
1270 }
1271 if (src_len == 0) {
1272 printk(KERN_ERR "mdp_ppp: could not retrieve image from "
1273 "memory\n");
1274 return -1;
1275 }
1276
1277 if (req->flags & MDP_BLIT_DST_GEM) {
1278 if (get_gem_img(&req->dst, &dst_start, &dst_len) < 0)
1279 return -1;
1280 } else {
1281 get_img(&req->dst, info, &dst_start, &dst_len, &p_dst_file);
1282 }
1283 if (dst_len == 0) {
1284 printk(KERN_ERR "mdp_ppp: could not retrieve image from "
1285 "memory\n");
1286 return -1;
1287 }
1288 *pp_src_file = p_src_file;
1289 *pp_dst_file = p_dst_file;
1290 if (mdp_ppp_verify_req(req)) {
1291 printk(KERN_ERR "mdp_ppp: invalid image!\n");
1292 return -1;
1293 }
1294
1295 iBuf.ibuf_width = req->dst.width;
1296 iBuf.ibuf_height = req->dst.height;
1297 iBuf.bpp = bytes_per_pixel[req->dst.format];
1298
1299 iBuf.ibuf_type = req->dst.format;
1300 iBuf.buf = (uint8 *) dst_start;
1301 iBuf.buf += req->dst.offset;
1302
1303 iBuf.roi.lcd_x = req->dst_rect.x;
1304 iBuf.roi.lcd_y = req->dst_rect.y;
1305 iBuf.roi.dst_width = req->dst_rect.w;
1306 iBuf.roi.dst_height = req->dst_rect.h;
1307
1308 iBuf.roi.x = req->src_rect.x;
1309 iBuf.roi.width = req->src_rect.w;
1310 iBuf.roi.y = req->src_rect.y;
1311 iBuf.roi.height = req->src_rect.h;
1312
1313 iBuf.mdpImg.width = req->src.width;
1314 iBuf.mdpImg.imgType = req->src.format;
1315
1316 iBuf.mdpImg.bmy_addr = (uint32 *) (src_start + req->src.offset);
1317 iBuf.mdpImg.cbcr_addr =
1318 (uint32 *) ((uint32) iBuf.mdpImg.bmy_addr +
1319 req->src.width * req->src.height);
1320
1321 iBuf.mdpImg.mdpOp = MDPOP_NOP;
1322
1323 /* blending check */
1324 if (req->transp_mask != MDP_TRANSP_NOP) {
1325 iBuf.mdpImg.mdpOp |= MDPOP_TRANSP;
1326 iBuf.mdpImg.tpVal = req->transp_mask;
1327 iBuf.mdpImg.tpVal = mdp_calc_tpval(&iBuf.mdpImg);
1328 }
1329
1330 req->alpha &= 0xff;
1331 if (req->alpha < MDP_ALPHA_NOP) {
1332 iBuf.mdpImg.mdpOp |= MDPOP_ALPHAB;
1333 iBuf.mdpImg.alpha = req->alpha;
1334 }
1335
1336 /* rotation check */
1337 if (req->flags & MDP_FLIP_LR)
1338 iBuf.mdpImg.mdpOp |= MDPOP_LR;
1339 if (req->flags & MDP_FLIP_UD)
1340 iBuf.mdpImg.mdpOp |= MDPOP_UD;
1341 if (req->flags & MDP_ROT_90)
1342 iBuf.mdpImg.mdpOp |= MDPOP_ROT90;
1343 if (req->flags & MDP_DITHER)
1344 iBuf.mdpImg.mdpOp |= MDPOP_DITHER;
1345
1346 if (req->flags & MDP_BLEND_FG_PREMULT) {
1347#ifdef CONFIG_FB_MSM_MDP31
1348 iBuf.mdpImg.mdpOp |= MDPOP_FG_PM_ALPHA;
1349#else
1350 return -EINVAL;
1351#endif
1352 }
1353
1354 if (req->flags & MDP_DEINTERLACE) {
1355#ifdef CONFIG_FB_MSM_MDP31
1356 if ((req->src.format != MDP_Y_CBCR_H2V2) &&
1357 (req->src.format != MDP_Y_CRCB_H2V2))
1358#endif
1359 return -EINVAL;
1360 }
1361
1362 /* scale check */
1363 if (req->flags & MDP_ROT_90) {
1364 dst_width = req->dst_rect.h;
1365 dst_height = req->dst_rect.w;
1366 } else {
1367 dst_width = req->dst_rect.w;
1368 dst_height = req->dst_rect.h;
1369 }
1370
1371 if ((iBuf.roi.width != dst_width) || (iBuf.roi.height != dst_height))
1372 iBuf.mdpImg.mdpOp |= MDPOP_ASCALE;
1373
1374 if (req->flags & MDP_BLUR) {
1375#ifdef CONFIG_FB_MSM_MDP31
1376 if (req->flags & MDP_SHARPENING)
1377 printk(KERN_WARNING
1378 "mdp: MDP_SHARPENING is set with MDP_BLUR!\n");
1379 req->flags |= MDP_SHARPENING;
1380 req->sharpening_strength = -127;
1381#else
1382 iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_BLUR;
1383
1384#endif
1385 }
1386
1387 if (req->flags & MDP_SHARPENING) {
1388#ifdef CONFIG_FB_MSM_MDP31
1389 if ((req->sharpening_strength > 127) ||
1390 (req->sharpening_strength < -127)) {
1391 printk(KERN_ERR
1392 "%s: sharpening strength out of range\n",
1393 __func__);
1394 return -EINVAL;
1395 }
1396
1397 iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_SHARPENING;
1398 iBuf.mdpImg.sp_value = req->sharpening_strength & 0xff;
1399#else
1400 return -EINVAL;
1401#endif
1402 }
1403
1404 down(&mdp_ppp_mutex);
1405 /* MDP cmd block enable */
1406 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1407
1408#ifdef CONFIG_FB_MSM_MDP31
1409 mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
1410#else
1411 /* bg tile fetching HW workaround */
1412 if (((iBuf.mdpImg.mdpOp & (MDPOP_TRANSP | MDPOP_ALPHAB)) ||
1413 (req->src.format == MDP_ARGB_8888) ||
1414 (req->src.format == MDP_BGRA_8888) ||
1415 (req->src.format == MDP_RGBA_8888)) &&
1416 (iBuf.mdpImg.mdpOp & MDPOP_ROT90) && (req->dst_rect.w <= 16)) {
1417 int dst_h, src_w, i;
1418
1419 src_w = req->src_rect.w;
1420 dst_h = iBuf.roi.dst_height;
1421
1422 for (i = 0; i < (req->dst_rect.h / 16); i++) {
1423 /* this tile size */
1424 iBuf.roi.dst_height = 16;
1425 iBuf.roi.width =
1426 (16 * req->src_rect.w) / req->dst_rect.h;
1427
1428 /* if it's out of scale range... */
1429 if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1430 iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR)
1431 iBuf.roi.width =
1432 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1433 MDP_MAX_X_SCALE_FACTOR;
1434 else if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1435 iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR)
1436 iBuf.roi.width =
1437 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1438 MDP_MIN_X_SCALE_FACTOR;
1439
1440 mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
1441
1442 /* next tile location */
1443 iBuf.roi.lcd_y += 16;
1444 iBuf.roi.x += iBuf.roi.width;
1445
1446 /* this is for a remainder update */
1447 dst_h -= 16;
1448 src_w -= iBuf.roi.width;
1449 }
1450
1451 if ((dst_h < 0) || (src_w < 0))
1452 printk
1453 ("msm_fb: mdp_blt_ex() unexpected result! line:%d\n",
1454 __LINE__);
1455
1456 /* remainder update */
1457 if ((dst_h > 0) && (src_w > 0)) {
1458 u32 tmp_v;
1459
1460 iBuf.roi.dst_height = dst_h;
1461 iBuf.roi.width = src_w;
1462
1463 if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1464 iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR) {
1465 tmp_v =
1466 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1467 MDP_MAX_X_SCALE_FACTOR +
1468 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) %
1469 MDP_MAX_X_SCALE_FACTOR ? 1 : 0;
1470
1471 /* move x location as roi width gets bigger */
1472 iBuf.roi.x -= tmp_v - iBuf.roi.width;
1473 iBuf.roi.width = tmp_v;
1474 } else
1475 if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1476 iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR) {
1477 tmp_v =
1478 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1479 MDP_MIN_X_SCALE_FACTOR +
1480 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) %
1481 MDP_MIN_X_SCALE_FACTOR ? 1 : 0;
1482
1483 /*
1484 * we don't move x location for continuity of
1485 * source image
1486 */
1487 iBuf.roi.width = tmp_v;
1488 }
1489
1490 mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
1491 }
1492 } else {
1493 mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
1494 }
1495#endif
1496
1497 /* MDP cmd block disable */
1498 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1499 up(&mdp_ppp_mutex);
1500
1501 return 0;
1502}
diff --git a/drivers/staging/msm/mdp_ppp_dq.c b/drivers/staging/msm/mdp_ppp_dq.c
new file mode 100644
index 000000000000..3dc1c0cc61f9
--- /dev/null
+++ b/drivers/staging/msm/mdp_ppp_dq.c
@@ -0,0 +1,347 @@
1/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "mdp.h"
19
20static boolean mdp_ppp_intr_flag = FALSE;
21static boolean mdp_ppp_busy_flag = FALSE;
22
23/* Queue to keep track of the completed jobs for cleaning */
24static LIST_HEAD(mdp_ppp_djob_clnrq);
25static DEFINE_SPINLOCK(mdp_ppp_djob_clnrq_lock);
26
27/* Worker to cleanup Display Jobs */
28static struct workqueue_struct *mdp_ppp_djob_clnr;
29
30/* Display Queue (DQ) for MDP PPP Block */
31static LIST_HEAD(mdp_ppp_dq);
32static DEFINE_SPINLOCK(mdp_ppp_dq_lock);
33
34/* Current Display Job for MDP PPP */
35static struct mdp_ppp_djob *curr_djob;
36
37/* Track ret code for the last opeartion */
38static int mdp_ppp_ret_code;
39
40inline int mdp_ppp_get_ret_code(void)
41{
42 return mdp_ppp_ret_code;
43}
44
45/* Push <Reg, Val> pair into DQ (if available) to later
46 * program the MDP PPP Block */
47inline void mdp_ppp_outdw(uint32_t addr, uint32_t data)
48{
49 if (curr_djob) {
50
51 /* get the last node of the list. */
52 struct mdp_ppp_roi_cmd_set *node =
53 list_entry(curr_djob->roi_cmd_list.prev,
54 struct mdp_ppp_roi_cmd_set, node);
55
56 /* If a node is already full, create a new one and add it to
57 * the list (roi_cmd_list).
58 */
59 if (node->ncmds == MDP_PPP_ROI_NODE_SIZE) {
60 node = kmalloc(sizeof(struct mdp_ppp_roi_cmd_set),
61 GFP_KERNEL);
62 if (!node) {
63 printk(KERN_ERR
64 "MDP_PPP: not enough memory.\n");
65 mdp_ppp_ret_code = -EINVAL;
66 return;
67 }
68
69 /* no ROI commands initially */
70 node->ncmds = 0;
71
72 /* add one node to roi_cmd_list. */
73 list_add_tail(&node->node, &curr_djob->roi_cmd_list);
74 }
75
76 /* register ROI commands */
77 node->cmd[node->ncmds].reg = addr;
78 node->cmd[node->ncmds].val = data;
79 node->ncmds++;
80 } else
81 /* program MDP PPP block now */
82 outpdw((addr), (data));
83}
84
85/* Initialize DQ */
86inline void mdp_ppp_dq_init(void)
87{
88 mdp_ppp_djob_clnr = create_singlethread_workqueue("MDPDJobClnrThrd");
89}
90
91/* Release resources of a job (DJob). */
92static void mdp_ppp_del_djob(struct mdp_ppp_djob *job)
93{
94 struct mdp_ppp_roi_cmd_set *node, *tmp;
95
96 /* release mem */
97 mdp_ppp_put_img(job->p_src_file, job->p_dst_file);
98
99 /* release roi_cmd_list */
100 list_for_each_entry_safe(node, tmp, &job->roi_cmd_list, node) {
101 list_del(&node->node);
102 kfree(node);
103 }
104
105 /* release job struct */
106 kfree(job);
107}
108
109/* Worker thread to reclaim resources once a display job is done */
110static void mdp_ppp_djob_cleaner(struct work_struct *work)
111{
112 struct mdp_ppp_djob *job;
113
114 MDP_PPP_DEBUG_MSG("mdp ppp display job cleaner started \n");
115
116 /* cleanup display job */
117 job = container_of(work, struct mdp_ppp_djob, cleaner.work);
118 if (likely(work && job))
119 mdp_ppp_del_djob(job);
120}
121
122/* Create a new Display Job (DJob) */
123inline struct mdp_ppp_djob *mdp_ppp_new_djob(void)
124{
125 struct mdp_ppp_djob *job;
126 struct mdp_ppp_roi_cmd_set *node;
127
128 /* create a new djob */
129 job = kmalloc(sizeof(struct mdp_ppp_djob), GFP_KERNEL);
130 if (!job)
131 return NULL;
132
133 /* add the first node to curr_djob->roi_cmd_list */
134 node = kmalloc(sizeof(struct mdp_ppp_roi_cmd_set), GFP_KERNEL);
135 if (!node) {
136 kfree(job);
137 return NULL;
138 }
139
140 /* make this current djob container to keep track of the curr djob not
141 * used in the async path i.e. no sync needed
142 *
143 * Should not contain any references from the past djob
144 */
145 BUG_ON(curr_djob);
146 curr_djob = job;
147 INIT_LIST_HEAD(&curr_djob->roi_cmd_list);
148
149 /* no ROI commands initially */
150 node->ncmds = 0;
151 INIT_LIST_HEAD(&node->node);
152 list_add_tail(&node->node, &curr_djob->roi_cmd_list);
153
154 /* register this djob with the djob cleaner
155 * initializes 'work' data struct
156 */
157 INIT_DELAYED_WORK(&curr_djob->cleaner, mdp_ppp_djob_cleaner);
158 INIT_LIST_HEAD(&curr_djob->entry);
159
160 curr_djob->p_src_file = 0;
161 curr_djob->p_dst_file = 0;
162
163 return job;
164}
165
166/* Undo the effect of mdp_ppp_new_djob() */
167inline void mdp_ppp_clear_curr_djob(void)
168{
169 if (likely(curr_djob)) {
170 mdp_ppp_del_djob(curr_djob);
171 curr_djob = NULL;
172 }
173}
174
175/* Cleanup dirty djobs */
176static void mdp_ppp_flush_dirty_djobs(void *cond)
177{
178 unsigned long flags;
179 struct mdp_ppp_djob *job;
180
181 /* Flush the jobs from the djob clnr queue */
182 while (cond && test_bit(0, (unsigned long *)cond)) {
183
184 /* Until we are done with the cleanup queue */
185 spin_lock_irqsave(&mdp_ppp_djob_clnrq_lock, flags);
186 if (list_empty(&mdp_ppp_djob_clnrq)) {
187 spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags);
188 break;
189 }
190
191 MDP_PPP_DEBUG_MSG("flushing djobs ... loop \n");
192
193 /* Retrieve the job that needs to be cleaned */
194 job = list_entry(mdp_ppp_djob_clnrq.next,
195 struct mdp_ppp_djob, entry);
196 list_del_init(&job->entry);
197 spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags);
198
199 /* Keep mem state coherent */
200 msm_fb_ensure_mem_coherency_after_dma(job->info, &job->req, 1);
201
202 /* Schedule jobs for cleanup
203 * A seperate worker thread does this */
204 queue_delayed_work(mdp_ppp_djob_clnr, &job->cleaner,
205 mdp_timer_duration);
206 }
207}
208
209/* If MDP PPP engine is busy, wait until it is available again */
210void mdp_ppp_wait(void)
211{
212 unsigned long flags;
213 int cond = 1;
214
215 /* keep flushing dirty djobs as long as MDP PPP engine is busy */
216 mdp_ppp_flush_dirty_djobs(&mdp_ppp_busy_flag);
217
218 /* block if MDP PPP engine is still busy */
219 spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
220 if (test_bit(0, (unsigned long *)&mdp_ppp_busy_flag)) {
221
222 /* prepare for the wakeup event */
223 test_and_set_bit(0, (unsigned long *)&mdp_ppp_waiting);
224 INIT_COMPLETION(mdp_ppp_comp);
225 spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
226
227 /* block uninterruptibly until available */
228 MDP_PPP_DEBUG_MSG("waiting for mdp... \n");
229 wait_for_completion_killable(&mdp_ppp_comp);
230
231 /* if MDP PPP engine is still free,
232 * disable INT_MDP if enabled
233 */
234 spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
235 if (!test_bit(0, (unsigned long *)&mdp_ppp_busy_flag) &&
236 test_and_clear_bit(0, (unsigned long *)&mdp_ppp_intr_flag))
237 mdp_disable_irq(MDP_PPP_TERM);
238 }
239 spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
240
241 /* flush remaining dirty djobs, if any */
242 mdp_ppp_flush_dirty_djobs(&cond);
243}
244
245/* Program MDP PPP block to process this ROI */
246static void mdp_ppp_process_roi(struct list_head *roi_cmd_list)
247{
248
249 /* program PPP engine with registered ROI commands */
250 struct mdp_ppp_roi_cmd_set *node;
251 list_for_each_entry(node, roi_cmd_list, node) {
252 int i = 0;
253 for (; i < node->ncmds; i++) {
254 MDP_PPP_DEBUG_MSG("%d: reg: 0x%x val: 0x%x \n",
255 i, node->cmd[i].reg, node->cmd[i].val);
256 outpdw(node->cmd[i].reg, node->cmd[i].val);
257 }
258 }
259
260 /* kickoff MDP PPP engine */
261 MDP_PPP_DEBUG_MSG("kicking off mdp \n");
262 outpdw(MDP_BASE + 0x30, 0x1000);
263}
264
265/* Submit this display job to MDP PPP engine */
266static void mdp_ppp_dispatch_djob(struct mdp_ppp_djob *job)
267{
268 /* enable INT_MDP if disabled */
269 if (!test_and_set_bit(0, (unsigned long *)&mdp_ppp_intr_flag))
270 mdp_enable_irq(MDP_PPP_TERM);
271
272 /* turn on PPP and CMD blocks */
273 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
274 mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
275
276 /* process this ROI */
277 mdp_ppp_process_roi(&job->roi_cmd_list);
278}
279
280/* Enqueue this display job to be cleaned up later in "mdp_ppp_djob_done" */
281static inline void mdp_ppp_enqueue_djob(struct mdp_ppp_djob *job)
282{
283 unsigned long flags;
284
285 spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
286 list_add_tail(&job->entry, &mdp_ppp_dq);
287 spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
288}
289
290/* First enqueue display job for cleanup and dispatch immediately
291 * if MDP PPP engine is free */
292void mdp_ppp_process_curr_djob(void)
293{
294 /* enqueue djob */
295 mdp_ppp_enqueue_djob(curr_djob);
296
297 /* dispatch now if MDP PPP engine is free */
298 if (!test_and_set_bit(0, (unsigned long *)&mdp_ppp_busy_flag))
299 mdp_ppp_dispatch_djob(curr_djob);
300
301 /* done with the current djob */
302 curr_djob = NULL;
303}
304
305/* Called from mdp_isr - cleanup finished job and start with next
306 * if available else set MDP PPP engine free */
307void mdp_ppp_djob_done(void)
308{
309 struct mdp_ppp_djob *curr, *next;
310 unsigned long flags;
311
312 /* dequeue current */
313 spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
314 curr = list_entry(mdp_ppp_dq.next, struct mdp_ppp_djob, entry);
315 list_del_init(&curr->entry);
316 spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
317
318 /* cleanup current - enqueue in the djob clnr queue */
319 spin_lock_irqsave(&mdp_ppp_djob_clnrq_lock, flags);
320 list_add_tail(&curr->entry, &mdp_ppp_djob_clnrq);
321 spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags);
322
323 /* grab next pending */
324 spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
325 if (!list_empty(&mdp_ppp_dq)) {
326 next = list_entry(mdp_ppp_dq.next, struct mdp_ppp_djob,
327 entry);
328 spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
329
330 /* process next in the queue */
331 mdp_ppp_process_roi(&next->roi_cmd_list);
332 } else {
333 /* no pending display job */
334 spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
335
336 /* turn off PPP and CMD blocks - "in_isr" is TRUE */
337 mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
338 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
339
340 /* notify if waiting */
341 if (test_and_clear_bit(0, (unsigned long *)&mdp_ppp_waiting))
342 complete(&mdp_ppp_comp);
343
344 /* set free */
345 test_and_clear_bit(0, (unsigned long *)&mdp_ppp_busy_flag);
346 }
347}
diff --git a/drivers/staging/msm/mdp_ppp_dq.h b/drivers/staging/msm/mdp_ppp_dq.h
new file mode 100644
index 000000000000..03e4e9a5f234
--- /dev/null
+++ b/drivers/staging/msm/mdp_ppp_dq.h
@@ -0,0 +1,86 @@
1/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef MDP_PPP_DQ_H
31#define MDP_PPP_DQ_H
32
33#include "msm_fb_def.h"
34
35#define MDP_PPP_DEBUG_MSG MSM_FB_DEBUG
36
37/* The maximum number of <Reg,Val> pairs in an mdp_ppp_roi_cmd_set structure (a
38 * node)
39 */
40#define MDP_PPP_ROI_NODE_SIZE 32
41
42/* ROI config command (<Reg,Val> pair) for MDP PPP block */
43struct mdp_ppp_roi_cmd {
44 uint32_t reg;
45 uint32_t val;
46};
47
48/* ROI config commands for MDP PPP block are stored in a list of
49 * mdp_ppp_roi_cmd_set structures (nodes).
50 */
51struct mdp_ppp_roi_cmd_set {
52 struct list_head node;
53 uint32_t ncmds; /* number of commands in this set (node). */
54 struct mdp_ppp_roi_cmd cmd[MDP_PPP_ROI_NODE_SIZE];
55};
56
57/* MDP PPP Display Job (DJob) */
58struct mdp_ppp_djob {
59 struct list_head entry;
60 /* One ROI per MDP PPP DJob */
61 struct list_head roi_cmd_list;
62 struct mdp_blit_req req;
63 struct fb_info *info;
64 struct delayed_work cleaner;
65 struct file *p_src_file, *p_dst_file;
66};
67
68extern struct completion mdp_ppp_comp;
69extern boolean mdp_ppp_waiting;
70extern unsigned long mdp_timer_duration;
71
72unsigned int mdp_ppp_async_op_get(void);
73void mdp_ppp_async_op_set(unsigned int flag);
74void msm_fb_ensure_mem_coherency_after_dma(struct fb_info *info,
75 struct mdp_blit_req *req_list, int req_list_count);
76void mdp_ppp_put_img(struct file *p_src_file, struct file *p_dst_file);
77void mdp_ppp_dq_init(void);
78void mdp_ppp_outdw(uint32_t addr, uint32_t data);
79struct mdp_ppp_djob *mdp_ppp_new_djob(void);
80void mdp_ppp_clear_curr_djob(void);
81void mdp_ppp_process_curr_djob(void);
82int mdp_ppp_get_ret_code(void);
83void mdp_ppp_djob_done(void);
84void mdp_ppp_wait(void);
85
86#endif /* MDP_PPP_DQ_H */
diff --git a/drivers/staging/msm/mdp_ppp_v20.c b/drivers/staging/msm/mdp_ppp_v20.c
new file mode 100644
index 000000000000..b5b7271921e0
--- /dev/null
+++ b/drivers/staging/msm/mdp_ppp_v20.c
@@ -0,0 +1,2486 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/fb.h>
25#include "linux/proc_fs.h"
26
27#include <mach/hardware.h>
28#include <linux/io.h>
29
30#include <asm/system.h>
31#include <asm/mach-types.h>
32#include <linux/semaphore.h>
33#include <asm/div64.h>
34
35#include "mdp.h"
36#include "msm_fb.h"
37
38static MDP_SCALE_MODE mdp_curr_up_scale_xy;
39static MDP_SCALE_MODE mdp_curr_down_scale_x;
40static MDP_SCALE_MODE mdp_curr_down_scale_y;
41
42static long long mdp_do_div(long long num, long long den)
43{
44 do_div(num, den);
45 return num;
46}
47
48struct mdp_table_entry mdp_gaussian_blur_table[] = {
49 /* max variance */
50 { 0x5fffc, 0x20000080 },
51 { 0x50280, 0x20000080 },
52 { 0x5fffc, 0x20000080 },
53 { 0x50284, 0x20000080 },
54 { 0x5fffc, 0x20000080 },
55 { 0x50288, 0x20000080 },
56 { 0x5fffc, 0x20000080 },
57 { 0x5028c, 0x20000080 },
58 { 0x5fffc, 0x20000080 },
59 { 0x50290, 0x20000080 },
60 { 0x5fffc, 0x20000080 },
61 { 0x50294, 0x20000080 },
62 { 0x5fffc, 0x20000080 },
63 { 0x50298, 0x20000080 },
64 { 0x5fffc, 0x20000080 },
65 { 0x5029c, 0x20000080 },
66 { 0x5fffc, 0x20000080 },
67 { 0x502a0, 0x20000080 },
68 { 0x5fffc, 0x20000080 },
69 { 0x502a4, 0x20000080 },
70 { 0x5fffc, 0x20000080 },
71 { 0x502a8, 0x20000080 },
72 { 0x5fffc, 0x20000080 },
73 { 0x502ac, 0x20000080 },
74 { 0x5fffc, 0x20000080 },
75 { 0x502b0, 0x20000080 },
76 { 0x5fffc, 0x20000080 },
77 { 0x502b4, 0x20000080 },
78 { 0x5fffc, 0x20000080 },
79 { 0x502b8, 0x20000080 },
80 { 0x5fffc, 0x20000080 },
81 { 0x502bc, 0x20000080 },
82 { 0x5fffc, 0x20000080 },
83 { 0x502c0, 0x20000080 },
84 { 0x5fffc, 0x20000080 },
85 { 0x502c4, 0x20000080 },
86 { 0x5fffc, 0x20000080 },
87 { 0x502c8, 0x20000080 },
88 { 0x5fffc, 0x20000080 },
89 { 0x502cc, 0x20000080 },
90 { 0x5fffc, 0x20000080 },
91 { 0x502d0, 0x20000080 },
92 { 0x5fffc, 0x20000080 },
93 { 0x502d4, 0x20000080 },
94 { 0x5fffc, 0x20000080 },
95 { 0x502d8, 0x20000080 },
96 { 0x5fffc, 0x20000080 },
97 { 0x502dc, 0x20000080 },
98 { 0x5fffc, 0x20000080 },
99 { 0x502e0, 0x20000080 },
100 { 0x5fffc, 0x20000080 },
101 { 0x502e4, 0x20000080 },
102 { 0x5fffc, 0x20000080 },
103 { 0x502e8, 0x20000080 },
104 { 0x5fffc, 0x20000080 },
105 { 0x502ec, 0x20000080 },
106 { 0x5fffc, 0x20000080 },
107 { 0x502f0, 0x20000080 },
108 { 0x5fffc, 0x20000080 },
109 { 0x502f4, 0x20000080 },
110 { 0x5fffc, 0x20000080 },
111 { 0x502f8, 0x20000080 },
112 { 0x5fffc, 0x20000080 },
113 { 0x502fc, 0x20000080 },
114 { 0x5fffc, 0x20000080 },
115 { 0x50300, 0x20000080 },
116 { 0x5fffc, 0x20000080 },
117 { 0x50304, 0x20000080 },
118 { 0x5fffc, 0x20000080 },
119 { 0x50308, 0x20000080 },
120 { 0x5fffc, 0x20000080 },
121 { 0x5030c, 0x20000080 },
122 { 0x5fffc, 0x20000080 },
123 { 0x50310, 0x20000080 },
124 { 0x5fffc, 0x20000080 },
125 { 0x50314, 0x20000080 },
126 { 0x5fffc, 0x20000080 },
127 { 0x50318, 0x20000080 },
128 { 0x5fffc, 0x20000080 },
129 { 0x5031c, 0x20000080 },
130 { 0x5fffc, 0x20000080 },
131 { 0x50320, 0x20000080 },
132 { 0x5fffc, 0x20000080 },
133 { 0x50324, 0x20000080 },
134 { 0x5fffc, 0x20000080 },
135 { 0x50328, 0x20000080 },
136 { 0x5fffc, 0x20000080 },
137 { 0x5032c, 0x20000080 },
138 { 0x5fffc, 0x20000080 },
139 { 0x50330, 0x20000080 },
140 { 0x5fffc, 0x20000080 },
141 { 0x50334, 0x20000080 },
142 { 0x5fffc, 0x20000080 },
143 { 0x50338, 0x20000080 },
144 { 0x5fffc, 0x20000080 },
145 { 0x5033c, 0x20000080 },
146 { 0x5fffc, 0x20000080 },
147 { 0x50340, 0x20000080 },
148 { 0x5fffc, 0x20000080 },
149 { 0x50344, 0x20000080 },
150 { 0x5fffc, 0x20000080 },
151 { 0x50348, 0x20000080 },
152 { 0x5fffc, 0x20000080 },
153 { 0x5034c, 0x20000080 },
154 { 0x5fffc, 0x20000080 },
155 { 0x50350, 0x20000080 },
156 { 0x5fffc, 0x20000080 },
157 { 0x50354, 0x20000080 },
158 { 0x5fffc, 0x20000080 },
159 { 0x50358, 0x20000080 },
160 { 0x5fffc, 0x20000080 },
161 { 0x5035c, 0x20000080 },
162 { 0x5fffc, 0x20000080 },
163 { 0x50360, 0x20000080 },
164 { 0x5fffc, 0x20000080 },
165 { 0x50364, 0x20000080 },
166 { 0x5fffc, 0x20000080 },
167 { 0x50368, 0x20000080 },
168 { 0x5fffc, 0x20000080 },
169 { 0x5036c, 0x20000080 },
170 { 0x5fffc, 0x20000080 },
171 { 0x50370, 0x20000080 },
172 { 0x5fffc, 0x20000080 },
173 { 0x50374, 0x20000080 },
174 { 0x5fffc, 0x20000080 },
175 { 0x50378, 0x20000080 },
176 { 0x5fffc, 0x20000080 },
177 { 0x5037c, 0x20000080 },
178};
179
180static void load_scale_table(
181 struct mdp_table_entry *table, int len)
182{
183 int i;
184 for (i = 0; i < len; i++)
185 MDP_OUTP(MDP_BASE + table[i].reg, table[i].val);
186}
187
188static void mdp_load_pr_upscale_table(void)
189{
190 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
191 MDP_OUTP(MDP_BASE + 0x50200, 0x7fc00000);
192 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
193 MDP_OUTP(MDP_BASE + 0x50204, 0x7fc00000);
194 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
195 MDP_OUTP(MDP_BASE + 0x50208, 0x7fc00000);
196 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
197 MDP_OUTP(MDP_BASE + 0x5020c, 0x7fc00000);
198 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
199 MDP_OUTP(MDP_BASE + 0x50210, 0x7fc00000);
200 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
201 MDP_OUTP(MDP_BASE + 0x50214, 0x7fc00000);
202 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
203 MDP_OUTP(MDP_BASE + 0x50218, 0x7fc00000);
204 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
205 MDP_OUTP(MDP_BASE + 0x5021c, 0x7fc00000);
206 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
207 MDP_OUTP(MDP_BASE + 0x50220, 0x7fc00000);
208 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
209 MDP_OUTP(MDP_BASE + 0x50224, 0x7fc00000);
210 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
211 MDP_OUTP(MDP_BASE + 0x50228, 0x7fc00000);
212 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
213 MDP_OUTP(MDP_BASE + 0x5022c, 0x7fc00000);
214 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
215 MDP_OUTP(MDP_BASE + 0x50230, 0x7fc00000);
216 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
217 MDP_OUTP(MDP_BASE + 0x50234, 0x7fc00000);
218 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
219 MDP_OUTP(MDP_BASE + 0x50238, 0x7fc00000);
220 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
221 MDP_OUTP(MDP_BASE + 0x5023c, 0x7fc00000);
222 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
223 MDP_OUTP(MDP_BASE + 0x50240, 0x0);
224 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
225 MDP_OUTP(MDP_BASE + 0x50244, 0x0);
226 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
227 MDP_OUTP(MDP_BASE + 0x50248, 0x0);
228 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
229 MDP_OUTP(MDP_BASE + 0x5024c, 0x0);
230 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
231 MDP_OUTP(MDP_BASE + 0x50250, 0x0);
232 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
233 MDP_OUTP(MDP_BASE + 0x50254, 0x0);
234 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
235 MDP_OUTP(MDP_BASE + 0x50258, 0x0);
236 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
237 MDP_OUTP(MDP_BASE + 0x5025c, 0x0);
238 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
239 MDP_OUTP(MDP_BASE + 0x50260, 0x0);
240 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
241 MDP_OUTP(MDP_BASE + 0x50264, 0x0);
242 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
243 MDP_OUTP(MDP_BASE + 0x50268, 0x0);
244 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
245 MDP_OUTP(MDP_BASE + 0x5026c, 0x0);
246 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
247 MDP_OUTP(MDP_BASE + 0x50270, 0x0);
248 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
249 MDP_OUTP(MDP_BASE + 0x50274, 0x0);
250 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
251 MDP_OUTP(MDP_BASE + 0x50278, 0x0);
252 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
253 MDP_OUTP(MDP_BASE + 0x5027c, 0x0);
254}
255
256static void mdp_load_pr_downscale_table_x_point2TOpoint4(void)
257{
258 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
259 MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
260 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
261 MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000);
262 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
263 MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000);
264 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
265 MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000);
266 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
267 MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000);
268 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
269 MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000);
270 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
271 MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000);
272 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
273 MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000);
274 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
275 MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000);
276 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
277 MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000);
278 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
279 MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000);
280 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
281 MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000);
282 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
283 MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000);
284 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
285 MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000);
286 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
287 MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000);
288 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
289 MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000);
290 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
291 MDP_OUTP(MDP_BASE + 0x502c0, 0x0);
292 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
293 MDP_OUTP(MDP_BASE + 0x502c4, 0x0);
294 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
295 MDP_OUTP(MDP_BASE + 0x502c8, 0x0);
296 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
297 MDP_OUTP(MDP_BASE + 0x502cc, 0x0);
298 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
299 MDP_OUTP(MDP_BASE + 0x502d0, 0x0);
300 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
301 MDP_OUTP(MDP_BASE + 0x502d4, 0x0);
302 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
303 MDP_OUTP(MDP_BASE + 0x502d8, 0x0);
304 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
305 MDP_OUTP(MDP_BASE + 0x502dc, 0x0);
306 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
307 MDP_OUTP(MDP_BASE + 0x502e0, 0x0);
308 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
309 MDP_OUTP(MDP_BASE + 0x502e4, 0x0);
310 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
311 MDP_OUTP(MDP_BASE + 0x502e8, 0x0);
312 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
313 MDP_OUTP(MDP_BASE + 0x502ec, 0x0);
314 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
315 MDP_OUTP(MDP_BASE + 0x502f0, 0x0);
316 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
317 MDP_OUTP(MDP_BASE + 0x502f4, 0x0);
318 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
319 MDP_OUTP(MDP_BASE + 0x502f8, 0x0);
320 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
321 MDP_OUTP(MDP_BASE + 0x502fc, 0x0);
322}
323
324static void mdp_load_pr_downscale_table_y_point2TOpoint4(void)
325{
326 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
327 MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
328 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
329 MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000);
330 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
331 MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000);
332 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
333 MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000);
334 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
335 MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000);
336 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
337 MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000);
338 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
339 MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000);
340 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
341 MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000);
342 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
343 MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000);
344 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
345 MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000);
346 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
347 MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000);
348 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
349 MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000);
350 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
351 MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000);
352 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
353 MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000);
354 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
355 MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000);
356 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
357 MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000);
358 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
359 MDP_OUTP(MDP_BASE + 0x50340, 0x0);
360 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
361 MDP_OUTP(MDP_BASE + 0x50344, 0x0);
362 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
363 MDP_OUTP(MDP_BASE + 0x50348, 0x0);
364 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
365 MDP_OUTP(MDP_BASE + 0x5034c, 0x0);
366 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
367 MDP_OUTP(MDP_BASE + 0x50350, 0x0);
368 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
369 MDP_OUTP(MDP_BASE + 0x50354, 0x0);
370 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
371 MDP_OUTP(MDP_BASE + 0x50358, 0x0);
372 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
373 MDP_OUTP(MDP_BASE + 0x5035c, 0x0);
374 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
375 MDP_OUTP(MDP_BASE + 0x50360, 0x0);
376 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
377 MDP_OUTP(MDP_BASE + 0x50364, 0x0);
378 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
379 MDP_OUTP(MDP_BASE + 0x50368, 0x0);
380 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
381 MDP_OUTP(MDP_BASE + 0x5036c, 0x0);
382 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
383 MDP_OUTP(MDP_BASE + 0x50370, 0x0);
384 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
385 MDP_OUTP(MDP_BASE + 0x50374, 0x0);
386 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
387 MDP_OUTP(MDP_BASE + 0x50378, 0x0);
388 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
389 MDP_OUTP(MDP_BASE + 0x5037c, 0x0);
390}
391
392static void mdp_load_pr_downscale_table_x_point4TOpoint6(void)
393{
394 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
395 MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
396 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
397 MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000);
398 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
399 MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000);
400 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
401 MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000);
402 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
403 MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000);
404 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
405 MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000);
406 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
407 MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000);
408 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
409 MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000);
410 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
411 MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000);
412 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
413 MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000);
414 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
415 MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000);
416 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
417 MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000);
418 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
419 MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000);
420 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
421 MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000);
422 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
423 MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000);
424 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
425 MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000);
426 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
427 MDP_OUTP(MDP_BASE + 0x502c0, 0x0);
428 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
429 MDP_OUTP(MDP_BASE + 0x502c4, 0x0);
430 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
431 MDP_OUTP(MDP_BASE + 0x502c8, 0x0);
432 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
433 MDP_OUTP(MDP_BASE + 0x502cc, 0x0);
434 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
435 MDP_OUTP(MDP_BASE + 0x502d0, 0x0);
436 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
437 MDP_OUTP(MDP_BASE + 0x502d4, 0x0);
438 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
439 MDP_OUTP(MDP_BASE + 0x502d8, 0x0);
440 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
441 MDP_OUTP(MDP_BASE + 0x502dc, 0x0);
442 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
443 MDP_OUTP(MDP_BASE + 0x502e0, 0x0);
444 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
445 MDP_OUTP(MDP_BASE + 0x502e4, 0x0);
446 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
447 MDP_OUTP(MDP_BASE + 0x502e8, 0x0);
448 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
449 MDP_OUTP(MDP_BASE + 0x502ec, 0x0);
450 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
451 MDP_OUTP(MDP_BASE + 0x502f0, 0x0);
452 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
453 MDP_OUTP(MDP_BASE + 0x502f4, 0x0);
454 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
455 MDP_OUTP(MDP_BASE + 0x502f8, 0x0);
456 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
457 MDP_OUTP(MDP_BASE + 0x502fc, 0x0);
458}
459
460static void mdp_load_pr_downscale_table_y_point4TOpoint6(void)
461{
462 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
463 MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
464 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
465 MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000);
466 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
467 MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000);
468 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
469 MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000);
470 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
471 MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000);
472 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
473 MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000);
474 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
475 MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000);
476 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
477 MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000);
478 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
479 MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000);
480 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
481 MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000);
482 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
483 MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000);
484 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
485 MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000);
486 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
487 MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000);
488 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
489 MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000);
490 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
491 MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000);
492 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
493 MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000);
494 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
495 MDP_OUTP(MDP_BASE + 0x50340, 0x0);
496 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
497 MDP_OUTP(MDP_BASE + 0x50344, 0x0);
498 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
499 MDP_OUTP(MDP_BASE + 0x50348, 0x0);
500 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
501 MDP_OUTP(MDP_BASE + 0x5034c, 0x0);
502 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
503 MDP_OUTP(MDP_BASE + 0x50350, 0x0);
504 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
505 MDP_OUTP(MDP_BASE + 0x50354, 0x0);
506 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
507 MDP_OUTP(MDP_BASE + 0x50358, 0x0);
508 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
509 MDP_OUTP(MDP_BASE + 0x5035c, 0x0);
510 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
511 MDP_OUTP(MDP_BASE + 0x50360, 0x0);
512 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
513 MDP_OUTP(MDP_BASE + 0x50364, 0x0);
514 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
515 MDP_OUTP(MDP_BASE + 0x50368, 0x0);
516 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
517 MDP_OUTP(MDP_BASE + 0x5036c, 0x0);
518 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
519 MDP_OUTP(MDP_BASE + 0x50370, 0x0);
520 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
521 MDP_OUTP(MDP_BASE + 0x50374, 0x0);
522 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
523 MDP_OUTP(MDP_BASE + 0x50378, 0x0);
524 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
525 MDP_OUTP(MDP_BASE + 0x5037c, 0x0);
526}
527
528static void mdp_load_pr_downscale_table_x_point6TOpoint8(void)
529{
530 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
531 MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
532 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
533 MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000);
534 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
535 MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000);
536 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
537 MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000);
538 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
539 MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000);
540 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
541 MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000);
542 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
543 MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000);
544 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
545 MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000);
546 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
547 MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000);
548 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
549 MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000);
550 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
551 MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000);
552 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
553 MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000);
554 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
555 MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000);
556 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
557 MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000);
558 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
559 MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000);
560 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
561 MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000);
562 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
563 MDP_OUTP(MDP_BASE + 0x502c0, 0x0);
564 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
565 MDP_OUTP(MDP_BASE + 0x502c4, 0x0);
566 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
567 MDP_OUTP(MDP_BASE + 0x502c8, 0x0);
568 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
569 MDP_OUTP(MDP_BASE + 0x502cc, 0x0);
570 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
571 MDP_OUTP(MDP_BASE + 0x502d0, 0x0);
572 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
573 MDP_OUTP(MDP_BASE + 0x502d4, 0x0);
574 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
575 MDP_OUTP(MDP_BASE + 0x502d8, 0x0);
576 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
577 MDP_OUTP(MDP_BASE + 0x502dc, 0x0);
578 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
579 MDP_OUTP(MDP_BASE + 0x502e0, 0x0);
580 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
581 MDP_OUTP(MDP_BASE + 0x502e4, 0x0);
582 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
583 MDP_OUTP(MDP_BASE + 0x502e8, 0x0);
584 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
585 MDP_OUTP(MDP_BASE + 0x502ec, 0x0);
586 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
587 MDP_OUTP(MDP_BASE + 0x502f0, 0x0);
588 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
589 MDP_OUTP(MDP_BASE + 0x502f4, 0x0);
590 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
591 MDP_OUTP(MDP_BASE + 0x502f8, 0x0);
592 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
593 MDP_OUTP(MDP_BASE + 0x502fc, 0x0);
594}
595
596static void mdp_load_pr_downscale_table_y_point6TOpoint8(void)
597{
598 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
599 MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
600 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
601 MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000);
602 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
603 MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000);
604 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
605 MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000);
606 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
607 MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000);
608 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
609 MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000);
610 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
611 MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000);
612 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
613 MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000);
614 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
615 MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000);
616 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
617 MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000);
618 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
619 MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000);
620 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
621 MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000);
622 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
623 MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000);
624 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
625 MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000);
626 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
627 MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000);
628 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
629 MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000);
630 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
631 MDP_OUTP(MDP_BASE + 0x50340, 0x0);
632 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
633 MDP_OUTP(MDP_BASE + 0x50344, 0x0);
634 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
635 MDP_OUTP(MDP_BASE + 0x50348, 0x0);
636 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
637 MDP_OUTP(MDP_BASE + 0x5034c, 0x0);
638 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
639 MDP_OUTP(MDP_BASE + 0x50350, 0x0);
640 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
641 MDP_OUTP(MDP_BASE + 0x50354, 0x0);
642 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
643 MDP_OUTP(MDP_BASE + 0x50358, 0x0);
644 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
645 MDP_OUTP(MDP_BASE + 0x5035c, 0x0);
646 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
647 MDP_OUTP(MDP_BASE + 0x50360, 0x0);
648 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
649 MDP_OUTP(MDP_BASE + 0x50364, 0x0);
650 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
651 MDP_OUTP(MDP_BASE + 0x50368, 0x0);
652 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
653 MDP_OUTP(MDP_BASE + 0x5036c, 0x0);
654 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
655 MDP_OUTP(MDP_BASE + 0x50370, 0x0);
656 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
657 MDP_OUTP(MDP_BASE + 0x50374, 0x0);
658 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
659 MDP_OUTP(MDP_BASE + 0x50378, 0x0);
660 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
661 MDP_OUTP(MDP_BASE + 0x5037c, 0x0);
662}
663
664static void mdp_load_pr_downscale_table_x_point8TO1(void)
665{
666 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
667 MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
668 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
669 MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000);
670 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
671 MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000);
672 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
673 MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000);
674 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
675 MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000);
676 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
677 MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000);
678 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
679 MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000);
680 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
681 MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000);
682 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
683 MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000);
684 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
685 MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000);
686 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
687 MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000);
688 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
689 MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000);
690 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
691 MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000);
692 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
693 MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000);
694 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
695 MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000);
696 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
697 MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000);
698 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
699 MDP_OUTP(MDP_BASE + 0x502c0, 0x0);
700 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
701 MDP_OUTP(MDP_BASE + 0x502c4, 0x0);
702 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
703 MDP_OUTP(MDP_BASE + 0x502c8, 0x0);
704 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
705 MDP_OUTP(MDP_BASE + 0x502cc, 0x0);
706 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
707 MDP_OUTP(MDP_BASE + 0x502d0, 0x0);
708 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
709 MDP_OUTP(MDP_BASE + 0x502d4, 0x0);
710 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
711 MDP_OUTP(MDP_BASE + 0x502d8, 0x0);
712 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
713 MDP_OUTP(MDP_BASE + 0x502dc, 0x0);
714 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
715 MDP_OUTP(MDP_BASE + 0x502e0, 0x0);
716 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
717 MDP_OUTP(MDP_BASE + 0x502e4, 0x0);
718 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
719 MDP_OUTP(MDP_BASE + 0x502e8, 0x0);
720 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
721 MDP_OUTP(MDP_BASE + 0x502ec, 0x0);
722 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
723 MDP_OUTP(MDP_BASE + 0x502f0, 0x0);
724 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
725 MDP_OUTP(MDP_BASE + 0x502f4, 0x0);
726 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
727 MDP_OUTP(MDP_BASE + 0x502f8, 0x0);
728 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
729 MDP_OUTP(MDP_BASE + 0x502fc, 0x0);
730}
731
732static void mdp_load_pr_downscale_table_y_point8TO1(void)
733{
734 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
735 MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
736 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
737 MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000);
738 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
739 MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000);
740 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
741 MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000);
742 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
743 MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000);
744 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
745 MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000);
746 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
747 MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000);
748 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
749 MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000);
750 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
751 MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000);
752 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
753 MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000);
754 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
755 MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000);
756 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
757 MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000);
758 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
759 MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000);
760 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
761 MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000);
762 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
763 MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000);
764 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
765 MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000);
766 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
767 MDP_OUTP(MDP_BASE + 0x50340, 0x0);
768 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
769 MDP_OUTP(MDP_BASE + 0x50344, 0x0);
770 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
771 MDP_OUTP(MDP_BASE + 0x50348, 0x0);
772 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
773 MDP_OUTP(MDP_BASE + 0x5034c, 0x0);
774 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
775 MDP_OUTP(MDP_BASE + 0x50350, 0x0);
776 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
777 MDP_OUTP(MDP_BASE + 0x50354, 0x0);
778 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
779 MDP_OUTP(MDP_BASE + 0x50358, 0x0);
780 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
781 MDP_OUTP(MDP_BASE + 0x5035c, 0x0);
782 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
783 MDP_OUTP(MDP_BASE + 0x50360, 0x0);
784 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
785 MDP_OUTP(MDP_BASE + 0x50364, 0x0);
786 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
787 MDP_OUTP(MDP_BASE + 0x50368, 0x0);
788 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
789 MDP_OUTP(MDP_BASE + 0x5036c, 0x0);
790 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
791 MDP_OUTP(MDP_BASE + 0x50370, 0x0);
792 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
793 MDP_OUTP(MDP_BASE + 0x50374, 0x0);
794 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
795 MDP_OUTP(MDP_BASE + 0x50378, 0x0);
796 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
797 MDP_OUTP(MDP_BASE + 0x5037c, 0x0);
798}
799
800static void mdp_load_bc_upscale_table(void)
801{
802 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
803 MDP_OUTP(MDP_BASE + 0x50200, 0x7fc00000);
804 MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d);
805 MDP_OUTP(MDP_BASE + 0x50204, 0x7ec003f9);
806 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c);
807 MDP_OUTP(MDP_BASE + 0x50208, 0x7d4003f3);
808 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b);
809 MDP_OUTP(MDP_BASE + 0x5020c, 0x7b8003ed);
810 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c);
811 MDP_OUTP(MDP_BASE + 0x50210, 0x794003e8);
812 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d);
813 MDP_OUTP(MDP_BASE + 0x50214, 0x76c003e4);
814 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f);
815 MDP_OUTP(MDP_BASE + 0x50218, 0x73c003e0);
816 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071);
817 MDP_OUTP(MDP_BASE + 0x5021c, 0x708003de);
818 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085);
819 MDP_OUTP(MDP_BASE + 0x50220, 0x6d0003db);
820 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098);
821 MDP_OUTP(MDP_BASE + 0x50224, 0x698003d9);
822 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac);
823 MDP_OUTP(MDP_BASE + 0x50228, 0x654003d8);
824 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1);
825 MDP_OUTP(MDP_BASE + 0x5022c, 0x610003d7);
826 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5);
827 MDP_OUTP(MDP_BASE + 0x50230, 0x5c8003d7);
828 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9);
829 MDP_OUTP(MDP_BASE + 0x50234, 0x580003d7);
830 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd);
831 MDP_OUTP(MDP_BASE + 0x50238, 0x534003d8);
832 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112);
833 MDP_OUTP(MDP_BASE + 0x5023c, 0x4e8003d8);
834 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126);
835 MDP_OUTP(MDP_BASE + 0x50240, 0x494003da);
836 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a);
837 MDP_OUTP(MDP_BASE + 0x50244, 0x448003db);
838 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d);
839 MDP_OUTP(MDP_BASE + 0x50248, 0x3f4003dd);
840 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160);
841 MDP_OUTP(MDP_BASE + 0x5024c, 0x3a4003df);
842 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172);
843 MDP_OUTP(MDP_BASE + 0x50250, 0x354003e1);
844 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184);
845 MDP_OUTP(MDP_BASE + 0x50254, 0x304003e3);
846 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195);
847 MDP_OUTP(MDP_BASE + 0x50258, 0x2b0003e6);
848 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6);
849 MDP_OUTP(MDP_BASE + 0x5025c, 0x260003e8);
850 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4);
851 MDP_OUTP(MDP_BASE + 0x50260, 0x214003eb);
852 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2);
853 MDP_OUTP(MDP_BASE + 0x50264, 0x1c4003ee);
854 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf);
855 MDP_OUTP(MDP_BASE + 0x50268, 0x17c003f1);
856 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db);
857 MDP_OUTP(MDP_BASE + 0x5026c, 0x134003f3);
858 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5);
859 MDP_OUTP(MDP_BASE + 0x50270, 0xf0003f6);
860 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee);
861 MDP_OUTP(MDP_BASE + 0x50274, 0xac003f9);
862 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5);
863 MDP_OUTP(MDP_BASE + 0x50278, 0x70003fb);
864 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb);
865 MDP_OUTP(MDP_BASE + 0x5027c, 0x34003fe);
866}
867
868static void mdp_load_bc_downscale_table_x_point2TOpoint4(void)
869{
870 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac00084);
871 MDP_OUTP(MDP_BASE + 0x50280, 0x23400083);
872 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b000084);
873 MDP_OUTP(MDP_BASE + 0x50284, 0x23000083);
874 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400084);
875 MDP_OUTP(MDP_BASE + 0x50288, 0x23000082);
876 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400085);
877 MDP_OUTP(MDP_BASE + 0x5028c, 0x23000081);
878 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b800085);
879 MDP_OUTP(MDP_BASE + 0x50290, 0x23000080);
880 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc00086);
881 MDP_OUTP(MDP_BASE + 0x50294, 0x22c0007f);
882 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c000086);
883 MDP_OUTP(MDP_BASE + 0x50298, 0x2280007f);
884 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c400086);
885 MDP_OUTP(MDP_BASE + 0x5029c, 0x2280007e);
886 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c800086);
887 MDP_OUTP(MDP_BASE + 0x502a0, 0x2280007d);
888 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00086);
889 MDP_OUTP(MDP_BASE + 0x502a4, 0x2240007d);
890 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00087);
891 MDP_OUTP(MDP_BASE + 0x502a8, 0x2240007c);
892 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d000087);
893 MDP_OUTP(MDP_BASE + 0x502ac, 0x2240007b);
894 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400087);
895 MDP_OUTP(MDP_BASE + 0x502b0, 0x2200007b);
896 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400088);
897 MDP_OUTP(MDP_BASE + 0x502b4, 0x22400079);
898 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d800088);
899 MDP_OUTP(MDP_BASE + 0x502b8, 0x22400078);
900 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00088);
901 MDP_OUTP(MDP_BASE + 0x502bc, 0x22400077);
902 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00089);
903 MDP_OUTP(MDP_BASE + 0x502c0, 0x22000077);
904 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e000089);
905 MDP_OUTP(MDP_BASE + 0x502c4, 0x22000076);
906 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e400089);
907 MDP_OUTP(MDP_BASE + 0x502c8, 0x22000075);
908 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00088);
909 MDP_OUTP(MDP_BASE + 0x502cc, 0x21c00075);
910 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00089);
911 MDP_OUTP(MDP_BASE + 0x502d0, 0x21c00074);
912 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f000089);
913 MDP_OUTP(MDP_BASE + 0x502d4, 0x21c00073);
914 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f400089);
915 MDP_OUTP(MDP_BASE + 0x502d8, 0x21800073);
916 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f40008a);
917 MDP_OUTP(MDP_BASE + 0x502dc, 0x21800072);
918 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f80008a);
919 MDP_OUTP(MDP_BASE + 0x502e0, 0x21800071);
920 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008a);
921 MDP_OUTP(MDP_BASE + 0x502e4, 0x21800070);
922 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008b);
923 MDP_OUTP(MDP_BASE + 0x502e8, 0x2180006f);
924 MDP_OUTP(MDP_BASE + 0x5fffc, 0x2000008c);
925 MDP_OUTP(MDP_BASE + 0x502ec, 0x2140006e);
926 MDP_OUTP(MDP_BASE + 0x5fffc, 0x2040008c);
927 MDP_OUTP(MDP_BASE + 0x502f0, 0x2140006d);
928 MDP_OUTP(MDP_BASE + 0x5fffc, 0x2080008c);
929 MDP_OUTP(MDP_BASE + 0x502f4, 0x2100006d);
930 MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008c);
931 MDP_OUTP(MDP_BASE + 0x502f8, 0x2100006c);
932 MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008d);
933 MDP_OUTP(MDP_BASE + 0x502fc, 0x2100006b);
934}
935
936static void mdp_load_bc_downscale_table_y_point2TOpoint4(void)
937{
938 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac00084);
939 MDP_OUTP(MDP_BASE + 0x50300, 0x23400083);
940 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b000084);
941 MDP_OUTP(MDP_BASE + 0x50304, 0x23000083);
942 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400084);
943 MDP_OUTP(MDP_BASE + 0x50308, 0x23000082);
944 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400085);
945 MDP_OUTP(MDP_BASE + 0x5030c, 0x23000081);
946 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b800085);
947 MDP_OUTP(MDP_BASE + 0x50310, 0x23000080);
948 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc00086);
949 MDP_OUTP(MDP_BASE + 0x50314, 0x22c0007f);
950 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c000086);
951 MDP_OUTP(MDP_BASE + 0x50318, 0x2280007f);
952 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c400086);
953 MDP_OUTP(MDP_BASE + 0x5031c, 0x2280007e);
954 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c800086);
955 MDP_OUTP(MDP_BASE + 0x50320, 0x2280007d);
956 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00086);
957 MDP_OUTP(MDP_BASE + 0x50324, 0x2240007d);
958 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00087);
959 MDP_OUTP(MDP_BASE + 0x50328, 0x2240007c);
960 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d000087);
961 MDP_OUTP(MDP_BASE + 0x5032c, 0x2240007b);
962 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400087);
963 MDP_OUTP(MDP_BASE + 0x50330, 0x2200007b);
964 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400088);
965 MDP_OUTP(MDP_BASE + 0x50334, 0x22400079);
966 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d800088);
967 MDP_OUTP(MDP_BASE + 0x50338, 0x22400078);
968 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00088);
969 MDP_OUTP(MDP_BASE + 0x5033c, 0x22400077);
970 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00089);
971 MDP_OUTP(MDP_BASE + 0x50340, 0x22000077);
972 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e000089);
973 MDP_OUTP(MDP_BASE + 0x50344, 0x22000076);
974 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e400089);
975 MDP_OUTP(MDP_BASE + 0x50348, 0x22000075);
976 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00088);
977 MDP_OUTP(MDP_BASE + 0x5034c, 0x21c00075);
978 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00089);
979 MDP_OUTP(MDP_BASE + 0x50350, 0x21c00074);
980 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f000089);
981 MDP_OUTP(MDP_BASE + 0x50354, 0x21c00073);
982 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f400089);
983 MDP_OUTP(MDP_BASE + 0x50358, 0x21800073);
984 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f40008a);
985 MDP_OUTP(MDP_BASE + 0x5035c, 0x21800072);
986 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f80008a);
987 MDP_OUTP(MDP_BASE + 0x50360, 0x21800071);
988 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008a);
989 MDP_OUTP(MDP_BASE + 0x50364, 0x21800070);
990 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008b);
991 MDP_OUTP(MDP_BASE + 0x50368, 0x2180006f);
992 MDP_OUTP(MDP_BASE + 0x5fffc, 0x2000008c);
993 MDP_OUTP(MDP_BASE + 0x5036c, 0x2140006e);
994 MDP_OUTP(MDP_BASE + 0x5fffc, 0x2040008c);
995 MDP_OUTP(MDP_BASE + 0x50370, 0x2140006d);
996 MDP_OUTP(MDP_BASE + 0x5fffc, 0x2080008c);
997 MDP_OUTP(MDP_BASE + 0x50374, 0x2100006d);
998 MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008c);
999 MDP_OUTP(MDP_BASE + 0x50378, 0x2100006c);
1000 MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008d);
1001 MDP_OUTP(MDP_BASE + 0x5037c, 0x2100006b);
1002}
1003
1004static void mdp_load_bc_downscale_table_x_point4TOpoint6(void)
1005{
1006 MDP_OUTP(MDP_BASE + 0x5fffc, 0x740008c);
1007 MDP_OUTP(MDP_BASE + 0x50280, 0x33800088);
1008 MDP_OUTP(MDP_BASE + 0x5fffc, 0x800008e);
1009 MDP_OUTP(MDP_BASE + 0x50284, 0x33400084);
1010 MDP_OUTP(MDP_BASE + 0x5fffc, 0x8400092);
1011 MDP_OUTP(MDP_BASE + 0x50288, 0x33000080);
1012 MDP_OUTP(MDP_BASE + 0x5fffc, 0x9000094);
1013 MDP_OUTP(MDP_BASE + 0x5028c, 0x3300007b);
1014 MDP_OUTP(MDP_BASE + 0x5fffc, 0x9c00098);
1015 MDP_OUTP(MDP_BASE + 0x50290, 0x32400077);
1016 MDP_OUTP(MDP_BASE + 0x5fffc, 0xa40009b);
1017 MDP_OUTP(MDP_BASE + 0x50294, 0x32000073);
1018 MDP_OUTP(MDP_BASE + 0x5fffc, 0xb00009d);
1019 MDP_OUTP(MDP_BASE + 0x50298, 0x31c0006f);
1020 MDP_OUTP(MDP_BASE + 0x5fffc, 0xbc000a0);
1021 MDP_OUTP(MDP_BASE + 0x5029c, 0x3140006b);
1022 MDP_OUTP(MDP_BASE + 0x5fffc, 0xc8000a2);
1023 MDP_OUTP(MDP_BASE + 0x502a0, 0x31000067);
1024 MDP_OUTP(MDP_BASE + 0x5fffc, 0xd8000a5);
1025 MDP_OUTP(MDP_BASE + 0x502a4, 0x30800062);
1026 MDP_OUTP(MDP_BASE + 0x5fffc, 0xe4000a8);
1027 MDP_OUTP(MDP_BASE + 0x502a8, 0x2fc0005f);
1028 MDP_OUTP(MDP_BASE + 0x5fffc, 0xec000aa);
1029 MDP_OUTP(MDP_BASE + 0x502ac, 0x2fc0005b);
1030 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8000ad);
1031 MDP_OUTP(MDP_BASE + 0x502b0, 0x2f400057);
1032 MDP_OUTP(MDP_BASE + 0x5fffc, 0x108000b0);
1033 MDP_OUTP(MDP_BASE + 0x502b4, 0x2e400054);
1034 MDP_OUTP(MDP_BASE + 0x5fffc, 0x114000b2);
1035 MDP_OUTP(MDP_BASE + 0x502b8, 0x2e000050);
1036 MDP_OUTP(MDP_BASE + 0x5fffc, 0x124000b4);
1037 MDP_OUTP(MDP_BASE + 0x502bc, 0x2d80004c);
1038 MDP_OUTP(MDP_BASE + 0x5fffc, 0x130000b6);
1039 MDP_OUTP(MDP_BASE + 0x502c0, 0x2d000049);
1040 MDP_OUTP(MDP_BASE + 0x5fffc, 0x140000b8);
1041 MDP_OUTP(MDP_BASE + 0x502c4, 0x2c800045);
1042 MDP_OUTP(MDP_BASE + 0x5fffc, 0x150000b9);
1043 MDP_OUTP(MDP_BASE + 0x502c8, 0x2c000042);
1044 MDP_OUTP(MDP_BASE + 0x5fffc, 0x15c000bd);
1045 MDP_OUTP(MDP_BASE + 0x502cc, 0x2b40003e);
1046 MDP_OUTP(MDP_BASE + 0x5fffc, 0x16c000bf);
1047 MDP_OUTP(MDP_BASE + 0x502d0, 0x2a80003b);
1048 MDP_OUTP(MDP_BASE + 0x5fffc, 0x17c000bf);
1049 MDP_OUTP(MDP_BASE + 0x502d4, 0x2a000039);
1050 MDP_OUTP(MDP_BASE + 0x5fffc, 0x188000c2);
1051 MDP_OUTP(MDP_BASE + 0x502d8, 0x29400036);
1052 MDP_OUTP(MDP_BASE + 0x5fffc, 0x19c000c4);
1053 MDP_OUTP(MDP_BASE + 0x502dc, 0x28800032);
1054 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac000c5);
1055 MDP_OUTP(MDP_BASE + 0x502e0, 0x2800002f);
1056 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc000c7);
1057 MDP_OUTP(MDP_BASE + 0x502e4, 0x2740002c);
1058 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc000c8);
1059 MDP_OUTP(MDP_BASE + 0x502e8, 0x26c00029);
1060 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc000c9);
1061 MDP_OUTP(MDP_BASE + 0x502ec, 0x26000027);
1062 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec000cc);
1063 MDP_OUTP(MDP_BASE + 0x502f0, 0x25000024);
1064 MDP_OUTP(MDP_BASE + 0x5fffc, 0x200000cc);
1065 MDP_OUTP(MDP_BASE + 0x502f4, 0x24800021);
1066 MDP_OUTP(MDP_BASE + 0x5fffc, 0x210000cd);
1067 MDP_OUTP(MDP_BASE + 0x502f8, 0x23800020);
1068 MDP_OUTP(MDP_BASE + 0x5fffc, 0x220000ce);
1069 MDP_OUTP(MDP_BASE + 0x502fc, 0x2300001d);
1070}
1071
1072static void mdp_load_bc_downscale_table_y_point4TOpoint6(void)
1073{
1074 MDP_OUTP(MDP_BASE + 0x5fffc, 0x740008c);
1075 MDP_OUTP(MDP_BASE + 0x50300, 0x33800088);
1076 MDP_OUTP(MDP_BASE + 0x5fffc, 0x800008e);
1077 MDP_OUTP(MDP_BASE + 0x50304, 0x33400084);
1078 MDP_OUTP(MDP_BASE + 0x5fffc, 0x8400092);
1079 MDP_OUTP(MDP_BASE + 0x50308, 0x33000080);
1080 MDP_OUTP(MDP_BASE + 0x5fffc, 0x9000094);
1081 MDP_OUTP(MDP_BASE + 0x5030c, 0x3300007b);
1082 MDP_OUTP(MDP_BASE + 0x5fffc, 0x9c00098);
1083 MDP_OUTP(MDP_BASE + 0x50310, 0x32400077);
1084 MDP_OUTP(MDP_BASE + 0x5fffc, 0xa40009b);
1085 MDP_OUTP(MDP_BASE + 0x50314, 0x32000073);
1086 MDP_OUTP(MDP_BASE + 0x5fffc, 0xb00009d);
1087 MDP_OUTP(MDP_BASE + 0x50318, 0x31c0006f);
1088 MDP_OUTP(MDP_BASE + 0x5fffc, 0xbc000a0);
1089 MDP_OUTP(MDP_BASE + 0x5031c, 0x3140006b);
1090 MDP_OUTP(MDP_BASE + 0x5fffc, 0xc8000a2);
1091 MDP_OUTP(MDP_BASE + 0x50320, 0x31000067);
1092 MDP_OUTP(MDP_BASE + 0x5fffc, 0xd8000a5);
1093 MDP_OUTP(MDP_BASE + 0x50324, 0x30800062);
1094 MDP_OUTP(MDP_BASE + 0x5fffc, 0xe4000a8);
1095 MDP_OUTP(MDP_BASE + 0x50328, 0x2fc0005f);
1096 MDP_OUTP(MDP_BASE + 0x5fffc, 0xec000aa);
1097 MDP_OUTP(MDP_BASE + 0x5032c, 0x2fc0005b);
1098 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8000ad);
1099 MDP_OUTP(MDP_BASE + 0x50330, 0x2f400057);
1100 MDP_OUTP(MDP_BASE + 0x5fffc, 0x108000b0);
1101 MDP_OUTP(MDP_BASE + 0x50334, 0x2e400054);
1102 MDP_OUTP(MDP_BASE + 0x5fffc, 0x114000b2);
1103 MDP_OUTP(MDP_BASE + 0x50338, 0x2e000050);
1104 MDP_OUTP(MDP_BASE + 0x5fffc, 0x124000b4);
1105 MDP_OUTP(MDP_BASE + 0x5033c, 0x2d80004c);
1106 MDP_OUTP(MDP_BASE + 0x5fffc, 0x130000b6);
1107 MDP_OUTP(MDP_BASE + 0x50340, 0x2d000049);
1108 MDP_OUTP(MDP_BASE + 0x5fffc, 0x140000b8);
1109 MDP_OUTP(MDP_BASE + 0x50344, 0x2c800045);
1110 MDP_OUTP(MDP_BASE + 0x5fffc, 0x150000b9);
1111 MDP_OUTP(MDP_BASE + 0x50348, 0x2c000042);
1112 MDP_OUTP(MDP_BASE + 0x5fffc, 0x15c000bd);
1113 MDP_OUTP(MDP_BASE + 0x5034c, 0x2b40003e);
1114 MDP_OUTP(MDP_BASE + 0x5fffc, 0x16c000bf);
1115 MDP_OUTP(MDP_BASE + 0x50350, 0x2a80003b);
1116 MDP_OUTP(MDP_BASE + 0x5fffc, 0x17c000bf);
1117 MDP_OUTP(MDP_BASE + 0x50354, 0x2a000039);
1118 MDP_OUTP(MDP_BASE + 0x5fffc, 0x188000c2);
1119 MDP_OUTP(MDP_BASE + 0x50358, 0x29400036);
1120 MDP_OUTP(MDP_BASE + 0x5fffc, 0x19c000c4);
1121 MDP_OUTP(MDP_BASE + 0x5035c, 0x28800032);
1122 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac000c5);
1123 MDP_OUTP(MDP_BASE + 0x50360, 0x2800002f);
1124 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc000c7);
1125 MDP_OUTP(MDP_BASE + 0x50364, 0x2740002c);
1126 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc000c8);
1127 MDP_OUTP(MDP_BASE + 0x50368, 0x26c00029);
1128 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc000c9);
1129 MDP_OUTP(MDP_BASE + 0x5036c, 0x26000027);
1130 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec000cc);
1131 MDP_OUTP(MDP_BASE + 0x50370, 0x25000024);
1132 MDP_OUTP(MDP_BASE + 0x5fffc, 0x200000cc);
1133 MDP_OUTP(MDP_BASE + 0x50374, 0x24800021);
1134 MDP_OUTP(MDP_BASE + 0x5fffc, 0x210000cd);
1135 MDP_OUTP(MDP_BASE + 0x50378, 0x23800020);
1136 MDP_OUTP(MDP_BASE + 0x5fffc, 0x220000ce);
1137 MDP_OUTP(MDP_BASE + 0x5037c, 0x2300001d);
1138}
1139
1140static void mdp_load_bc_downscale_table_x_point6TOpoint8(void)
1141{
1142 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000070);
1143 MDP_OUTP(MDP_BASE + 0x50280, 0x4bc00068);
1144 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000078);
1145 MDP_OUTP(MDP_BASE + 0x50284, 0x4bc00060);
1146 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000080);
1147 MDP_OUTP(MDP_BASE + 0x50288, 0x4b800059);
1148 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000089);
1149 MDP_OUTP(MDP_BASE + 0x5028c, 0x4b000052);
1150 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe400091);
1151 MDP_OUTP(MDP_BASE + 0x50290, 0x4a80004b);
1152 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40009a);
1153 MDP_OUTP(MDP_BASE + 0x50294, 0x4a000044);
1154 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe8000a3);
1155 MDP_OUTP(MDP_BASE + 0x50298, 0x4940003d);
1156 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec000ac);
1157 MDP_OUTP(MDP_BASE + 0x5029c, 0x48400037);
1158 MDP_OUTP(MDP_BASE + 0x5fffc, 0xff0000b4);
1159 MDP_OUTP(MDP_BASE + 0x502a0, 0x47800031);
1160 MDP_OUTP(MDP_BASE + 0x5fffc, 0xff8000bd);
1161 MDP_OUTP(MDP_BASE + 0x502a4, 0x4640002b);
1162 MDP_OUTP(MDP_BASE + 0x5fffc, 0xc5);
1163 MDP_OUTP(MDP_BASE + 0x502a8, 0x45000026);
1164 MDP_OUTP(MDP_BASE + 0x5fffc, 0x8000ce);
1165 MDP_OUTP(MDP_BASE + 0x502ac, 0x43800021);
1166 MDP_OUTP(MDP_BASE + 0x5fffc, 0x10000d6);
1167 MDP_OUTP(MDP_BASE + 0x502b0, 0x4240001c);
1168 MDP_OUTP(MDP_BASE + 0x5fffc, 0x18000df);
1169 MDP_OUTP(MDP_BASE + 0x502b4, 0x40800018);
1170 MDP_OUTP(MDP_BASE + 0x5fffc, 0x24000e6);
1171 MDP_OUTP(MDP_BASE + 0x502b8, 0x3f000014);
1172 MDP_OUTP(MDP_BASE + 0x5fffc, 0x30000ee);
1173 MDP_OUTP(MDP_BASE + 0x502bc, 0x3d400010);
1174 MDP_OUTP(MDP_BASE + 0x5fffc, 0x40000f5);
1175 MDP_OUTP(MDP_BASE + 0x502c0, 0x3b80000c);
1176 MDP_OUTP(MDP_BASE + 0x5fffc, 0x50000fc);
1177 MDP_OUTP(MDP_BASE + 0x502c4, 0x39800009);
1178 MDP_OUTP(MDP_BASE + 0x5fffc, 0x6000102);
1179 MDP_OUTP(MDP_BASE + 0x502c8, 0x37c00006);
1180 MDP_OUTP(MDP_BASE + 0x5fffc, 0x7000109);
1181 MDP_OUTP(MDP_BASE + 0x502cc, 0x35800004);
1182 MDP_OUTP(MDP_BASE + 0x5fffc, 0x840010e);
1183 MDP_OUTP(MDP_BASE + 0x502d0, 0x33800002);
1184 MDP_OUTP(MDP_BASE + 0x5fffc, 0x9800114);
1185 MDP_OUTP(MDP_BASE + 0x502d4, 0x31400000);
1186 MDP_OUTP(MDP_BASE + 0x5fffc, 0xac00119);
1187 MDP_OUTP(MDP_BASE + 0x502d8, 0x2f4003fe);
1188 MDP_OUTP(MDP_BASE + 0x5fffc, 0xc40011e);
1189 MDP_OUTP(MDP_BASE + 0x502dc, 0x2d0003fc);
1190 MDP_OUTP(MDP_BASE + 0x5fffc, 0xdc00121);
1191 MDP_OUTP(MDP_BASE + 0x502e0, 0x2b0003fb);
1192 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf400125);
1193 MDP_OUTP(MDP_BASE + 0x502e4, 0x28c003fa);
1194 MDP_OUTP(MDP_BASE + 0x5fffc, 0x11000128);
1195 MDP_OUTP(MDP_BASE + 0x502e8, 0x268003f9);
1196 MDP_OUTP(MDP_BASE + 0x5fffc, 0x12c0012a);
1197 MDP_OUTP(MDP_BASE + 0x502ec, 0x244003f9);
1198 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1480012c);
1199 MDP_OUTP(MDP_BASE + 0x502f0, 0x224003f8);
1200 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1640012e);
1201 MDP_OUTP(MDP_BASE + 0x502f4, 0x200003f8);
1202 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1800012f);
1203 MDP_OUTP(MDP_BASE + 0x502f8, 0x1e0003f8);
1204 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1a00012f);
1205 MDP_OUTP(MDP_BASE + 0x502fc, 0x1c0003f8);
1206}
1207
1208static void mdp_load_bc_downscale_table_y_point6TOpoint8(void)
1209{
1210 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000070);
1211 MDP_OUTP(MDP_BASE + 0x50300, 0x4bc00068);
1212 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000078);
1213 MDP_OUTP(MDP_BASE + 0x50304, 0x4bc00060);
1214 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000080);
1215 MDP_OUTP(MDP_BASE + 0x50308, 0x4b800059);
1216 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000089);
1217 MDP_OUTP(MDP_BASE + 0x5030c, 0x4b000052);
1218 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe400091);
1219 MDP_OUTP(MDP_BASE + 0x50310, 0x4a80004b);
1220 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40009a);
1221 MDP_OUTP(MDP_BASE + 0x50314, 0x4a000044);
1222 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe8000a3);
1223 MDP_OUTP(MDP_BASE + 0x50318, 0x4940003d);
1224 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec000ac);
1225 MDP_OUTP(MDP_BASE + 0x5031c, 0x48400037);
1226 MDP_OUTP(MDP_BASE + 0x5fffc, 0xff0000b4);
1227 MDP_OUTP(MDP_BASE + 0x50320, 0x47800031);
1228 MDP_OUTP(MDP_BASE + 0x5fffc, 0xff8000bd);
1229 MDP_OUTP(MDP_BASE + 0x50324, 0x4640002b);
1230 MDP_OUTP(MDP_BASE + 0x5fffc, 0xc5);
1231 MDP_OUTP(MDP_BASE + 0x50328, 0x45000026);
1232 MDP_OUTP(MDP_BASE + 0x5fffc, 0x8000ce);
1233 MDP_OUTP(MDP_BASE + 0x5032c, 0x43800021);
1234 MDP_OUTP(MDP_BASE + 0x5fffc, 0x10000d6);
1235 MDP_OUTP(MDP_BASE + 0x50330, 0x4240001c);
1236 MDP_OUTP(MDP_BASE + 0x5fffc, 0x18000df);
1237 MDP_OUTP(MDP_BASE + 0x50334, 0x40800018);
1238 MDP_OUTP(MDP_BASE + 0x5fffc, 0x24000e6);
1239 MDP_OUTP(MDP_BASE + 0x50338, 0x3f000014);
1240 MDP_OUTP(MDP_BASE + 0x5fffc, 0x30000ee);
1241 MDP_OUTP(MDP_BASE + 0x5033c, 0x3d400010);
1242 MDP_OUTP(MDP_BASE + 0x5fffc, 0x40000f5);
1243 MDP_OUTP(MDP_BASE + 0x50340, 0x3b80000c);
1244 MDP_OUTP(MDP_BASE + 0x5fffc, 0x50000fc);
1245 MDP_OUTP(MDP_BASE + 0x50344, 0x39800009);
1246 MDP_OUTP(MDP_BASE + 0x5fffc, 0x6000102);
1247 MDP_OUTP(MDP_BASE + 0x50348, 0x37c00006);
1248 MDP_OUTP(MDP_BASE + 0x5fffc, 0x7000109);
1249 MDP_OUTP(MDP_BASE + 0x5034c, 0x35800004);
1250 MDP_OUTP(MDP_BASE + 0x5fffc, 0x840010e);
1251 MDP_OUTP(MDP_BASE + 0x50350, 0x33800002);
1252 MDP_OUTP(MDP_BASE + 0x5fffc, 0x9800114);
1253 MDP_OUTP(MDP_BASE + 0x50354, 0x31400000);
1254 MDP_OUTP(MDP_BASE + 0x5fffc, 0xac00119);
1255 MDP_OUTP(MDP_BASE + 0x50358, 0x2f4003fe);
1256 MDP_OUTP(MDP_BASE + 0x5fffc, 0xc40011e);
1257 MDP_OUTP(MDP_BASE + 0x5035c, 0x2d0003fc);
1258 MDP_OUTP(MDP_BASE + 0x5fffc, 0xdc00121);
1259 MDP_OUTP(MDP_BASE + 0x50360, 0x2b0003fb);
1260 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf400125);
1261 MDP_OUTP(MDP_BASE + 0x50364, 0x28c003fa);
1262 MDP_OUTP(MDP_BASE + 0x5fffc, 0x11000128);
1263 MDP_OUTP(MDP_BASE + 0x50368, 0x268003f9);
1264 MDP_OUTP(MDP_BASE + 0x5fffc, 0x12c0012a);
1265 MDP_OUTP(MDP_BASE + 0x5036c, 0x244003f9);
1266 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1480012c);
1267 MDP_OUTP(MDP_BASE + 0x50370, 0x224003f8);
1268 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1640012e);
1269 MDP_OUTP(MDP_BASE + 0x50374, 0x200003f8);
1270 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1800012f);
1271 MDP_OUTP(MDP_BASE + 0x50378, 0x1e0003f8);
1272 MDP_OUTP(MDP_BASE + 0x5fffc, 0x1a00012f);
1273 MDP_OUTP(MDP_BASE + 0x5037c, 0x1c0003f8);
1274}
1275
1276static void mdp_load_bc_downscale_table_x_point8TO1(void)
1277{
1278 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
1279 MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
1280 MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d);
1281 MDP_OUTP(MDP_BASE + 0x50284, 0x7ec003f9);
1282 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c);
1283 MDP_OUTP(MDP_BASE + 0x50288, 0x7d4003f3);
1284 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b);
1285 MDP_OUTP(MDP_BASE + 0x5028c, 0x7b8003ed);
1286 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c);
1287 MDP_OUTP(MDP_BASE + 0x50290, 0x794003e8);
1288 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d);
1289 MDP_OUTP(MDP_BASE + 0x50294, 0x76c003e4);
1290 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f);
1291 MDP_OUTP(MDP_BASE + 0x50298, 0x73c003e0);
1292 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071);
1293 MDP_OUTP(MDP_BASE + 0x5029c, 0x708003de);
1294 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085);
1295 MDP_OUTP(MDP_BASE + 0x502a0, 0x6d0003db);
1296 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098);
1297 MDP_OUTP(MDP_BASE + 0x502a4, 0x698003d9);
1298 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac);
1299 MDP_OUTP(MDP_BASE + 0x502a8, 0x654003d8);
1300 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1);
1301 MDP_OUTP(MDP_BASE + 0x502ac, 0x610003d7);
1302 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5);
1303 MDP_OUTP(MDP_BASE + 0x502b0, 0x5c8003d7);
1304 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9);
1305 MDP_OUTP(MDP_BASE + 0x502b4, 0x580003d7);
1306 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd);
1307 MDP_OUTP(MDP_BASE + 0x502b8, 0x534003d8);
1308 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112);
1309 MDP_OUTP(MDP_BASE + 0x502bc, 0x4e8003d8);
1310 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126);
1311 MDP_OUTP(MDP_BASE + 0x502c0, 0x494003da);
1312 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a);
1313 MDP_OUTP(MDP_BASE + 0x502c4, 0x448003db);
1314 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d);
1315 MDP_OUTP(MDP_BASE + 0x502c8, 0x3f4003dd);
1316 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160);
1317 MDP_OUTP(MDP_BASE + 0x502cc, 0x3a4003df);
1318 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172);
1319 MDP_OUTP(MDP_BASE + 0x502d0, 0x354003e1);
1320 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184);
1321 MDP_OUTP(MDP_BASE + 0x502d4, 0x304003e3);
1322 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195);
1323 MDP_OUTP(MDP_BASE + 0x502d8, 0x2b0003e6);
1324 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6);
1325 MDP_OUTP(MDP_BASE + 0x502dc, 0x260003e8);
1326 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4);
1327 MDP_OUTP(MDP_BASE + 0x502e0, 0x214003eb);
1328 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2);
1329 MDP_OUTP(MDP_BASE + 0x502e4, 0x1c4003ee);
1330 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf);
1331 MDP_OUTP(MDP_BASE + 0x502e8, 0x17c003f1);
1332 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db);
1333 MDP_OUTP(MDP_BASE + 0x502ec, 0x134003f3);
1334 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5);
1335 MDP_OUTP(MDP_BASE + 0x502f0, 0xf0003f6);
1336 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee);
1337 MDP_OUTP(MDP_BASE + 0x502f4, 0xac003f9);
1338 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5);
1339 MDP_OUTP(MDP_BASE + 0x502f8, 0x70003fb);
1340 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb);
1341 MDP_OUTP(MDP_BASE + 0x502fc, 0x34003fe);
1342}
1343
1344static void mdp_load_bc_downscale_table_y_point8TO1(void)
1345{
1346 MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
1347 MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
1348 MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d);
1349 MDP_OUTP(MDP_BASE + 0x50304, 0x7ec003f9);
1350 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c);
1351 MDP_OUTP(MDP_BASE + 0x50308, 0x7d4003f3);
1352 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b);
1353 MDP_OUTP(MDP_BASE + 0x5030c, 0x7b8003ed);
1354 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c);
1355 MDP_OUTP(MDP_BASE + 0x50310, 0x794003e8);
1356 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d);
1357 MDP_OUTP(MDP_BASE + 0x50314, 0x76c003e4);
1358 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f);
1359 MDP_OUTP(MDP_BASE + 0x50318, 0x73c003e0);
1360 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071);
1361 MDP_OUTP(MDP_BASE + 0x5031c, 0x708003de);
1362 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085);
1363 MDP_OUTP(MDP_BASE + 0x50320, 0x6d0003db);
1364 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098);
1365 MDP_OUTP(MDP_BASE + 0x50324, 0x698003d9);
1366 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac);
1367 MDP_OUTP(MDP_BASE + 0x50328, 0x654003d8);
1368 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1);
1369 MDP_OUTP(MDP_BASE + 0x5032c, 0x610003d7);
1370 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5);
1371 MDP_OUTP(MDP_BASE + 0x50330, 0x5c8003d7);
1372 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9);
1373 MDP_OUTP(MDP_BASE + 0x50334, 0x580003d7);
1374 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd);
1375 MDP_OUTP(MDP_BASE + 0x50338, 0x534003d8);
1376 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112);
1377 MDP_OUTP(MDP_BASE + 0x5033c, 0x4e8003d8);
1378 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126);
1379 MDP_OUTP(MDP_BASE + 0x50340, 0x494003da);
1380 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a);
1381 MDP_OUTP(MDP_BASE + 0x50344, 0x448003db);
1382 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d);
1383 MDP_OUTP(MDP_BASE + 0x50348, 0x3f4003dd);
1384 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160);
1385 MDP_OUTP(MDP_BASE + 0x5034c, 0x3a4003df);
1386 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172);
1387 MDP_OUTP(MDP_BASE + 0x50350, 0x354003e1);
1388 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184);
1389 MDP_OUTP(MDP_BASE + 0x50354, 0x304003e3);
1390 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195);
1391 MDP_OUTP(MDP_BASE + 0x50358, 0x2b0003e6);
1392 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6);
1393 MDP_OUTP(MDP_BASE + 0x5035c, 0x260003e8);
1394 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4);
1395 MDP_OUTP(MDP_BASE + 0x50360, 0x214003eb);
1396 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2);
1397 MDP_OUTP(MDP_BASE + 0x50364, 0x1c4003ee);
1398 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf);
1399 MDP_OUTP(MDP_BASE + 0x50368, 0x17c003f1);
1400 MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db);
1401 MDP_OUTP(MDP_BASE + 0x5036c, 0x134003f3);
1402 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5);
1403 MDP_OUTP(MDP_BASE + 0x50370, 0xf0003f6);
1404 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee);
1405 MDP_OUTP(MDP_BASE + 0x50374, 0xac003f9);
1406 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5);
1407 MDP_OUTP(MDP_BASE + 0x50378, 0x70003fb);
1408 MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb);
1409 MDP_OUTP(MDP_BASE + 0x5037c, 0x34003fe);
1410}
1411
1412static int mdp_get_edge_cond(MDPIBUF *iBuf, uint32 *dup, uint32 *dup2)
1413{
1414 uint32 reg;
1415 uint32 dst_roi_width; /* Dimensions of DST ROI. */
1416 uint32 dst_roi_height; /* Used to calculate scaling ratios. */
1417
1418 /*
1419 * positions of the luma pixel(relative to the image ) required for
1420 * scaling the ROI
1421 */
1422 int32 luma_interp_point_left = 0; /* left-most luma pixel needed */
1423 int32 luma_interp_point_right = 0; /* right-most luma pixel needed */
1424 int32 luma_interp_point_top = 0; /* top-most luma pixel needed */
1425 int32 luma_interp_point_bottom = 0; /* bottom-most luma pixel needed */
1426
1427 /*
1428 * positions of the chroma pixel(relative to the image ) required for
1429 * interpolating a chroma value at all required luma positions
1430 */
1431 /* left-most chroma pixel needed */
1432 int32 chroma_interp_point_left = 0;
1433 /* right-most chroma pixel needed */
1434 int32 chroma_interp_point_right = 0;
1435 /* top-most chroma pixel needed */
1436 int32 chroma_interp_point_top = 0;
1437 /* bottom-most chroma pixel needed */
1438 int32 chroma_interp_point_bottom = 0;
1439
1440 /*
1441 * a rectangular region within the chroma plane of the "image".
1442 * Chroma pixels falling inside of this rectangle belongs to the ROI
1443 */
1444 int32 chroma_bound_left = 0;
1445 int32 chroma_bound_right = 0;
1446 int32 chroma_bound_top = 0;
1447 int32 chroma_bound_bottom = 0;
1448
1449 /*
1450 * number of chroma pixels to replicate on the left, right,
1451 * top and bottom edge of the ROI.
1452 */
1453 int32 chroma_repeat_left = 0;
1454 int32 chroma_repeat_right = 0;
1455 int32 chroma_repeat_top = 0;
1456 int32 chroma_repeat_bottom = 0;
1457
1458 /*
1459 * number of luma pixels to replicate on the left, right,
1460 * top and bottom edge of the ROI.
1461 */
1462 int32 luma_repeat_left = 0;
1463 int32 luma_repeat_right = 0;
1464 int32 luma_repeat_top = 0;
1465 int32 luma_repeat_bottom = 0;
1466
1467 boolean chroma_edge_enable;
1468
1469 uint32 _is_scale_enabled = 0;
1470 uint32 _is_yuv_offsite_vertical = 0;
1471
1472 /* fg edge duplicate */
1473 reg = 0x0;
1474
1475 if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) { /* if scaling enabled */
1476
1477 _is_scale_enabled = 1;
1478
1479 /*
1480 * if rotation mode involves a 90 deg rotation, flip
1481 * dst_roi_width with dst_roi_height.
1482 * Scaling ratios is based on source ROI dimensions, and
1483 * dst ROI dimensions before rotation.
1484 */
1485 if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
1486 dst_roi_width = iBuf->roi.dst_height;
1487 dst_roi_height = iBuf->roi.dst_width;
1488 } else {
1489 dst_roi_width = iBuf->roi.dst_width;
1490 dst_roi_height = iBuf->roi.dst_height;
1491 }
1492
1493 /*
1494 * Find out the luma pixels needed for scaling in the
1495 * x direction (LEFT and RIGHT). Locations of pixels are
1496 * relative to the ROI. Upper-left corner of ROI corresponds
1497 * to coordinates (0,0). Also set the number of luma pixel
1498 * to repeat.
1499 */
1500 if (iBuf->roi.width > 3 * dst_roi_width) {
1501 /* scale factor < 1/3 */
1502 luma_interp_point_left = 0;
1503 luma_interp_point_right = (iBuf->roi.width - 1);
1504 luma_repeat_left = 0;
1505 luma_repeat_right = 0;
1506 } else if (iBuf->roi.width == 3 * dst_roi_width) {
1507 /* scale factor == 1/3 */
1508 luma_interp_point_left = 0;
1509 luma_interp_point_right = (iBuf->roi.width - 1) + 1;
1510 luma_repeat_left = 0;
1511 luma_repeat_right = 1;
1512 } else if ((iBuf->roi.width > dst_roi_width) &&
1513 (iBuf->roi.width < 3 * dst_roi_width)) {
1514 /* 1/3 < scale factor < 1 */
1515 luma_interp_point_left = -1;
1516 luma_interp_point_right = (iBuf->roi.width - 1) + 1;
1517 luma_repeat_left = 1;
1518 luma_repeat_right = 1;
1519 }
1520
1521 else if (iBuf->roi.width == dst_roi_width) {
1522 /* scale factor == 1 */
1523 luma_interp_point_left = -1;
1524 luma_interp_point_right = (iBuf->roi.width - 1) + 2;
1525 luma_repeat_left = 1;
1526 luma_repeat_right = 2;
1527 } else { /* (iBuf->roi.width < dst_roi_width) */
1528 /* scale factor > 1 */
1529 luma_interp_point_left = -2;
1530 luma_interp_point_right = (iBuf->roi.width - 1) + 2;
1531 luma_repeat_left = 2;
1532 luma_repeat_right = 2;
1533 }
1534
1535 /*
1536 * Find out the number of pixels needed for scaling in the
1537 * y direction (TOP and BOTTOM). Locations of pixels are
1538 * relative to the ROI. Upper-left corner of ROI corresponds
1539 * to coordinates (0,0). Also set the number of luma pixel
1540 * to repeat.
1541 */
1542 if (iBuf->roi.height > 3 * dst_roi_height) {
1543 /* scale factor < 1/3 */
1544 luma_interp_point_top = 0;
1545 luma_interp_point_bottom = (iBuf->roi.height - 1);
1546 luma_repeat_top = 0;
1547 luma_repeat_bottom = 0;
1548 } else if (iBuf->roi.height == 3 * dst_roi_height) {
1549 /* scale factor == 1/3 */
1550 luma_interp_point_top = 0;
1551 luma_interp_point_bottom = (iBuf->roi.height - 1) + 1;
1552 luma_repeat_top = 0;
1553 luma_repeat_bottom = 1;
1554 } else if ((iBuf->roi.height > dst_roi_height) &&
1555 (iBuf->roi.height < 3 * dst_roi_height)) {
1556 /* 1/3 < scale factor < 1 */
1557 luma_interp_point_top = -1;
1558 luma_interp_point_bottom = (iBuf->roi.height - 1) + 1;
1559 luma_repeat_top = 1;
1560 luma_repeat_bottom = 1;
1561 } else if (iBuf->roi.height == dst_roi_height) {
1562 /* scale factor == 1 */
1563 luma_interp_point_top = -1;
1564 luma_interp_point_bottom = (iBuf->roi.height - 1) + 2;
1565 luma_repeat_top = 1;
1566 luma_repeat_bottom = 2;
1567 } else { /* (iBuf->roi.height < dst_roi_height) */
1568 /* scale factor > 1 */
1569 luma_interp_point_top = -2;
1570 luma_interp_point_bottom = (iBuf->roi.height - 1) + 2;
1571 luma_repeat_top = 2;
1572 luma_repeat_bottom = 2;
1573 }
1574 } /* if (iBuf->scale.scale_flag) */
1575 else { /* scaling disabled */
1576 /*
1577 * Since no scaling needed, Tile Fetch does not require any
1578 * more luma pixel than what the ROI contains.
1579 */
1580 luma_interp_point_left = (int32) 0;
1581 luma_interp_point_right = (int32) (iBuf->roi.width - 1);
1582 luma_interp_point_top = (int32) 0;
1583 luma_interp_point_bottom = (int32) (iBuf->roi.height - 1);
1584
1585 luma_repeat_left = 0;
1586 luma_repeat_right = 0;
1587 luma_repeat_top = 0;
1588 luma_repeat_bottom = 0;
1589 }
1590
1591 /* After adding the ROI offsets, we have locations of
1592 * luma_interp_points relative to the image.
1593 */
1594 luma_interp_point_left += (int32) (iBuf->roi.x);
1595 luma_interp_point_right += (int32) (iBuf->roi.x);
1596 luma_interp_point_top += (int32) (iBuf->roi.y);
1597 luma_interp_point_bottom += (int32) (iBuf->roi.y);
1598
1599 /*
1600 * After adding the ROI offsets, we have locations of
1601 * chroma_interp_points relative to the image.
1602 */
1603 chroma_interp_point_left = luma_interp_point_left;
1604 chroma_interp_point_right = luma_interp_point_right;
1605 chroma_interp_point_top = luma_interp_point_top;
1606 chroma_interp_point_bottom = luma_interp_point_bottom;
1607
1608 chroma_edge_enable = TRUE;
1609 /* find out which chroma pixels are needed for chroma upsampling. */
1610 switch (iBuf->mdpImg.imgType) {
1611 /*
1612 * cosite in horizontal axis
1613 * fully sampled in vertical axis
1614 */
1615 case MDP_Y_CBCR_H2V1:
1616 case MDP_Y_CRCB_H2V1:
1617 case MDP_YCRYCB_H2V1:
1618 /* floor( luma_interp_point_left / 2 ); */
1619 chroma_interp_point_left = luma_interp_point_left >> 1;
1620 /* floor( ( luma_interp_point_right + 1 ) / 2 ); */
1621 chroma_interp_point_right = (luma_interp_point_right + 1) >> 1;
1622
1623 chroma_interp_point_top = luma_interp_point_top;
1624 chroma_interp_point_bottom = luma_interp_point_bottom;
1625 break;
1626
1627 /*
1628 * cosite in horizontal axis
1629 * offsite in vertical axis
1630 */
1631 case MDP_Y_CBCR_H2V2:
1632 case MDP_Y_CRCB_H2V2:
1633 /* floor( luma_interp_point_left / 2) */
1634 chroma_interp_point_left = luma_interp_point_left >> 1;
1635
1636 /* floor( ( luma_interp_point_right + 1 )/ 2 ) */
1637 chroma_interp_point_right = (luma_interp_point_right + 1) >> 1;
1638
1639 /* floor( (luma_interp_point_top - 1 ) / 2 ) */
1640 chroma_interp_point_top = (luma_interp_point_top - 1) >> 1;
1641
1642 /* floor( ( luma_interp_point_bottom + 1 ) / 2 ) */
1643 chroma_interp_point_bottom =
1644 (luma_interp_point_bottom + 1) >> 1;
1645
1646 _is_yuv_offsite_vertical = 1;
1647 break;
1648
1649 default:
1650 chroma_edge_enable = FALSE;
1651 chroma_interp_point_left = luma_interp_point_left;
1652 chroma_interp_point_right = luma_interp_point_right;
1653 chroma_interp_point_top = luma_interp_point_top;
1654 chroma_interp_point_bottom = luma_interp_point_bottom;
1655
1656 break;
1657 }
1658
1659 /* only if the image type is in YUV domain, we calculate chroma edge */
1660 if (chroma_edge_enable) {
1661 /* Defines which chroma pixels belongs to the roi */
1662 switch (iBuf->mdpImg.imgType) {
1663 /*
1664 * Cosite in horizontal direction, and fully sampled
1665 * in vertical direction.
1666 */
1667 case MDP_Y_CBCR_H2V1:
1668 case MDP_Y_CRCB_H2V1:
1669 case MDP_YCRYCB_H2V1:
1670 /*
1671 * width of chroma ROI is 1/2 of size of luma ROI
1672 * height of chroma ROI same as size of luma ROI
1673 */
1674 chroma_bound_left = iBuf->roi.x / 2;
1675
1676 /* there are half as many chroma pixel as luma pixels */
1677 chroma_bound_right =
1678 (iBuf->roi.width + iBuf->roi.x - 1) / 2;
1679 chroma_bound_top = iBuf->roi.y;
1680 chroma_bound_bottom =
1681 (iBuf->roi.height + iBuf->roi.y - 1);
1682 break;
1683
1684 case MDP_Y_CBCR_H2V2:
1685 case MDP_Y_CRCB_H2V2:
1686 /*
1687 * cosite in horizontal dir, and offsite in vertical dir
1688 * width of chroma ROI is 1/2 of size of luma ROI
1689 * height of chroma ROI is 1/2 of size of luma ROI
1690 */
1691
1692 chroma_bound_left = iBuf->roi.x / 2;
1693 chroma_bound_right =
1694 (iBuf->roi.width + iBuf->roi.x - 1) / 2;
1695 chroma_bound_top = iBuf->roi.y / 2;
1696 chroma_bound_bottom =
1697 (iBuf->roi.height + iBuf->roi.y - 1) / 2;
1698 break;
1699
1700 default:
1701 /*
1702 * If no valid chroma sub-sampling format specified,
1703 * assume 4:4:4 ( i.e. fully sampled). Set ROI
1704 * boundaries for chroma same as ROI boundaries for
1705 * luma.
1706 */
1707 chroma_bound_left = iBuf->roi.x;
1708 chroma_bound_right = iBuf->roi.width + iBuf->roi.x - 1;
1709 chroma_bound_top = iBuf->roi.y;
1710 chroma_bound_bottom =
1711 (iBuf->roi.height + iBuf->roi.y - 1);
1712 break;
1713 }
1714
1715 /*
1716 * Knowing which chroma pixels are needed, and which chroma
1717 * pixels belong to the ROI (i.e. available for fetching ),
1718 * calculate how many chroma pixels Tile Fetch needs to
1719 * duplicate. If any required chroma pixels falls outside
1720 * of the ROI, Tile Fetch must obtain them by replicating
1721 * pixels.
1722 */
1723 if (chroma_bound_left > chroma_interp_point_left)
1724 chroma_repeat_left =
1725 chroma_bound_left - chroma_interp_point_left;
1726 else
1727 chroma_repeat_left = 0;
1728
1729 if (chroma_interp_point_right > chroma_bound_right)
1730 chroma_repeat_right =
1731 chroma_interp_point_right - chroma_bound_right;
1732 else
1733 chroma_repeat_right = 0;
1734
1735 if (chroma_bound_top > chroma_interp_point_top)
1736 chroma_repeat_top =
1737 chroma_bound_top - chroma_interp_point_top;
1738 else
1739 chroma_repeat_top = 0;
1740
1741 if (chroma_interp_point_bottom > chroma_bound_bottom)
1742 chroma_repeat_bottom =
1743 chroma_interp_point_bottom - chroma_bound_bottom;
1744 else
1745 chroma_repeat_bottom = 0;
1746
1747 if (_is_scale_enabled && (iBuf->roi.height == 1)
1748 && _is_yuv_offsite_vertical) {
1749 chroma_repeat_bottom = 3;
1750 chroma_repeat_top = 0;
1751 }
1752 }
1753 /* make sure chroma repeats are non-negative */
1754 if ((chroma_repeat_left < 0) || (chroma_repeat_right < 0) ||
1755 (chroma_repeat_top < 0) || (chroma_repeat_bottom < 0))
1756 return -1;
1757
1758 /* make sure chroma repeats are no larger than 3 pixels */
1759 if ((chroma_repeat_left > 3) || (chroma_repeat_right > 3) ||
1760 (chroma_repeat_top > 3) || (chroma_repeat_bottom > 3))
1761 return -1;
1762
1763 /* make sure luma repeats are non-negative */
1764 if ((luma_repeat_left < 0) || (luma_repeat_right < 0) ||
1765 (luma_repeat_top < 0) || (luma_repeat_bottom < 0))
1766 return -1;
1767
1768 /* make sure luma repeats are no larger than 3 pixels */
1769 if ((luma_repeat_left > 3) || (luma_repeat_right > 3) ||
1770 (luma_repeat_top > 3) || (luma_repeat_bottom > 3))
1771 return -1;
1772
1773 /* write chroma_repeat_left to register */
1774 reg |= (chroma_repeat_left & 3) << MDP_LEFT_CHROMA;
1775
1776 /* write chroma_repeat_right to register */
1777 reg |= (chroma_repeat_right & 3) << MDP_RIGHT_CHROMA;
1778
1779 /* write chroma_repeat_top to register */
1780 reg |= (chroma_repeat_top & 3) << MDP_TOP_CHROMA;
1781
1782 /* write chroma_repeat_bottom to register */
1783 reg |= (chroma_repeat_bottom & 3) << MDP_BOTTOM_CHROMA;
1784
1785 /* write luma_repeat_left to register */
1786 reg |= (luma_repeat_left & 3) << MDP_LEFT_LUMA;
1787
1788 /* write luma_repeat_right to register */
1789 reg |= (luma_repeat_right & 3) << MDP_RIGHT_LUMA;
1790
1791 /* write luma_repeat_top to register */
1792 reg |= (luma_repeat_top & 3) << MDP_TOP_LUMA;
1793
1794 /* write luma_repeat_bottom to register */
1795 reg |= (luma_repeat_bottom & 3) << MDP_BOTTOM_LUMA;
1796
1797 /* done with reg */
1798 *dup = reg;
1799
1800 /* bg edge duplicate */
1801 reg = 0x0;
1802
1803 switch (iBuf->ibuf_type) {
1804 case MDP_Y_CBCR_H2V2:
1805 case MDP_Y_CRCB_H2V2:
1806 /*
1807 * Edge condition for MDP_Y_CRCB/CBCR_H2V2 cosite only.
1808 * For 420 cosite, 1 chroma replicated on all sides except
1809 * left, so reg 101b8 should be 0x0209. For 420 offsite,
1810 * 1 chroma replicated all sides.
1811 */
1812 if (iBuf->roi.lcd_y == 0) {
1813 reg |= BIT(MDP_TOP_CHROMA);
1814 }
1815
1816 if ((iBuf->roi.lcd_y + iBuf->roi.dst_height) ==
1817 iBuf->ibuf_height) {
1818 reg |= BIT(MDP_BOTTOM_CHROMA);
1819 }
1820
1821 if (((iBuf->roi.lcd_x + iBuf->roi.dst_width) ==
1822 iBuf->ibuf_width) && ((iBuf->roi.dst_width % 2) == 0)) {
1823 reg |= BIT(MDP_RIGHT_CHROMA);
1824 }
1825
1826 break;
1827
1828 case MDP_Y_CBCR_H2V1:
1829 case MDP_Y_CRCB_H2V1:
1830 case MDP_YCRYCB_H2V1:
1831 if (((iBuf->roi.lcd_x + iBuf->roi.dst_width) ==
1832 iBuf->ibuf_width) && ((iBuf->roi.dst_width % 2) == 0)) {
1833 reg |= BIT(MDP_RIGHT_CHROMA);
1834 }
1835 break;
1836 default:
1837 break;
1838 }
1839
1840 *dup2 = reg;
1841
1842 return 0;
1843}
1844
1845#define ADJUST_IP /* for 1/3 scale factor fix */
1846
1847static int mdp_calc_scale_params(
1848/* ROI origin coordinate for the dimension */
1849 uint32 org,
1850/* src ROI dimension */
1851 uint32 dim_in,
1852/* scaled ROI dimension*/
1853 uint32 dim_out,
1854/* is this ROI width dimension? */
1855 boolean is_W,
1856/* initial phase location address */
1857 int32 *phase_init_ptr,
1858/* phase increment location address */
1859 uint32 *phase_step_ptr,
1860/* ROI start over-fetch location address */
1861 uint32 *num_repl_beg_ptr,
1862/* ROI end over-fetch location address */
1863 uint32 *num_repl_end_ptr)
1864{
1865 boolean rpa_on = FALSE;
1866 int init_phase = 0;
1867 uint32 beg_of = 0;
1868 uint32 end_of = 0;
1869 uint64 numer = 0;
1870 uint64 denom = 0;
1871 /*uint64 inverter = 1; */
1872 int64 point5 = 1;
1873 int64 one = 1;
1874 int64 k1, k2, k3, k4; /* linear equation coefficients */
1875 uint64 int_mask;
1876 uint64 fract_mask;
1877 uint64 Os;
1878 int64 Osprime;
1879 int64 Od;
1880 int64 Odprime;
1881 int64 Oreq;
1882 uint64 Es;
1883 uint64 Ed;
1884 uint64 Ereq;
1885#ifdef ADJUST_IP
1886 int64 IP64;
1887 int64 delta;
1888#endif
1889 uint32 mult;
1890
1891 /*
1892 * The phase accumulator should really be rational for all cases in a
1893 * general purpose polyphase scaler for a tiled architecture with
1894 * non-zero * origin capability because there is no way to represent
1895 * certain scale factors in fixed point regardless of precision.
1896 * The error incurred in attempting to use fixed point is most
1897 * eggregious for SF where 1/SF is an integral multiple of 1/3.
1898 *
1899 * However, since the MDP2 has already been committed to HW, we
1900 * only use the rational phase accumulator (RPA) when 1/SF is an
1901 * integral multiple of 1/3. This will help minimize regressions in
1902 * matching the HW to the C-Sim.
1903 */
1904 /*
1905 * Set the RPA flag for this dimension.
1906 *
1907 * In order for 1/SF (dim_in/dim_out) to be an integral multiple of
1908 * 1/3, dim_out must be an integral multiple of 3.
1909 */
1910 if (!(dim_out % 3)) {
1911 mult = dim_out / 3;
1912 rpa_on = (!(dim_in % mult));
1913 }
1914
1915 numer = dim_out;
1916 denom = dim_in;
1917
1918 /*
1919 * convert to U30.34 before division
1920 *
1921 * The K vectors carry 4 extra bits of precision
1922 * and are rounded.
1923 *
1924 * We initially go 5 bits over then round by adding
1925 * 1 and right shifting by 1
1926 * so final result is U31.33
1927 */
1928 numer <<= PQF_PLUS_5;
1929
1930 /* now calculate the scale factor (aka k3) */
1931 k3 = ((mdp_do_div(numer, denom) + 1) >> 1);
1932
1933 /* check scale factor for legal range [0.25 - 4.0] */
1934 if (((k3 >> 4) < (1LL << PQF_MINUS_2)) ||
1935 ((k3 >> 4) > (1LL << PQF_PLUS_2))) {
1936 return -1;
1937 }
1938
1939 /* calculate inverse scale factor (aka k1) for phase init */
1940 numer = dim_in;
1941 denom = dim_out;
1942 numer <<= PQF_PLUS_5;
1943 k1 = ((mdp_do_div(numer, denom) + 1) >> 1);
1944
1945 /*
1946 * calculate initial phase and ROI overfetch
1947 */
1948 /* convert point5 & one to S39.24 (will always be positive) */
1949 point5 <<= (PQF_PLUS_4 - 1);
1950 one <<= PQF_PLUS_4;
1951 k2 = ((k1 - one) >> 1);
1952 init_phase = (int)(k2 >> 4);
1953 k4 = ((k3 - one) >> 1);
1954 if (k3 == one) {
1955 /* the simple case; SF = 1.0 */
1956 beg_of = 1;
1957 end_of = 2;
1958 } else {
1959 /* calculate the masks */
1960 fract_mask = one - 1;
1961 int_mask = ~fract_mask;
1962
1963 if (!rpa_on) {
1964 /*
1965 * FIXED POINT IMPLEMENTATION
1966 */
1967 if (!org) {
1968 /* A fairly simple case; ROI origin = 0 */
1969 if (k1 < one) {
1970 /* upscaling */
1971 beg_of = end_of = 2;
1972 }
1973 /* 0.33 <= SF < 1.0 */
1974 else if (k1 < (3LL << PQF_PLUS_4))
1975 beg_of = end_of = 1;
1976 /* 0.33 == SF */
1977 else if (k1 == (3LL << PQF_PLUS_4)) {
1978 beg_of = 0;
1979 end_of = 1;
1980 }
1981 /* 0.25 <= SF < 0.33 */
1982 else
1983 beg_of = end_of = 0;
1984 } else {
1985 /*
1986 * The complicated case; ROI origin != 0
1987 * init_phase needs to be adjusted
1988 * OF is also position dependent
1989 */
1990
1991 /* map (org - .5) into destination space */
1992 Os = ((uint64) org << 1) - 1;
1993 Od = ((k3 * Os) >> 1) + k4;
1994
1995 /* take the ceiling */
1996 Odprime = (Od & int_mask);
1997 if (Odprime != Od)
1998 Odprime += one;
1999
2000 /* now map that back to source space */
2001 Osprime = (k1 * (Odprime >> PQF_PLUS_4)) + k2;
2002
2003 /* then floor & decrement to calculate the required
2004 starting coordinate */
2005 Oreq = (Osprime & int_mask) - one;
2006
2007 /* calculate end coord in destination space then map to
2008 source space */
2009 Ed = Odprime +
2010 ((uint64) dim_out << PQF_PLUS_4) - one;
2011 Es = (k1 * (Ed >> PQF_PLUS_4)) + k2;
2012
2013 /* now floor & increment by 2 to calculate the required
2014 ending coordinate */
2015 Ereq = (Es & int_mask) + (one << 1);
2016
2017 /* calculate initial phase */
2018#ifdef ADJUST_IP
2019
2020 IP64 = Osprime - Oreq;
2021 delta = ((int64) (org) << PQF_PLUS_4) - Oreq;
2022 IP64 -= delta;
2023
2024 /* limit to valid range before the left shift */
2025 delta = (IP64 & (1LL << 63)) ? 4 : -4;
2026 delta <<= PQF_PLUS_4;
2027 while (abs((int)(IP64 >> PQF_PLUS_4)) > 4)
2028 IP64 += delta;
2029
2030 /* right shift to account for extra bits of precision */
2031 init_phase = (int)(IP64 >> 4);
2032
2033#else /* ADJUST_IP */
2034
2035 /* just calculate the real initial phase */
2036 init_phase = (int)((Osprime - Oreq) >> 4);
2037
2038#endif /* ADJUST_IP */
2039
2040 /* calculate the overfetch */
2041 beg_of = org - (uint32) (Oreq >> PQF_PLUS_4);
2042 end_of =
2043 (uint32) (Ereq >> PQF_PLUS_4) - (org +
2044 dim_in -
2045 1);
2046 }
2047 } else {
2048 /*
2049 * RPA IMPLEMENTATION
2050 *
2051 * init_phase needs to be calculated in all RPA_on cases
2052 * because it's a numerator, not a fixed point value.
2053 */
2054
2055 /* map (org - .5) into destination space */
2056 Os = ((uint64) org << PQF_PLUS_4) - point5;
2057 Od = mdp_do_div((dim_out * (Os + point5)),
2058 dim_in) - point5;
2059
2060 /* take the ceiling */
2061 Odprime = (Od & int_mask);
2062 if (Odprime != Od)
2063 Odprime += one;
2064
2065 /* now map that back to source space */
2066 Osprime =
2067 mdp_do_div((dim_in * (Odprime + point5)),
2068 dim_out) - point5;
2069
2070 /* then floor & decrement to calculate the required
2071 starting coordinate */
2072 Oreq = (Osprime & int_mask) - one;
2073
2074 /* calculate end coord in destination space then map to
2075 source space */
2076 Ed = Odprime + ((uint64) dim_out << PQF_PLUS_4) - one;
2077 Es = mdp_do_div((dim_in * (Ed + point5)),
2078 dim_out) - point5;
2079
2080 /* now floor & increment by 2 to calculate the required
2081 ending coordinate */
2082 Ereq = (Es & int_mask) + (one << 1);
2083
2084 /* calculate initial phase */
2085
2086#ifdef ADJUST_IP
2087
2088 IP64 = Osprime - Oreq;
2089 delta = ((int64) (org) << PQF_PLUS_4) - Oreq;
2090 IP64 -= delta;
2091
2092 /* limit to valid range before the left shift */
2093 delta = (IP64 & (1LL << 63)) ? 4 : -4;
2094 delta <<= PQF_PLUS_4;
2095 while (abs((int)(IP64 >> PQF_PLUS_4)) > 4)
2096 IP64 += delta;
2097
2098 /* right shift to account for extra bits of precision */
2099 init_phase = (int)(IP64 >> 4);
2100
2101#else /* ADJUST_IP */
2102
2103 /* just calculate the real initial phase */
2104 init_phase = (int)((Osprime - Oreq) >> 4);
2105
2106#endif /* ADJUST_IP */
2107
2108 /* calculate the overfetch */
2109 beg_of = org - (uint32) (Oreq >> PQF_PLUS_4);
2110 end_of =
2111 (uint32) (Ereq >> PQF_PLUS_4) - (org + dim_in - 1);
2112 }
2113 }
2114
2115 /* return the scale parameters */
2116 *phase_init_ptr = init_phase;
2117 *phase_step_ptr = (uint32) (k1 >> 4);
2118 *num_repl_beg_ptr = beg_of;
2119 *num_repl_end_ptr = end_of;
2120
2121 return 0;
2122}
2123
2124static uint8 *mdp_adjust_rot_addr(MDPIBUF *iBuf, uint8 *addr, uint32 uv)
2125{
2126 uint32 dest_ystride = iBuf->ibuf_width * iBuf->bpp;
2127 uint32 h_slice = 1;
2128
2129 if (uv && ((iBuf->ibuf_type == MDP_Y_CBCR_H2V2) ||
2130 (iBuf->ibuf_type == MDP_Y_CRCB_H2V2)))
2131 h_slice = 2;
2132
2133 if (MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_ROT90) ^
2134 MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_LR)) {
2135 addr =
2136 addr + (iBuf->roi.dst_width -
2137 MIN(16, iBuf->roi.dst_width)) * iBuf->bpp;
2138 }
2139 if (MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_UD)) {
2140 addr =
2141 addr + ((iBuf->roi.dst_height -
2142 MIN(16, iBuf->roi.dst_height))/h_slice) * dest_ystride;
2143 }
2144
2145 return addr;
2146}
2147
2148void mdp_set_scale(MDPIBUF *iBuf,
2149 uint32 dst_roi_width,
2150 uint32 dst_roi_height,
2151 boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr)
2152{
2153 uint32 dst_roi_width_scale;
2154 uint32 dst_roi_height_scale;
2155 boolean use_pr;
2156 uint32 phasex_step = 0;
2157 uint32 phasey_step = 0;
2158 int32 phasex_init = 0;
2159 int32 phasey_init = 0;
2160 uint32 lines_dup = 0;
2161 uint32 lines_dup_bg = 0;
2162 uint32 dummy;
2163 uint32 mdp_blur = 0;
2164
2165 if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {
2166 if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
2167 dst_roi_width_scale = dst_roi_height;
2168 dst_roi_height_scale = dst_roi_width;
2169 } else {
2170 dst_roi_width_scale = dst_roi_width;
2171 dst_roi_height_scale = dst_roi_height;
2172 }
2173
2174 mdp_blur = iBuf->mdpImg.mdpOp & MDPOP_BLUR;
2175
2176 if ((dst_roi_width_scale != iBuf->roi.width) ||
2177 (dst_roi_height_scale != iBuf->roi.height) ||
2178 mdp_blur) {
2179 *pppop_reg_ptr |=
2180 (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
2181
2182 /* let's use SHIM logic to calculate the partial ROI scaling */
2183#if 0
2184 phasex_step =
2185 (uint32) mdp_do_div(0x20000000 * iBuf->roi.width,
2186 dst_roi_width_scale);
2187 phasey_step =
2188 (uint32) mdp_do_div(0x20000000 * iBuf->roi.height,
2189 dst_roi_height_scale);
2190
2191/*
2192 phasex_step= ((long long) iBuf->roi.width * 0x20000000)/dst_roi_width_scale;
2193 phasey_step= ((long long)iBuf->roi.height * 0x20000000)/dst_roi_height_scale;
2194*/
2195
2196 phasex_init =
2197 (((long long)phasex_step - 0x20000000) >> 1);
2198 phasey_init =
2199 (((long long)phasey_step - 0x20000000) >> 1);
2200
2201#else
2202 mdp_calc_scale_params(iBuf->roi.x, iBuf->roi.width,
2203 dst_roi_width_scale, 1,
2204 &phasex_init, &phasex_step,
2205 &dummy, &dummy);
2206 mdp_calc_scale_params(iBuf->roi.y, iBuf->roi.height,
2207 dst_roi_height_scale, 0,
2208 &phasey_init, &phasey_step,
2209 &dummy, &dummy);
2210#endif
2211 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
2212 phasex_init);
2213 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
2214 phasey_init);
2215 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144,
2216 phasex_step);
2217 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148,
2218 phasey_step);
2219
2220 use_pr = (inputRGB) && (outputRGB);
2221
2222 if ((dst_roi_width_scale > iBuf->roi.width) ||
2223 (dst_roi_height_scale > iBuf->roi.height)) {
2224 if ((use_pr)
2225 && (mdp_curr_up_scale_xy !=
2226 MDP_PR_SCALE_UP)) {
2227 mdp_load_pr_upscale_table();
2228 mdp_curr_up_scale_xy = MDP_PR_SCALE_UP;
2229 } else if ((!use_pr)
2230 && (mdp_curr_up_scale_xy !=
2231 MDP_BC_SCALE_UP)) {
2232 mdp_load_bc_upscale_table();
2233 mdp_curr_up_scale_xy = MDP_BC_SCALE_UP;
2234 }
2235 }
2236
2237 if (mdp_blur) {
2238 load_scale_table(mdp_gaussian_blur_table,
2239 ARRAY_SIZE(mdp_gaussian_blur_table));
2240 mdp_curr_down_scale_x = MDP_SCALE_BLUR;
2241 mdp_curr_down_scale_y = MDP_SCALE_BLUR;
2242 }
2243
2244 /* 0.2 < x <= 1 scaling factor */
2245 if ((dst_roi_width_scale <= iBuf->roi.width) &&
2246 !mdp_blur) {
2247 if (((dst_roi_width_scale * 10) /
2248 iBuf->roi.width) > 8) {
2249 if ((use_pr)
2250 && (mdp_curr_down_scale_x !=
2251 MDP_PR_SCALE_POINT8_1)) {
2252 mdp_load_pr_downscale_table_x_point8TO1
2253 ();
2254 mdp_curr_down_scale_x =
2255 MDP_PR_SCALE_POINT8_1;
2256 } else if ((!use_pr)
2257 && (mdp_curr_down_scale_x !=
2258 MDP_BC_SCALE_POINT8_1)) {
2259 mdp_load_bc_downscale_table_x_point8TO1
2260 ();
2261 mdp_curr_down_scale_x =
2262 MDP_BC_SCALE_POINT8_1;
2263 }
2264 } else
2265 if (((dst_roi_width_scale * 10) /
2266 iBuf->roi.width) > 6) {
2267 if ((use_pr)
2268 && (mdp_curr_down_scale_x !=
2269 MDP_PR_SCALE_POINT6_POINT8)) {
2270 mdp_load_pr_downscale_table_x_point6TOpoint8
2271 ();
2272 mdp_curr_down_scale_x =
2273 MDP_PR_SCALE_POINT6_POINT8;
2274 } else if ((!use_pr)
2275 && (mdp_curr_down_scale_x !=
2276 MDP_BC_SCALE_POINT6_POINT8))
2277 {
2278 mdp_load_bc_downscale_table_x_point6TOpoint8
2279 ();
2280 mdp_curr_down_scale_x =
2281 MDP_BC_SCALE_POINT6_POINT8;
2282 }
2283 } else
2284 if (((dst_roi_width_scale * 10) /
2285 iBuf->roi.width) > 4) {
2286 if ((use_pr)
2287 && (mdp_curr_down_scale_x !=
2288 MDP_PR_SCALE_POINT4_POINT6)) {
2289 mdp_load_pr_downscale_table_x_point4TOpoint6
2290 ();
2291 mdp_curr_down_scale_x =
2292 MDP_PR_SCALE_POINT4_POINT6;
2293 } else if ((!use_pr)
2294 && (mdp_curr_down_scale_x !=
2295 MDP_BC_SCALE_POINT4_POINT6))
2296 {
2297 mdp_load_bc_downscale_table_x_point4TOpoint6
2298 ();
2299 mdp_curr_down_scale_x =
2300 MDP_BC_SCALE_POINT4_POINT6;
2301 }
2302 } else {
2303 if ((use_pr)
2304 && (mdp_curr_down_scale_x !=
2305 MDP_PR_SCALE_POINT2_POINT4)) {
2306 mdp_load_pr_downscale_table_x_point2TOpoint4
2307 ();
2308 mdp_curr_down_scale_x =
2309 MDP_PR_SCALE_POINT2_POINT4;
2310 } else if ((!use_pr)
2311 && (mdp_curr_down_scale_x !=
2312 MDP_BC_SCALE_POINT2_POINT4))
2313 {
2314 mdp_load_bc_downscale_table_x_point2TOpoint4
2315 ();
2316 mdp_curr_down_scale_x =
2317 MDP_BC_SCALE_POINT2_POINT4;
2318 }
2319 }
2320 }
2321 /* 0.2 < y <= 1 scaling factor */
2322 if ((dst_roi_height_scale <= iBuf->roi.height) &&
2323 !mdp_blur) {
2324 if (((dst_roi_height_scale * 10) /
2325 iBuf->roi.height) > 8) {
2326 if ((use_pr)
2327 && (mdp_curr_down_scale_y !=
2328 MDP_PR_SCALE_POINT8_1)) {
2329 mdp_load_pr_downscale_table_y_point8TO1
2330 ();
2331 mdp_curr_down_scale_y =
2332 MDP_PR_SCALE_POINT8_1;
2333 } else if ((!use_pr)
2334 && (mdp_curr_down_scale_y !=
2335 MDP_BC_SCALE_POINT8_1)) {
2336 mdp_load_bc_downscale_table_y_point8TO1
2337 ();
2338 mdp_curr_down_scale_y =
2339 MDP_BC_SCALE_POINT8_1;
2340 }
2341 } else
2342 if (((dst_roi_height_scale * 10) /
2343 iBuf->roi.height) > 6) {
2344 if ((use_pr)
2345 && (mdp_curr_down_scale_y !=
2346 MDP_PR_SCALE_POINT6_POINT8)) {
2347 mdp_load_pr_downscale_table_y_point6TOpoint8
2348 ();
2349 mdp_curr_down_scale_y =
2350 MDP_PR_SCALE_POINT6_POINT8;
2351 } else if ((!use_pr)
2352 && (mdp_curr_down_scale_y !=
2353 MDP_BC_SCALE_POINT6_POINT8))
2354 {
2355 mdp_load_bc_downscale_table_y_point6TOpoint8
2356 ();
2357 mdp_curr_down_scale_y =
2358 MDP_BC_SCALE_POINT6_POINT8;
2359 }
2360 } else
2361 if (((dst_roi_height_scale * 10) /
2362 iBuf->roi.height) > 4) {
2363 if ((use_pr)
2364 && (mdp_curr_down_scale_y !=
2365 MDP_PR_SCALE_POINT4_POINT6)) {
2366 mdp_load_pr_downscale_table_y_point4TOpoint6
2367 ();
2368 mdp_curr_down_scale_y =
2369 MDP_PR_SCALE_POINT4_POINT6;
2370 } else if ((!use_pr)
2371 && (mdp_curr_down_scale_y !=
2372 MDP_BC_SCALE_POINT4_POINT6))
2373 {
2374 mdp_load_bc_downscale_table_y_point4TOpoint6
2375 ();
2376 mdp_curr_down_scale_y =
2377 MDP_BC_SCALE_POINT4_POINT6;
2378 }
2379 } else {
2380 if ((use_pr)
2381 && (mdp_curr_down_scale_y !=
2382 MDP_PR_SCALE_POINT2_POINT4)) {
2383 mdp_load_pr_downscale_table_y_point2TOpoint4
2384 ();
2385 mdp_curr_down_scale_y =
2386 MDP_PR_SCALE_POINT2_POINT4;
2387 } else if ((!use_pr)
2388 && (mdp_curr_down_scale_y !=
2389 MDP_BC_SCALE_POINT2_POINT4))
2390 {
2391 mdp_load_bc_downscale_table_y_point2TOpoint4
2392 ();
2393 mdp_curr_down_scale_y =
2394 MDP_BC_SCALE_POINT2_POINT4;
2395 }
2396 }
2397 }
2398 } else {
2399 iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE);
2400 }
2401 }
2402 /* setting edge condition here after scaling check */
2403 if (mdp_get_edge_cond(iBuf, &lines_dup, &lines_dup_bg))
2404 printk(KERN_ERR "msm_fb: mdp_get_edge_cond() error!\n");
2405
2406 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01b8, lines_dup);
2407 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01bc, lines_dup_bg);
2408}
2409
2410void mdp_init_scale_table(void)
2411{
2412 mdp_curr_up_scale_xy = MDP_INIT_SCALE;
2413 mdp_curr_down_scale_x = MDP_INIT_SCALE;
2414 mdp_curr_down_scale_y = MDP_INIT_SCALE;
2415}
2416
2417void mdp_adjust_start_addr(uint8 **src0,
2418 uint8 **src1,
2419 int v_slice,
2420 int h_slice,
2421 int x,
2422 int y,
2423 uint32 width,
2424 uint32 height, int bpp, MDPIBUF *iBuf, int layer)
2425{
2426 *src0 += (x + y * width) * bpp;
2427
2428 /* if it's dest/bg buffer, we need to adjust it for rotation */
2429 if (layer != 0)
2430 *src0 = mdp_adjust_rot_addr(iBuf, *src0, 0);
2431
2432 if (*src1) {
2433 /*
2434 * MDP_Y_CBCR_H2V2/MDP_Y_CRCB_H2V2 cosite for now
2435 * we need to shift x direction same as y dir for offsite
2436 */
2437 *src1 +=
2438 ((x / h_slice) * h_slice +
2439 ((y == 0) ? 0 : ((y + 1) / v_slice - 1) * width)) * bpp;
2440
2441 /* if it's dest/bg buffer, we need to adjust it for rotation */
2442 if (layer != 0)
2443 *src1 = mdp_adjust_rot_addr(iBuf, *src1, 1);
2444 }
2445}
2446
2447void mdp_set_blend_attr(MDPIBUF *iBuf,
2448 uint32 *alpha,
2449 uint32 *tpVal,
2450 uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
2451{
2452 if (perPixelAlpha) {
2453 *pppop_reg_ptr |= PPP_OP_ROT_ON |
2454 PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
2455 } else {
2456 if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
2457 && (iBuf->mdpImg.alpha == 0xff)) {
2458 iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
2459 }
2460
2461 if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
2462 && (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
2463 *pppop_reg_ptr |=
2464 PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
2465 PPP_OP_BLEND_CONSTANT_ALPHA |
2466 PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
2467 PPP_BLEND_CALPHA_TRNASP;
2468
2469 *alpha = iBuf->mdpImg.alpha;
2470 *tpVal = iBuf->mdpImg.tpVal;
2471 } else {
2472 if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) {
2473 *pppop_reg_ptr |= PPP_OP_ROT_ON |
2474 PPP_OP_BLEND_ON |
2475 PPP_OP_BLEND_SRCPIXEL_TRANSP;
2476 *tpVal = iBuf->mdpImg.tpVal;
2477 } else if (iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) {
2478 *pppop_reg_ptr |= PPP_OP_ROT_ON |
2479 PPP_OP_BLEND_ON |
2480 PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
2481 PPP_OP_BLEND_CONSTANT_ALPHA;
2482 *alpha = iBuf->mdpImg.alpha;
2483 }
2484 }
2485 }
2486}
diff --git a/drivers/staging/msm/mdp_ppp_v31.c b/drivers/staging/msm/mdp_ppp_v31.c
new file mode 100644
index 000000000000..76495dbe4e64
--- /dev/null
+++ b/drivers/staging/msm/mdp_ppp_v31.c
@@ -0,0 +1,828 @@
1/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/fb.h>
25#include "linux/proc_fs.h"
26
27#include <mach/hardware.h>
28#include <linux/io.h>
29
30#include <asm/system.h>
31#include <asm/mach-types.h>
32#include <linux/semaphore.h>
33#include <asm/div64.h>
34
35#include "mdp.h"
36#include "msm_fb.h"
37
38#define MDP_SCALE_COEFF_NUM 32
39#define MDP_SCALE_0P2_TO_0P4_INDEX 0
40#define MDP_SCALE_0P4_TO_0P6_INDEX 32
41#define MDP_SCALE_0P6_TO_0P8_INDEX 64
42#define MDP_SCALE_0P8_TO_8P0_INDEX 96
43#define MDP_SCALE_COEFF_MASK 0x3ff
44
45#define MDP_SCALE_PR 0
46#define MDP_SCALE_FIR 1
47
48static uint32 mdp_scale_0p8_to_8p0_mode;
49static uint32 mdp_scale_0p6_to_0p8_mode;
50static uint32 mdp_scale_0p4_to_0p6_mode;
51static uint32 mdp_scale_0p2_to_0p4_mode;
52
53/* -------- All scaling range, "pixel repeat" -------- */
54static int16 mdp_scale_pixel_repeat_C0[MDP_SCALE_COEFF_NUM] = {
55 0, 0, 0, 0, 0, 0, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0
59};
60
61static int16 mdp_scale_pixel_repeat_C1[MDP_SCALE_COEFF_NUM] = {
62 511, 511, 511, 511, 511, 511, 511, 511,
63 511, 511, 511, 511, 511, 511, 511, 511,
64 511, 511, 511, 511, 511, 511, 511, 511,
65 511, 511, 511, 511, 511, 511, 511, 511
66};
67
68static int16 mdp_scale_pixel_repeat_C2[MDP_SCALE_COEFF_NUM] = {
69 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0, 0, 0, 0
73};
74
75static int16 mdp_scale_pixel_repeat_C3[MDP_SCALE_COEFF_NUM] = {
76 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0
80};
81
82/* --------------------------- FIR ------------------------------------- */
83/* -------- Downscale, ranging from 0.8x to 8.0x of original size -------- */
84
85static int16 mdp_scale_0p8_to_8p0_C0[MDP_SCALE_COEFF_NUM] = {
86 0, -7, -13, -19, -24, -28, -32, -34, -37, -39,
87 -40, -41, -41, -41, -40, -40, -38, -37, -35, -33,
88 -31, -29, -26, -24, -21, -18, -15, -13, -10, -7,
89 -5, -2
90};
91
92static int16 mdp_scale_0p8_to_8p0_C1[MDP_SCALE_COEFF_NUM] = {
93 511, 507, 501, 494, 485, 475, 463, 450, 436, 422,
94 405, 388, 370, 352, 333, 314, 293, 274, 253, 233,
95 213, 193, 172, 152, 133, 113, 95, 77, 60, 43,
96 28, 13
97};
98
99static int16 mdp_scale_0p8_to_8p0_C2[MDP_SCALE_COEFF_NUM] = {
100 0, 13, 28, 43, 60, 77, 95, 113, 133, 152,
101 172, 193, 213, 233, 253, 274, 294, 314, 333, 352,
102 370, 388, 405, 422, 436, 450, 463, 475, 485, 494,
103 501, 507,
104};
105
106static int16 mdp_scale_0p8_to_8p0_C3[MDP_SCALE_COEFF_NUM] = {
107 0, -2, -5, -7, -10, -13, -15, -18, -21, -24,
108 -26, -29, -31, -33, -35, -37, -38, -40, -40, -41,
109 -41, -41, -40, -39, -37, -34, -32, -28, -24, -19,
110 -13, -7
111};
112
113/* -------- Downscale, ranging from 0.6x to 0.8x of original size -------- */
114
115static int16 mdp_scale_0p6_to_0p8_C0[MDP_SCALE_COEFF_NUM] = {
116 104, 96, 89, 82, 75, 68, 61, 55, 49, 43,
117 38, 33, 28, 24, 20, 16, 12, 9, 6, 4,
118 2, 0, -2, -4, -5, -6, -7, -7, -8, -8,
119 -8, -8
120};
121
122static int16 mdp_scale_0p6_to_0p8_C1[MDP_SCALE_COEFF_NUM] = {
123 303, 303, 302, 300, 298, 296, 293, 289, 286, 281,
124 276, 270, 265, 258, 252, 245, 238, 230, 223, 214,
125 206, 197, 189, 180, 172, 163, 154, 145, 137, 128,
126 120, 112
127};
128
129static int16 mdp_scale_0p6_to_0p8_C2[MDP_SCALE_COEFF_NUM] = {
130 112, 120, 128, 137, 145, 154, 163, 172, 180, 189,
131 197, 206, 214, 223, 230, 238, 245, 252, 258, 265,
132 270, 276, 281, 286, 289, 293, 296, 298, 300, 302,
133 303, 303
134};
135
136static int16 mdp_scale_0p6_to_0p8_C3[MDP_SCALE_COEFF_NUM] = {
137 -8, -8, -8, -8, -7, -7, -6, -5, -4, -2,
138 0, 2, 4, 6, 9, 12, 16, 20, 24, 28,
139 33, 38, 43, 49, 55, 61, 68, 75, 82, 89,
140 96, 104
141};
142
143/* -------- Downscale, ranging from 0.4x to 0.6x of original size -------- */
144
145static int16 mdp_scale_0p4_to_0p6_C0[MDP_SCALE_COEFF_NUM] = {
146 136, 132, 128, 123, 119, 115, 111, 107, 103, 98,
147 95, 91, 87, 84, 80, 76, 73, 69, 66, 62,
148 59, 57, 54, 50, 47, 44, 41, 39, 36, 33,
149 32, 29
150};
151
152static int16 mdp_scale_0p4_to_0p6_C1[MDP_SCALE_COEFF_NUM] = {
153 206, 205, 204, 204, 201, 200, 199, 197, 196, 194,
154 191, 191, 189, 185, 184, 182, 180, 178, 176, 173,
155 170, 168, 165, 162, 160, 157, 155, 152, 148, 146,
156 142, 140
157};
158
159static int16 mdp_scale_0p4_to_0p6_C2[MDP_SCALE_COEFF_NUM] = {
160 140, 142, 146, 148, 152, 155, 157, 160, 162, 165,
161 168, 170, 173, 176, 178, 180, 182, 184, 185, 189,
162 191, 191, 194, 196, 197, 199, 200, 201, 204, 204,
163 205, 206
164};
165
166static int16 mdp_scale_0p4_to_0p6_C3[MDP_SCALE_COEFF_NUM] = {
167 29, 32, 33, 36, 39, 41, 44, 47, 50, 54,
168 57, 59, 62, 66, 69, 73, 76, 80, 84, 87,
169 91, 95, 98, 103, 107, 111, 115, 119, 123, 128,
170 132, 136
171};
172
173/* -------- Downscale, ranging from 0.2x to 0.4x of original size -------- */
174
175static int16 mdp_scale_0p2_to_0p4_C0[MDP_SCALE_COEFF_NUM] = {
176 131, 131, 130, 129, 128, 127, 127, 126, 125, 125,
177 124, 123, 123, 121, 120, 119, 119, 118, 117, 117,
178 116, 115, 115, 114, 113, 112, 111, 110, 109, 109,
179 108, 107
180};
181
182static int16 mdp_scale_0p2_to_0p4_C1[MDP_SCALE_COEFF_NUM] = {
183 141, 140, 140, 140, 140, 139, 138, 138, 138, 137,
184 137, 137, 136, 137, 137, 137, 136, 136, 136, 135,
185 135, 135, 134, 134, 134, 134, 134, 133, 133, 132,
186 132, 132
187};
188
189static int16 mdp_scale_0p2_to_0p4_C2[MDP_SCALE_COEFF_NUM] = {
190 132, 132, 132, 133, 133, 134, 134, 134, 134, 134,
191 135, 135, 135, 136, 136, 136, 137, 137, 137, 136,
192 137, 137, 137, 138, 138, 138, 139, 140, 140, 140,
193 140, 141
194};
195
196static int16 mdp_scale_0p2_to_0p4_C3[MDP_SCALE_COEFF_NUM] = {
197 107, 108, 109, 109, 110, 111, 112, 113, 114, 115,
198 115, 116, 117, 117, 118, 119, 119, 120, 121, 123,
199 123, 124, 125, 125, 126, 127, 127, 128, 129, 130,
200 131, 131
201};
202
203static void mdp_update_scale_table(int index, int16 *c0, int16 *c1,
204 int16 *c2, int16 *c3)
205{
206 int i, val;
207
208 for (i = 0; i < MDP_SCALE_COEFF_NUM; i++) {
209 val =
210 ((MDP_SCALE_COEFF_MASK & c1[i]) << 16) |
211 (MDP_SCALE_COEFF_MASK & c0[i]);
212 MDP_OUTP(MDP_PPP_SCALE_COEFF_LSBn(index), val);
213 val =
214 ((MDP_SCALE_COEFF_MASK & c3[i]) << 16) |
215 (MDP_SCALE_COEFF_MASK & c2[i]);
216 MDP_OUTP(MDP_PPP_SCALE_COEFF_MSBn(index), val);
217 index++;
218 }
219}
220
221void mdp_init_scale_table(void)
222{
223 mdp_scale_0p2_to_0p4_mode = MDP_SCALE_FIR;
224 mdp_update_scale_table(MDP_SCALE_0P2_TO_0P4_INDEX,
225 mdp_scale_0p2_to_0p4_C0,
226 mdp_scale_0p2_to_0p4_C1,
227 mdp_scale_0p2_to_0p4_C2,
228 mdp_scale_0p2_to_0p4_C3);
229
230 mdp_scale_0p4_to_0p6_mode = MDP_SCALE_FIR;
231 mdp_update_scale_table(MDP_SCALE_0P4_TO_0P6_INDEX,
232 mdp_scale_0p4_to_0p6_C0,
233 mdp_scale_0p4_to_0p6_C1,
234 mdp_scale_0p4_to_0p6_C2,
235 mdp_scale_0p4_to_0p6_C3);
236
237 mdp_scale_0p6_to_0p8_mode = MDP_SCALE_FIR;
238 mdp_update_scale_table(MDP_SCALE_0P6_TO_0P8_INDEX,
239 mdp_scale_0p6_to_0p8_C0,
240 mdp_scale_0p6_to_0p8_C1,
241 mdp_scale_0p6_to_0p8_C2,
242 mdp_scale_0p6_to_0p8_C3);
243
244 mdp_scale_0p8_to_8p0_mode = MDP_SCALE_FIR;
245 mdp_update_scale_table(MDP_SCALE_0P8_TO_8P0_INDEX,
246 mdp_scale_0p8_to_8p0_C0,
247 mdp_scale_0p8_to_8p0_C1,
248 mdp_scale_0p8_to_8p0_C2,
249 mdp_scale_0p8_to_8p0_C3);
250}
251
252static long long mdp_do_div(long long num, long long den)
253{
254 do_div(num, den);
255 return num;
256}
257
258#define SCALER_PHASE_BITS 29
259#define HAL_MDP_PHASE_STEP_2P50 0x50000000
260#define HAL_MDP_PHASE_STEP_1P66 0x35555555
261#define HAL_MDP_PHASE_STEP_1P25 0x28000000
262
263struct phase_val {
264 int phase_init_x;
265 int phase_init_y;
266 int phase_step_x;
267 int phase_step_y;
268};
269
270static void mdp_calc_scaleInitPhase_3p1(uint32 in_w,
271 uint32 in_h,
272 uint32 out_w,
273 uint32 out_h,
274 boolean is_rotate,
275 boolean is_pp_x,
276 boolean is_pp_y, struct phase_val *pval)
277{
278 uint64 dst_ROI_width;
279 uint64 dst_ROI_height;
280 uint64 src_ROI_width;
281 uint64 src_ROI_height;
282
283 /*
284 * phase_step_x, phase_step_y, phase_init_x and phase_init_y
285 * are represented in fixed-point, unsigned 3.29 format
286 */
287 uint32 phase_step_x = 0;
288 uint32 phase_step_y = 0;
289 uint32 phase_init_x = 0;
290 uint32 phase_init_y = 0;
291 uint32 yscale_filter_sel, xscale_filter_sel;
292 uint32 scale_unit_sel_x, scale_unit_sel_y;
293
294 uint64 numerator, denominator;
295 uint64 temp_dim;
296
297 src_ROI_width = in_w;
298 src_ROI_height = in_h;
299 dst_ROI_width = out_w;
300 dst_ROI_height = out_h;
301
302 /* if there is a 90 degree rotation */
303 if (is_rotate) {
304 /* decide whether to use FIR or M/N for scaling */
305
306 /* if down-scaling by a factor smaller than 1/4 */
307 if (src_ROI_width > (4 * dst_ROI_height))
308 scale_unit_sel_x = 1; /* use M/N scalar */
309 else
310 scale_unit_sel_x = 0; /* use FIR scalar */
311
312 /* if down-scaling by a factor smaller than 1/4 */
313 if (src_ROI_height > (4 * dst_ROI_width))
314 scale_unit_sel_y = 1; /* use M/N scalar */
315 else
316 scale_unit_sel_y = 0; /* use FIR scalar */
317 } else {
318 /* decide whether to use FIR or M/N for scaling */
319
320 if (src_ROI_width > (4 * dst_ROI_width))
321 scale_unit_sel_x = 1; /* use M/N scalar */
322 else
323 scale_unit_sel_x = 0; /* use FIR scalar */
324
325 if (src_ROI_height > (4 * dst_ROI_height))
326 scale_unit_sel_y = 1; /* use M/N scalar */
327 else
328 scale_unit_sel_y = 0; /* use FIR scalar */
329
330 }
331
332 /* if there is a 90 degree rotation */
333 if (is_rotate) {
334 /* swap the width and height of dst ROI */
335 temp_dim = dst_ROI_width;
336 dst_ROI_width = dst_ROI_height;
337 dst_ROI_height = temp_dim;
338 }
339
340 /* calculate phase step for the x direction */
341
342 /* if destination is only 1 pixel wide, the value of phase_step_x
343 is unimportant. Assigning phase_step_x to src ROI width
344 as an arbitrary value. */
345 if (dst_ROI_width == 1)
346 phase_step_x = (uint32) ((src_ROI_width) << SCALER_PHASE_BITS);
347
348 /* if using FIR scalar */
349 else if (scale_unit_sel_x == 0) {
350
351 /* Calculate the quotient ( src_ROI_width - 1 ) / ( dst_ROI_width - 1)
352 with u3.29 precision. Quotient is rounded up to the larger
353 29th decimal point. */
354 numerator = (src_ROI_width - 1) << SCALER_PHASE_BITS;
355 denominator = (dst_ROI_width - 1); /* never equals to 0 because of the "( dst_ROI_width == 1 ) case" */
356 phase_step_x = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* divide and round up to the larger 29th decimal point. */
357
358 }
359
360 /* if M/N scalar */
361 else if (scale_unit_sel_x == 1) {
362 /* Calculate the quotient ( src_ROI_width ) / ( dst_ROI_width)
363 with u3.29 precision. Quotient is rounded down to the
364 smaller 29th decimal point. */
365 numerator = (src_ROI_width) << SCALER_PHASE_BITS;
366 denominator = (dst_ROI_width);
367 phase_step_x = (uint32) mdp_do_div(numerator, denominator);
368 }
369 /* calculate phase step for the y direction */
370
371 /* if destination is only 1 pixel wide, the value of
372 phase_step_x is unimportant. Assigning phase_step_x
373 to src ROI width as an arbitrary value. */
374 if (dst_ROI_height == 1)
375 phase_step_y = (uint32) ((src_ROI_height) << SCALER_PHASE_BITS);
376
377 /* if FIR scalar */
378 else if (scale_unit_sel_y == 0) {
379 /* Calculate the quotient ( src_ROI_height - 1 ) / ( dst_ROI_height - 1)
380 with u3.29 precision. Quotient is rounded up to the larger
381 29th decimal point. */
382 numerator = (src_ROI_height - 1) << SCALER_PHASE_BITS;
383 denominator = (dst_ROI_height - 1); /* never equals to 0 because of the "( dst_ROI_height == 1 )" case */
384 phase_step_y = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* Quotient is rounded up to the larger 29th decimal point. */
385
386 }
387
388 /* if M/N scalar */
389 else if (scale_unit_sel_y == 1) {
390 /* Calculate the quotient ( src_ROI_height ) / ( dst_ROI_height)
391 with u3.29 precision. Quotient is rounded down to the smaller
392 29th decimal point. */
393 numerator = (src_ROI_height) << SCALER_PHASE_BITS;
394 denominator = (dst_ROI_height);
395 phase_step_y = (uint32) mdp_do_div(numerator, denominator);
396 }
397
398 /* decide which set of FIR coefficients to use */
399 if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
400 xscale_filter_sel = 0;
401 else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
402 xscale_filter_sel = 1;
403 else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
404 xscale_filter_sel = 2;
405 else
406 xscale_filter_sel = 3;
407
408 if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
409 yscale_filter_sel = 0;
410 else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
411 yscale_filter_sel = 1;
412 else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
413 yscale_filter_sel = 2;
414 else
415 yscale_filter_sel = 3;
416
417 /* calculate phase init for the x direction */
418
419 /* if using FIR scalar */
420 if (scale_unit_sel_x == 0) {
421 if (dst_ROI_width == 1)
422 phase_init_x =
423 (uint32) ((src_ROI_width - 1) << SCALER_PHASE_BITS);
424 else
425 phase_init_x = 0;
426
427 }
428 /* M over N scalar */
429 else if (scale_unit_sel_x == 1)
430 phase_init_x = 0;
431
432 /* calculate phase init for the y direction
433 if using FIR scalar */
434 if (scale_unit_sel_y == 0) {
435 if (dst_ROI_height == 1)
436 phase_init_y =
437 (uint32) ((src_ROI_height -
438 1) << SCALER_PHASE_BITS);
439 else
440 phase_init_y = 0;
441
442 }
443 /* M over N scalar */
444 else if (scale_unit_sel_y == 1)
445 phase_init_y = 0;
446
447 /* write registers */
448 pval->phase_step_x = (uint32) phase_step_x;
449 pval->phase_step_y = (uint32) phase_step_y;
450 pval->phase_init_x = (uint32) phase_init_x;
451 pval->phase_init_y = (uint32) phase_init_y;
452
453 return;
454}
455
456void mdp_set_scale(MDPIBUF *iBuf,
457 uint32 dst_roi_width,
458 uint32 dst_roi_height,
459 boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr)
460{
461 uint32 dst_roi_width_scale;
462 uint32 dst_roi_height_scale;
463 struct phase_val pval;
464 boolean use_pr;
465 uint32 ppp_scale_config = 0;
466
467 if (!inputRGB)
468 ppp_scale_config |= BIT(6);
469
470 if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {
471 if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
472 dst_roi_width_scale = dst_roi_height;
473 dst_roi_height_scale = dst_roi_width;
474 } else {
475 dst_roi_width_scale = dst_roi_width;
476 dst_roi_height_scale = dst_roi_height;
477 }
478
479 if ((dst_roi_width_scale != iBuf->roi.width) ||
480 (dst_roi_height_scale != iBuf->roi.height) ||
481 (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
482 *pppop_reg_ptr |=
483 (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
484
485 mdp_calc_scaleInitPhase_3p1(iBuf->roi.width,
486 iBuf->roi.height,
487 dst_roi_width,
488 dst_roi_height,
489 iBuf->mdpImg.
490 mdpOp & MDPOP_ROT90, 1, 1,
491 &pval);
492
493 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
494 pval.phase_init_x);
495 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
496 pval.phase_init_y);
497 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144,
498 pval.phase_step_x);
499 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148,
500 pval.phase_step_y);
501
502 use_pr = (inputRGB) && (outputRGB);
503
504 /* x-direction */
505 if ((dst_roi_width_scale == iBuf->roi.width) &&
506 !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
507 *pppop_reg_ptr &= ~PPP_OP_SCALE_X_ON;
508 } else
509 if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
510 8) {
511 if ((use_pr)
512 && (mdp_scale_0p8_to_8p0_mode !=
513 MDP_SCALE_PR)) {
514 mdp_scale_0p8_to_8p0_mode =
515 MDP_SCALE_PR;
516 mdp_update_scale_table
517 (MDP_SCALE_0P8_TO_8P0_INDEX,
518 mdp_scale_pixel_repeat_C0,
519 mdp_scale_pixel_repeat_C1,
520 mdp_scale_pixel_repeat_C2,
521 mdp_scale_pixel_repeat_C3);
522 } else if ((!use_pr)
523 && (mdp_scale_0p8_to_8p0_mode !=
524 MDP_SCALE_FIR)) {
525 mdp_scale_0p8_to_8p0_mode =
526 MDP_SCALE_FIR;
527 mdp_update_scale_table
528 (MDP_SCALE_0P8_TO_8P0_INDEX,
529 mdp_scale_0p8_to_8p0_C0,
530 mdp_scale_0p8_to_8p0_C1,
531 mdp_scale_0p8_to_8p0_C2,
532 mdp_scale_0p8_to_8p0_C3);
533 }
534 ppp_scale_config |= (SCALE_U1_SET << 2);
535 } else
536 if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
537 6) {
538 if ((use_pr)
539 && (mdp_scale_0p6_to_0p8_mode !=
540 MDP_SCALE_PR)) {
541 mdp_scale_0p6_to_0p8_mode =
542 MDP_SCALE_PR;
543 mdp_update_scale_table
544 (MDP_SCALE_0P6_TO_0P8_INDEX,
545 mdp_scale_pixel_repeat_C0,
546 mdp_scale_pixel_repeat_C1,
547 mdp_scale_pixel_repeat_C2,
548 mdp_scale_pixel_repeat_C3);
549 } else if ((!use_pr)
550 && (mdp_scale_0p6_to_0p8_mode !=
551 MDP_SCALE_FIR)) {
552 mdp_scale_0p6_to_0p8_mode =
553 MDP_SCALE_FIR;
554 mdp_update_scale_table
555 (MDP_SCALE_0P6_TO_0P8_INDEX,
556 mdp_scale_0p6_to_0p8_C0,
557 mdp_scale_0p6_to_0p8_C1,
558 mdp_scale_0p6_to_0p8_C2,
559 mdp_scale_0p6_to_0p8_C3);
560 }
561 ppp_scale_config |= (SCALE_D2_SET << 2);
562 } else
563 if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
564 4) {
565 if ((use_pr)
566 && (mdp_scale_0p4_to_0p6_mode !=
567 MDP_SCALE_PR)) {
568 mdp_scale_0p4_to_0p6_mode =
569 MDP_SCALE_PR;
570 mdp_update_scale_table
571 (MDP_SCALE_0P4_TO_0P6_INDEX,
572 mdp_scale_pixel_repeat_C0,
573 mdp_scale_pixel_repeat_C1,
574 mdp_scale_pixel_repeat_C2,
575 mdp_scale_pixel_repeat_C3);
576 } else if ((!use_pr)
577 && (mdp_scale_0p4_to_0p6_mode !=
578 MDP_SCALE_FIR)) {
579 mdp_scale_0p4_to_0p6_mode =
580 MDP_SCALE_FIR;
581 mdp_update_scale_table
582 (MDP_SCALE_0P4_TO_0P6_INDEX,
583 mdp_scale_0p4_to_0p6_C0,
584 mdp_scale_0p4_to_0p6_C1,
585 mdp_scale_0p4_to_0p6_C2,
586 mdp_scale_0p4_to_0p6_C3);
587 }
588 ppp_scale_config |= (SCALE_D1_SET << 2);
589 } else
590 if (((dst_roi_width_scale * 4) / iBuf->roi.width) >=
591 1) {
592 if ((use_pr)
593 && (mdp_scale_0p2_to_0p4_mode !=
594 MDP_SCALE_PR)) {
595 mdp_scale_0p2_to_0p4_mode =
596 MDP_SCALE_PR;
597 mdp_update_scale_table
598 (MDP_SCALE_0P2_TO_0P4_INDEX,
599 mdp_scale_pixel_repeat_C0,
600 mdp_scale_pixel_repeat_C1,
601 mdp_scale_pixel_repeat_C2,
602 mdp_scale_pixel_repeat_C3);
603 } else if ((!use_pr)
604 && (mdp_scale_0p2_to_0p4_mode !=
605 MDP_SCALE_FIR)) {
606 mdp_scale_0p2_to_0p4_mode =
607 MDP_SCALE_FIR;
608 mdp_update_scale_table
609 (MDP_SCALE_0P2_TO_0P4_INDEX,
610 mdp_scale_0p2_to_0p4_C0,
611 mdp_scale_0p2_to_0p4_C1,
612 mdp_scale_0p2_to_0p4_C2,
613 mdp_scale_0p2_to_0p4_C3);
614 }
615 ppp_scale_config |= (SCALE_D0_SET << 2);
616 } else
617 ppp_scale_config |= BIT(0);
618
619 /* y-direction */
620 if ((dst_roi_height_scale == iBuf->roi.height) &&
621 !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
622 *pppop_reg_ptr &= ~PPP_OP_SCALE_Y_ON;
623 } else if (((dst_roi_height_scale * 10) /
624 iBuf->roi.height) > 8) {
625 if ((use_pr)
626 && (mdp_scale_0p8_to_8p0_mode !=
627 MDP_SCALE_PR)) {
628 mdp_scale_0p8_to_8p0_mode =
629 MDP_SCALE_PR;
630 mdp_update_scale_table
631 (MDP_SCALE_0P8_TO_8P0_INDEX,
632 mdp_scale_pixel_repeat_C0,
633 mdp_scale_pixel_repeat_C1,
634 mdp_scale_pixel_repeat_C2,
635 mdp_scale_pixel_repeat_C3);
636 } else if ((!use_pr)
637 && (mdp_scale_0p8_to_8p0_mode !=
638 MDP_SCALE_FIR)) {
639 mdp_scale_0p8_to_8p0_mode =
640 MDP_SCALE_FIR;
641 mdp_update_scale_table
642 (MDP_SCALE_0P8_TO_8P0_INDEX,
643 mdp_scale_0p8_to_8p0_C0,
644 mdp_scale_0p8_to_8p0_C1,
645 mdp_scale_0p8_to_8p0_C2,
646 mdp_scale_0p8_to_8p0_C3);
647 }
648 ppp_scale_config |= (SCALE_U1_SET << 4);
649 } else
650 if (((dst_roi_height_scale * 10) /
651 iBuf->roi.height) > 6) {
652 if ((use_pr)
653 && (mdp_scale_0p6_to_0p8_mode !=
654 MDP_SCALE_PR)) {
655 mdp_scale_0p6_to_0p8_mode =
656 MDP_SCALE_PR;
657 mdp_update_scale_table
658 (MDP_SCALE_0P6_TO_0P8_INDEX,
659 mdp_scale_pixel_repeat_C0,
660 mdp_scale_pixel_repeat_C1,
661 mdp_scale_pixel_repeat_C2,
662 mdp_scale_pixel_repeat_C3);
663 } else if ((!use_pr)
664 && (mdp_scale_0p6_to_0p8_mode !=
665 MDP_SCALE_FIR)) {
666 mdp_scale_0p6_to_0p8_mode =
667 MDP_SCALE_FIR;
668 mdp_update_scale_table
669 (MDP_SCALE_0P6_TO_0P8_INDEX,
670 mdp_scale_0p6_to_0p8_C0,
671 mdp_scale_0p6_to_0p8_C1,
672 mdp_scale_0p6_to_0p8_C2,
673 mdp_scale_0p6_to_0p8_C3);
674 }
675 ppp_scale_config |= (SCALE_D2_SET << 4);
676 } else
677 if (((dst_roi_height_scale * 10) /
678 iBuf->roi.height) > 4) {
679 if ((use_pr)
680 && (mdp_scale_0p4_to_0p6_mode !=
681 MDP_SCALE_PR)) {
682 mdp_scale_0p4_to_0p6_mode =
683 MDP_SCALE_PR;
684 mdp_update_scale_table
685 (MDP_SCALE_0P4_TO_0P6_INDEX,
686 mdp_scale_pixel_repeat_C0,
687 mdp_scale_pixel_repeat_C1,
688 mdp_scale_pixel_repeat_C2,
689 mdp_scale_pixel_repeat_C3);
690 } else if ((!use_pr)
691 && (mdp_scale_0p4_to_0p6_mode !=
692 MDP_SCALE_FIR)) {
693 mdp_scale_0p4_to_0p6_mode =
694 MDP_SCALE_FIR;
695 mdp_update_scale_table
696 (MDP_SCALE_0P4_TO_0P6_INDEX,
697 mdp_scale_0p4_to_0p6_C0,
698 mdp_scale_0p4_to_0p6_C1,
699 mdp_scale_0p4_to_0p6_C2,
700 mdp_scale_0p4_to_0p6_C3);
701 }
702 ppp_scale_config |= (SCALE_D1_SET << 4);
703 } else
704 if (((dst_roi_height_scale * 4) /
705 iBuf->roi.height) >= 1) {
706 if ((use_pr)
707 && (mdp_scale_0p2_to_0p4_mode !=
708 MDP_SCALE_PR)) {
709 mdp_scale_0p2_to_0p4_mode =
710 MDP_SCALE_PR;
711 mdp_update_scale_table
712 (MDP_SCALE_0P2_TO_0P4_INDEX,
713 mdp_scale_pixel_repeat_C0,
714 mdp_scale_pixel_repeat_C1,
715 mdp_scale_pixel_repeat_C2,
716 mdp_scale_pixel_repeat_C3);
717 } else if ((!use_pr)
718 && (mdp_scale_0p2_to_0p4_mode !=
719 MDP_SCALE_FIR)) {
720 mdp_scale_0p2_to_0p4_mode =
721 MDP_SCALE_FIR;
722 mdp_update_scale_table
723 (MDP_SCALE_0P2_TO_0P4_INDEX,
724 mdp_scale_0p2_to_0p4_C0,
725 mdp_scale_0p2_to_0p4_C1,
726 mdp_scale_0p2_to_0p4_C2,
727 mdp_scale_0p2_to_0p4_C3);
728 }
729 ppp_scale_config |= (SCALE_D0_SET << 4);
730 } else
731 ppp_scale_config |= BIT(1);
732
733 if (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING) {
734 ppp_scale_config |= BIT(7);
735 MDP_OUTP(MDP_BASE + 0x50020,
736 iBuf->mdpImg.sp_value);
737 }
738
739 MDP_OUTP(MDP_BASE + 0x10230, ppp_scale_config);
740 } else {
741 iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE);
742 }
743 }
744}
745
746void mdp_adjust_start_addr(uint8 **src0,
747 uint8 **src1,
748 int v_slice,
749 int h_slice,
750 int x,
751 int y,
752 uint32 width,
753 uint32 height, int bpp, MDPIBUF *iBuf, int layer)
754{
755 switch (layer) {
756 case 0:
757 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0200, (y << 16) | (x));
758 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0208,
759 (height << 16) | (width));
760 break;
761
762 case 1:
763 /* MDP 3.1 HW bug workaround */
764 if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
765 *src0 += (x + y * width) * bpp;
766 x = y = 0;
767 width = iBuf->roi.dst_width;
768 height = iBuf->roi.dst_height;
769 }
770
771 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0204, (y << 16) | (x));
772 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x020c,
773 (height << 16) | (width));
774 break;
775
776 case 2:
777 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x019c, (y << 16) | (x));
778 break;
779 }
780}
781
782void mdp_set_blend_attr(MDPIBUF *iBuf,
783 uint32 *alpha,
784 uint32 *tpVal,
785 uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
786{
787 int bg_alpha;
788
789 *alpha = iBuf->mdpImg.alpha;
790 *tpVal = iBuf->mdpImg.tpVal;
791
792 if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
793 *pppop_reg_ptr |= PPP_OP_ROT_ON |
794 PPP_OP_BLEND_ON | PPP_OP_BLEND_CONSTANT_ALPHA;
795
796 bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
797 PPP_BLEND_BG_ALPHA_REVERSE;
798
799 if (perPixelAlpha)
800 bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
801 else
802 bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
803
804 outpdw(MDP_BASE + 0x70010, bg_alpha);
805
806 if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
807 *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
808 } else if (perPixelAlpha) {
809 *pppop_reg_ptr |= PPP_OP_ROT_ON |
810 PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
811 } else {
812 if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
813 && (iBuf->mdpImg.alpha == 0xff)) {
814 iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
815 }
816
817 if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
818 || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
819 *pppop_reg_ptr |=
820 PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
821 PPP_OP_BLEND_CONSTANT_ALPHA |
822 PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
823 }
824
825 if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
826 *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
827 }
828}
diff --git a/drivers/staging/msm/mdp_vsync.c b/drivers/staging/msm/mdp_vsync.c
new file mode 100644
index 000000000000..bbd456044356
--- /dev/null
+++ b/drivers/staging/msm/mdp_vsync.c
@@ -0,0 +1,389 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/hrtimer.h>
26#include <linux/vmalloc.h>
27#include <linux/clk.h>
28
29#include <mach/hardware.h>
30#include <linux/io.h>
31
32#include <asm/system.h>
33#include <asm/mach-types.h>
34#include <linux/semaphore.h>
35#include <linux/uaccess.h>
36#include <mach/gpio.h>
37
38#include "mdp.h"
39#include "msm_fb.h"
40#include "mddihost.h"
41
42#ifdef CONFIG_FB_MSM_MDP40
43#define MDP_SYNC_CFG_0 0x100
44#define MDP_SYNC_STATUS_0 0x10c
45#define MDP_PRIM_VSYNC_OUT_CTRL 0x118
46#define MDP_PRIM_VSYNC_INIT_VAL 0x128
47#else
48#define MDP_SYNC_CFG_0 0x300
49#define MDP_SYNC_STATUS_0 0x30c
50#define MDP_PRIM_VSYNC_OUT_CTRL 0x318
51#define MDP_PRIM_VSYNC_INIT_VAL 0x328
52#endif
53
54extern mddi_lcd_type mddi_lcd_idx;
55extern spinlock_t mdp_spin_lock;
56extern struct workqueue_struct *mdp_vsync_wq;
57extern int lcdc_mode;
58extern int vsync_mode;
59
60#ifdef MDP_HW_VSYNC
61int vsync_above_th = 4;
62int vsync_start_th = 1;
63int vsync_load_cnt;
64
65struct clk *mdp_vsync_clk;
66
67void mdp_hw_vsync_clk_enable(struct msm_fb_data_type *mfd)
68{
69 if (mfd->use_mdp_vsync)
70 clk_enable(mdp_vsync_clk);
71}
72
73void mdp_hw_vsync_clk_disable(struct msm_fb_data_type *mfd)
74{
75 if (mfd->use_mdp_vsync)
76 clk_disable(mdp_vsync_clk);
77}
78#endif
79
80static void mdp_set_vsync(unsigned long data)
81{
82 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
83 struct msm_fb_panel_data *pdata = NULL;
84
85 pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
86
87 if ((pdata) && (pdata->set_vsync_notifier == NULL))
88 return;
89
90 init_timer(&mfd->vsync_resync_timer);
91 mfd->vsync_resync_timer.function = mdp_set_vsync;
92 mfd->vsync_resync_timer.data = data;
93 mfd->vsync_resync_timer.expires =
94 jiffies + mfd->panel_info.lcd.vsync_notifier_period;
95 add_timer(&mfd->vsync_resync_timer);
96
97 if ((mfd->panel_info.lcd.vsync_enable) && (mfd->panel_power_on)
98 && (!mfd->vsync_handler_pending)) {
99 mfd->vsync_handler_pending = TRUE;
100 if (!queue_work(mdp_vsync_wq, &mfd->vsync_resync_worker)) {
101 MSM_FB_INFO
102 ("mdp_set_vsync: can't queue_work! -> needs to increase vsync_resync_timer_duration\n");
103 }
104 } else {
105 MSM_FB_DEBUG
106 ("mdp_set_vsync failed! EN:%d PWR:%d PENDING:%d\n",
107 mfd->panel_info.lcd.vsync_enable, mfd->panel_power_on,
108 mfd->vsync_handler_pending);
109 }
110}
111
112static void mdp_vsync_handler(void *data)
113{
114 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
115
116 if (mfd->use_mdp_vsync) {
117#ifdef MDP_HW_VSYNC
118 if (mfd->panel_power_on)
119 MDP_OUTP(MDP_BASE + MDP_SYNC_STATUS_0, vsync_load_cnt);
120
121 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
122#endif
123 } else {
124 mfd->last_vsync_timetick = ktime_get_real();
125 }
126
127 mfd->vsync_handler_pending = FALSE;
128}
129
130irqreturn_t mdp_hw_vsync_handler_proxy(int irq, void *data)
131{
132 /*
133 * ToDo: tried enabling/disabling GPIO MDP HW VSYNC interrupt
134 * but getting inaccurate timing in mdp_vsync_handler()
135 * disable_irq(MDP_HW_VSYNC_IRQ);
136 */
137 mdp_vsync_handler(data);
138
139 return IRQ_HANDLED;
140}
141
142#ifdef MDP_HW_VSYNC
143static void mdp_set_sync_cfg_0(struct msm_fb_data_type *mfd, int vsync_cnt)
144{
145 unsigned long cfg;
146
147 cfg = mfd->total_lcd_lines - 1;
148 cfg <<= MDP_SYNCFG_HGT_LOC;
149 if (mfd->panel_info.lcd.hw_vsync_mode)
150 cfg |= MDP_SYNCFG_VSYNC_EXT_EN;
151 cfg |= (MDP_SYNCFG_VSYNC_INT_EN | vsync_cnt);
152
153 MDP_OUTP(MDP_BASE + MDP_SYNC_CFG_0, cfg);
154}
155#endif
156
157void mdp_config_vsync(struct msm_fb_data_type *mfd)
158{
159
160 /* vsync on primary lcd only for now */
161 if ((mfd->dest != DISPLAY_LCD) || (mfd->panel_info.pdest != DISPLAY_1)
162 || (!vsync_mode)) {
163 goto err_handle;
164 }
165
166 if (mfd->panel_info.lcd.vsync_enable) {
167 mfd->total_porch_lines = mfd->panel_info.lcd.v_back_porch +
168 mfd->panel_info.lcd.v_front_porch +
169 mfd->panel_info.lcd.v_pulse_width;
170 mfd->total_lcd_lines =
171 mfd->panel_info.yres + mfd->total_porch_lines;
172 mfd->lcd_ref_usec_time =
173 100000000 / mfd->panel_info.lcd.refx100;
174 mfd->vsync_handler_pending = FALSE;
175 mfd->last_vsync_timetick.tv.sec = 0;
176 mfd->last_vsync_timetick.tv.nsec = 0;
177
178#ifdef MDP_HW_VSYNC
179 if (mdp_vsync_clk == NULL)
180 mdp_vsync_clk = clk_get(NULL, "mdp_vsync_clk");
181
182 if (IS_ERR(mdp_vsync_clk)) {
183 printk(KERN_ERR "error: can't get mdp_vsync_clk!\n");
184 mfd->use_mdp_vsync = 0;
185 } else
186 mfd->use_mdp_vsync = 1;
187
188 if (mfd->use_mdp_vsync) {
189 uint32 vsync_cnt_cfg, vsync_cnt_cfg_dem;
190 uint32 mdp_vsync_clk_speed_hz;
191
192 mdp_vsync_clk_speed_hz = clk_get_rate(mdp_vsync_clk);
193
194 if (mdp_vsync_clk_speed_hz == 0) {
195 mfd->use_mdp_vsync = 0;
196 } else {
197 /*
198 * Do this calculation in 2 steps for
199 * rounding uint32 properly.
200 */
201 vsync_cnt_cfg_dem =
202 (mfd->panel_info.lcd.refx100 *
203 mfd->total_lcd_lines) / 100;
204 vsync_cnt_cfg =
205 (mdp_vsync_clk_speed_hz) /
206 vsync_cnt_cfg_dem;
207
208 /* MDP cmd block enable */
209 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
210 FALSE);
211 mdp_hw_vsync_clk_enable(mfd);
212
213 mdp_set_sync_cfg_0(mfd, vsync_cnt_cfg);
214
215 /*
216 * load the last line + 1 to be in the
217 * safety zone
218 */
219 vsync_load_cnt = mfd->panel_info.yres;
220
221 /* line counter init value at the next pulse */
222 MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_INIT_VAL,
223 vsync_load_cnt);
224
225 /*
226 * external vsync source pulse width and
227 * polarity flip
228 */
229 MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_OUT_CTRL,
230 BIT(30) | BIT(0));
231
232
233 /* threshold */
234 MDP_OUTP(MDP_BASE + 0x200,
235 (vsync_above_th << 16) |
236 (vsync_start_th));
237
238 mdp_hw_vsync_clk_disable(mfd);
239 /* MDP cmd block disable */
240 mdp_pipe_ctrl(MDP_CMD_BLOCK,
241 MDP_BLOCK_POWER_OFF, FALSE);
242 }
243 }
244#else
245 mfd->use_mdp_vsync = 0;
246 hrtimer_init(&mfd->dma_hrtimer, CLOCK_MONOTONIC,
247 HRTIMER_MODE_REL);
248 mfd->dma_hrtimer.function = mdp_dma2_vsync_hrtimer_handler;
249 mfd->vsync_width_boundary = vmalloc(mfd->panel_info.xres * 4);
250#endif
251
252 mfd->channel_irq = 0;
253 if (mfd->panel_info.lcd.hw_vsync_mode) {
254 u32 vsync_gpio = mfd->vsync_gpio;
255 u32 ret;
256
257 if (vsync_gpio == -1) {
258 MSM_FB_INFO("vsync_gpio not defined!\n");
259 goto err_handle;
260 }
261
262 ret = gpio_tlmm_config(GPIO_CFG
263 (vsync_gpio,
264 (mfd->use_mdp_vsync) ? 1 : 0,
265 GPIO_INPUT,
266 GPIO_PULL_DOWN,
267 GPIO_2MA),
268 GPIO_ENABLE);
269 if (ret)
270 goto err_handle;
271
272 if (!mfd->use_mdp_vsync) {
273 mfd->channel_irq = MSM_GPIO_TO_INT(vsync_gpio);
274 if (request_irq
275 (mfd->channel_irq,
276 &mdp_hw_vsync_handler_proxy,
277 IRQF_TRIGGER_FALLING, "VSYNC_GPIO",
278 (void *)mfd)) {
279 MSM_FB_INFO
280 ("irq=%d failed! vsync_gpio=%d\n",
281 mfd->channel_irq,
282 vsync_gpio);
283 goto err_handle;
284 }
285 }
286 }
287
288 mdp_set_vsync((unsigned long)mfd);
289 }
290
291 return;
292
293err_handle:
294 if (mfd->vsync_width_boundary)
295 vfree(mfd->vsync_width_boundary);
296 mfd->panel_info.lcd.vsync_enable = FALSE;
297 printk(KERN_ERR "%s: failed!\n", __func__);
298}
299
300void mdp_vsync_resync_workqueue_handler(struct work_struct *work)
301{
302 struct msm_fb_data_type *mfd = NULL;
303 int vsync_fnc_enabled = FALSE;
304 struct msm_fb_panel_data *pdata = NULL;
305
306 mfd = container_of(work, struct msm_fb_data_type, vsync_resync_worker);
307
308 if (mfd) {
309 if (mfd->panel_power_on) {
310 pdata =
311 (struct msm_fb_panel_data *)mfd->pdev->dev.
312 platform_data;
313
314 /*
315 * we need to turn on MDP power if it uses MDP vsync
316 * HW block in SW mode
317 */
318 if ((!mfd->panel_info.lcd.hw_vsync_mode) &&
319 (mfd->use_mdp_vsync) &&
320 (pdata) && (pdata->set_vsync_notifier != NULL)) {
321 /*
322 * enable pwr here since we can't enable it in
323 * vsync callback in isr mode
324 */
325 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
326 FALSE);
327 }
328
329 if (pdata->set_vsync_notifier != NULL) {
330 vsync_fnc_enabled = TRUE;
331 pdata->set_vsync_notifier(mdp_vsync_handler,
332 (void *)mfd);
333 }
334 }
335 }
336
337 if ((mfd) && (!vsync_fnc_enabled))
338 mfd->vsync_handler_pending = FALSE;
339}
340
341boolean mdp_hw_vsync_set_handler(msm_fb_vsync_handler_type handler, void *data)
342{
343 /*
344 * ToDo: tried enabling/disabling GPIO MDP HW VSYNC interrupt
345 * but getting inaccurate timing in mdp_vsync_handler()
346 * enable_irq(MDP_HW_VSYNC_IRQ);
347 */
348
349 return TRUE;
350}
351
352uint32 mdp_get_lcd_line_counter(struct msm_fb_data_type *mfd)
353{
354 uint32 elapsed_usec_time;
355 uint32 lcd_line;
356 ktime_t last_vsync_timetick_local;
357 ktime_t curr_time;
358 unsigned long flag;
359
360 if ((!mfd->panel_info.lcd.vsync_enable) || (!vsync_mode))
361 return 0;
362
363 spin_lock_irqsave(&mdp_spin_lock, flag);
364 last_vsync_timetick_local = mfd->last_vsync_timetick;
365 spin_unlock_irqrestore(&mdp_spin_lock, flag);
366
367 curr_time = ktime_get_real();
368 elapsed_usec_time =
369 ((curr_time.tv.sec - last_vsync_timetick_local.tv.sec) * 1000000) +
370 ((curr_time.tv.nsec - last_vsync_timetick_local.tv.nsec) / 1000);
371
372 elapsed_usec_time = elapsed_usec_time % mfd->lcd_ref_usec_time;
373
374 /* lcd line calculation referencing to line counter = 0 */
375 lcd_line =
376 (elapsed_usec_time * mfd->total_lcd_lines) / mfd->lcd_ref_usec_time;
377
378 /* lcd line adjusment referencing to the actual line counter at vsync */
379 lcd_line =
380 (mfd->total_lcd_lines - mfd->panel_info.lcd.v_back_porch +
381 lcd_line) % (mfd->total_lcd_lines + 1);
382
383 if (lcd_line > mfd->total_lcd_lines) {
384 MSM_FB_INFO
385 ("mdp_get_lcd_line_counter: mdp_lcd_rd_cnt >= mfd->total_lcd_lines error!\n");
386 }
387
388 return lcd_line;
389}
diff --git a/drivers/staging/msm/memory.c b/drivers/staging/msm/memory.c
new file mode 100644
index 000000000000..cc80fdf17d61
--- /dev/null
+++ b/drivers/staging/msm/memory.c
@@ -0,0 +1,214 @@
1/* arch/arm/mach-msm/memory.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
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 */
16
17#include <linux/mm.h>
18#include <linux/mm_types.h>
19#include <linux/bootmem.h>
20#include <linux/module.h>
21#include <asm/pgtable.h>
22#include <asm/io.h>
23#include <asm/mach/map.h>
24#include "memory_ll.h"
25#include <asm/cacheflush.h>
26#if defined(CONFIG_MSM_NPA_REMOTE)
27#include "npa_remote.h"
28#include <linux/completion.h>
29#include <linux/err.h>
30#endif
31
32int arch_io_remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
33 unsigned long pfn, unsigned long size, pgprot_t prot)
34{
35 unsigned long pfn_addr = pfn << PAGE_SHIFT;
36/*
37 if ((pfn_addr >= 0x88000000) && (pfn_addr < 0xD0000000)) {
38 prot = pgprot_device(prot);
39 printk("remapping device %lx\n", prot);
40 }
41*/
42 panic("Memory remap PFN stuff not done\n");
43 return remap_pfn_range(vma, addr, pfn, size, prot);
44}
45
46void *zero_page_strongly_ordered;
47
48static void map_zero_page_strongly_ordered(void)
49{
50 if (zero_page_strongly_ordered)
51 return;
52/*
53 zero_page_strongly_ordered =
54 ioremap_strongly_ordered(page_to_pfn(empty_zero_page)
55 << PAGE_SHIFT, PAGE_SIZE);
56*/
57 panic("Strongly ordered memory functions not implemented\n");
58}
59
60void write_to_strongly_ordered_memory(void)
61{
62 map_zero_page_strongly_ordered();
63 *(int *)zero_page_strongly_ordered = 0;
64}
65EXPORT_SYMBOL(write_to_strongly_ordered_memory);
66
67void flush_axi_bus_buffer(void)
68{
69 __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
70 : : "r" (0) : "memory");
71 write_to_strongly_ordered_memory();
72}
73
74#define CACHE_LINE_SIZE 32
75
76/* These cache related routines make the assumption that the associated
77 * physical memory is contiguous. They will operate on all (L1
78 * and L2 if present) caches.
79 */
80void clean_and_invalidate_caches(unsigned long vstart,
81 unsigned long length, unsigned long pstart)
82{
83 unsigned long vaddr;
84
85 for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE)
86 asm ("mcr p15, 0, %0, c7, c14, 1" : : "r" (vaddr));
87#ifdef CONFIG_OUTER_CACHE
88 outer_flush_range(pstart, pstart + length);
89#endif
90 asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
91 asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
92
93 flush_axi_bus_buffer();
94}
95
96void clean_caches(unsigned long vstart,
97 unsigned long length, unsigned long pstart)
98{
99 unsigned long vaddr;
100
101 for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE)
102 asm ("mcr p15, 0, %0, c7, c10, 1" : : "r" (vaddr));
103#ifdef CONFIG_OUTER_CACHE
104 outer_clean_range(pstart, pstart + length);
105#endif
106 asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
107 asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
108
109 flush_axi_bus_buffer();
110}
111
112void invalidate_caches(unsigned long vstart,
113 unsigned long length, unsigned long pstart)
114{
115 unsigned long vaddr;
116
117 for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE)
118 asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (vaddr));
119#ifdef CONFIG_OUTER_CACHE
120 outer_inv_range(pstart, pstart + length);
121#endif
122 asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
123 asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
124
125 flush_axi_bus_buffer();
126}
127
128void *alloc_bootmem_aligned(unsigned long size, unsigned long alignment)
129{
130 void *unused_addr = NULL;
131 unsigned long addr, tmp_size, unused_size;
132
133 /* Allocate maximum size needed, see where it ends up.
134 * Then free it -- in this path there are no other allocators
135 * so we can depend on getting the same address back
136 * when we allocate a smaller piece that is aligned
137 * at the end (if necessary) and the piece we really want,
138 * then free the unused first piece.
139 */
140
141 tmp_size = size + alignment - PAGE_SIZE;
142 addr = (unsigned long)alloc_bootmem(tmp_size);
143 free_bootmem(__pa(addr), tmp_size);
144
145 unused_size = alignment - (addr % alignment);
146 if (unused_size)
147 unused_addr = alloc_bootmem(unused_size);
148
149 addr = (unsigned long)alloc_bootmem(size);
150 if (unused_size)
151 free_bootmem(__pa(unused_addr), unused_size);
152
153 return (void *)addr;
154}
155
156#if defined(CONFIG_MSM_NPA_REMOTE)
157struct npa_client *npa_memory_client;
158#endif
159
160static int change_memory_power_state(unsigned long start_pfn,
161 unsigned long nr_pages, int state)
162{
163#if defined(CONFIG_MSM_NPA_REMOTE)
164 static atomic_t node_created_flag = ATOMIC_INIT(1);
165#else
166 unsigned long start;
167 unsigned long size;
168 unsigned long virtual;
169#endif
170 int rc = 0;
171
172#if defined(CONFIG_MSM_NPA_REMOTE)
173 if (atomic_dec_and_test(&node_created_flag)) {
174 /* Create NPA 'required' client. */
175 npa_memory_client = npa_create_sync_client(NPA_MEMORY_NODE_NAME,
176 "memory node", NPA_CLIENT_REQUIRED);
177 if (IS_ERR(npa_memory_client)) {
178 rc = PTR_ERR(npa_memory_client);
179 return rc;
180 }
181 }
182
183 rc = npa_issue_required_request(npa_memory_client, state);
184#else
185 if (state == MEMORY_DEEP_POWERDOWN) {
186 /* simulate turning off memory by writing bit pattern into it */
187 start = start_pfn << PAGE_SHIFT;
188 size = nr_pages << PAGE_SHIFT;
189 virtual = __phys_to_virt(start);
190 memset((void *)virtual, 0x27, size);
191 }
192#endif
193 return rc;
194}
195
196int platform_physical_remove_pages(unsigned long start_pfn,
197 unsigned long nr_pages)
198{
199 return change_memory_power_state(start_pfn, nr_pages,
200 MEMORY_DEEP_POWERDOWN);
201}
202
203int platform_physical_add_pages(unsigned long start_pfn,
204 unsigned long nr_pages)
205{
206 return change_memory_power_state(start_pfn, nr_pages, MEMORY_ACTIVE);
207}
208
209int platform_physical_low_power_pages(unsigned long start_pfn,
210 unsigned long nr_pages)
211{
212 return change_memory_power_state(start_pfn, nr_pages,
213 MEMORY_SELF_REFRESH);
214}
diff --git a/drivers/staging/msm/memory_ll.h b/drivers/staging/msm/memory_ll.h
new file mode 100644
index 000000000000..18a239a89a78
--- /dev/null
+++ b/drivers/staging/msm/memory_ll.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
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 */
15#ifndef __ASM_ARCH_MEMORY_LL_H
16#define __ASM_ARCH_MEMORY_LL_H
17
18#define MAX_PHYSMEM_BITS 32
19#define SECTION_SIZE_BITS 25
20
21#define HAS_ARCH_IO_REMAP_PFN_RANGE
22
23#ifndef __ASSEMBLY__
24void *alloc_bootmem_aligned(unsigned long size, unsigned long alignment);
25void clean_and_invalidate_caches(unsigned long, unsigned long, unsigned long);
26void clean_caches(unsigned long, unsigned long, unsigned long);
27void invalidate_caches(unsigned long, unsigned long, unsigned long);
28int platform_physical_remove_pages(unsigned long, unsigned long);
29int platform_physical_add_pages(unsigned long, unsigned long);
30int platform_physical_low_power_pages(unsigned long, unsigned long);
31
32#ifdef CONFIG_ARCH_MSM_ARM11
33void write_to_strongly_ordered_memory(void);
34
35#include <asm/mach-types.h>
36
37#define arch_barrier_extra() do \
38 { if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) \
39 write_to_strongly_ordered_memory(); \
40 } while (0)
41#endif
42
43#ifdef CONFIG_CACHE_L2X0
44extern void l2x0_cache_sync(void);
45#define finish_arch_switch(prev) do { l2x0_cache_sync(); } while (0)
46#endif
47
48#endif
49
50#ifdef CONFIG_ARCH_MSM_SCORPION
51#define arch_has_speculative_dfetch() 1
52#endif
53
54#endif
55
56/* these correspond to values known by the modem */
57#define MEMORY_DEEP_POWERDOWN 0
58#define MEMORY_SELF_REFRESH 1
59#define MEMORY_ACTIVE 2
60
61#define NPA_MEMORY_NODE_NAME "/mem/ebi1/cs1"
diff --git a/drivers/staging/msm/msm_fb.c b/drivers/staging/msm/msm_fb.c
new file mode 100644
index 000000000000..af5620e4eee1
--- /dev/null
+++ b/drivers/staging/msm/msm_fb.c
@@ -0,0 +1,2354 @@
1/*
2 *
3 * Core MSM framebuffer driver.
4 *
5 * Copyright (C) 2007 Google Incorporated
6 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
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
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/mm.h>
24#include <linux/fb.h>
25#include "msm_mdp.h"
26#include <linux/init.h>
27#include <linux/ioport.h>
28#include <linux/device.h>
29#include <linux/dma-mapping.h>
30#include <mach/board.h>
31#include <linux/uaccess.h>
32
33#include <linux/workqueue.h>
34#include <linux/string.h>
35#include <linux/version.h>
36#include <linux/proc_fs.h>
37#include <linux/vmalloc.h>
38#include <linux/debugfs.h>
39#include <linux/console.h>
40#include <linux/leds.h>
41#include <asm/dma-mapping.h>
42
43
44#define MSM_FB_C
45#include "msm_fb.h"
46#include "mddihosti.h"
47#include "tvenc.h"
48#include "mdp.h"
49#include "mdp4.h"
50
51#ifdef CONFIG_FB_MSM_LOGO
52#define INIT_IMAGE_FILE "/logo.rle"
53extern int load_565rle_image(char *filename);
54#endif
55
56
57#define pgprot_noncached(prot) \
58 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
59#define pgprot_writecombine(prot) \
60 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
61#define pgprot_device(prot) \
62 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_DEV_NONSHARED)
63#define pgprot_writethroughcache(prot) \
64 __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITETHROUGH)
65#define pgprot_writebackcache(prot) \
66 __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITEBACK)
67#define pgprot_writebackwacache(prot) \
68 __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITEALLOC)
69
70static unsigned char *fbram;
71static unsigned char *fbram_phys;
72static int fbram_size;
73
74static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
75static int pdev_list_cnt;
76
77int vsync_mode = 1;
78
79#define MAX_FBI_LIST 32
80static struct fb_info *fbi_list[MAX_FBI_LIST];
81static int fbi_list_index;
82
83static struct msm_fb_data_type *mfd_list[MAX_FBI_LIST];
84static int mfd_list_index;
85
86static u32 msm_fb_pseudo_palette[16] = {
87 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
88 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
89 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
90 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
91};
92
93u32 msm_fb_debug_enabled;
94/* Setting msm_fb_msg_level to 8 prints out ALL messages */
95u32 msm_fb_msg_level = 7;
96
97/* Setting mddi_msg_level to 8 prints out ALL messages */
98u32 mddi_msg_level = 5;
99
100extern int32 mdp_block_power_cnt[MDP_MAX_BLOCK];
101extern unsigned long mdp_timer_duration;
102
103static int msm_fb_register(struct msm_fb_data_type *mfd);
104static int msm_fb_open(struct fb_info *info, int user);
105static int msm_fb_release(struct fb_info *info, int user);
106static int msm_fb_pan_display(struct fb_var_screeninfo *var,
107 struct fb_info *info);
108static int msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd);
109int msm_fb_resume_sw_refresher(struct msm_fb_data_type *mfd);
110static int msm_fb_check_var(struct fb_var_screeninfo *var,
111 struct fb_info *info);
112static int msm_fb_set_par(struct fb_info *info);
113static int msm_fb_blank_sub(int blank_mode, struct fb_info *info,
114 boolean op_enable);
115static int msm_fb_suspend_sub(struct msm_fb_data_type *mfd);
116static int msm_fb_resume_sub(struct msm_fb_data_type *mfd);
117static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd,
118 unsigned long arg);
119static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma);
120
121#ifdef MSM_FB_ENABLE_DBGFS
122
123#define MSM_FB_MAX_DBGFS 1024
124#define MAX_BACKLIGHT_BRIGHTNESS 255
125
126int msm_fb_debugfs_file_index;
127struct dentry *msm_fb_debugfs_root;
128struct dentry *msm_fb_debugfs_file[MSM_FB_MAX_DBGFS];
129
130struct dentry *msm_fb_get_debugfs_root(void)
131{
132 if (msm_fb_debugfs_root == NULL)
133 msm_fb_debugfs_root = debugfs_create_dir("msm_fb", NULL);
134
135 return msm_fb_debugfs_root;
136}
137
138void msm_fb_debugfs_file_create(struct dentry *root, const char *name,
139 u32 *var)
140{
141 if (msm_fb_debugfs_file_index >= MSM_FB_MAX_DBGFS)
142 return;
143
144 msm_fb_debugfs_file[msm_fb_debugfs_file_index++] =
145 debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
146}
147#endif
148
149int msm_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
150{
151 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
152
153 if (!mfd->cursor_update)
154 return -ENODEV;
155
156 return mfd->cursor_update(info, cursor);
157}
158
159static int msm_fb_resource_initialized;
160
161#ifndef CONFIG_FB_BACKLIGHT
162static int lcd_backlight_registered;
163
164static void msm_fb_set_bl_brightness(struct led_classdev *led_cdev,
165 enum led_brightness value)
166{
167 struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent);
168 int bl_lvl;
169
170 if (value > MAX_BACKLIGHT_BRIGHTNESS)
171 value = MAX_BACKLIGHT_BRIGHTNESS;
172
173 /* This maps android backlight level 0 to 255 into
174 driver backlight level 0 to bl_max with rounding */
175 bl_lvl = (2 * value * mfd->panel_info.bl_max + MAX_BACKLIGHT_BRIGHTNESS)
176 /(2 * MAX_BACKLIGHT_BRIGHTNESS);
177
178 if (!bl_lvl && value)
179 bl_lvl = 1;
180
181 msm_fb_set_backlight(mfd, bl_lvl, 1);
182}
183
184static struct led_classdev backlight_led = {
185 .name = "lcd-backlight",
186 .brightness = MAX_BACKLIGHT_BRIGHTNESS,
187 .brightness_set = msm_fb_set_bl_brightness,
188};
189#endif
190
191static struct msm_fb_platform_data *msm_fb_pdata;
192
193int msm_fb_detect_client(const char *name)
194{
195 int ret = -EPERM;
196#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
197 u32 id;
198#endif
199
200 if (msm_fb_pdata && msm_fb_pdata->detect_client) {
201 ret = msm_fb_pdata->detect_client(name);
202
203 /* if it's non mddi panel, we need to pre-scan
204 mddi client to see if we can disable mddi host */
205
206#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
207 if (!ret && msm_fb_pdata->mddi_prescan)
208 id = mddi_get_client_id();
209#endif
210 }
211
212 return ret;
213}
214
215static int msm_fb_probe(struct platform_device *pdev)
216{
217 struct msm_fb_data_type *mfd;
218 int rc;
219
220 MSM_FB_DEBUG("msm_fb_probe\n");
221
222 if ((pdev->id == 0) && (pdev->num_resources > 0)) {
223 msm_fb_pdata = pdev->dev.platform_data;
224 fbram_size =
225 pdev->resource[0].end - pdev->resource[0].start + 1;
226 fbram_phys = (char *)pdev->resource[0].start;
227 fbram = ioremap((unsigned long)fbram_phys, fbram_size);
228
229 if (!fbram) {
230 printk(KERN_ERR "fbram ioremap failed!\n");
231 return -ENOMEM;
232 }
233 MSM_FB_INFO("msm_fb_probe: phy_Addr = 0x%x virt = 0x%x\n",
234 (int)fbram_phys, (int)fbram);
235
236 msm_fb_resource_initialized = 1;
237 return 0;
238 }
239
240 if (!msm_fb_resource_initialized)
241 return -EPERM;
242
243 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
244
245 if (!mfd)
246 return -ENODEV;
247
248 if (mfd->key != MFD_KEY)
249 return -EINVAL;
250
251 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
252 return -ENOMEM;
253
254 mfd->panel_info.frame_count = 0;
255 mfd->bl_level = mfd->panel_info.bl_max;
256
257 if (mfd->panel_info.type == LCDC_PANEL)
258 mfd->allow_set_offset =
259 msm_fb_pdata->allow_set_offset != NULL ?
260 msm_fb_pdata->allow_set_offset() : 0;
261 else
262 mfd->allow_set_offset = 0;
263
264 rc = msm_fb_register(mfd);
265 if (rc)
266 return rc;
267
268#ifdef CONFIG_FB_BACKLIGHT
269 msm_fb_config_backlight(mfd);
270#else
271 /* android supports only one lcd-backlight/lcd for now */
272 if (!lcd_backlight_registered) {
273 if (led_classdev_register(&pdev->dev, &backlight_led))
274 printk(KERN_ERR "led_classdev_register failed\n");
275 else
276 lcd_backlight_registered = 1;
277 }
278#endif
279
280 pdev_list[pdev_list_cnt++] = pdev;
281 return 0;
282}
283
284static int msm_fb_remove(struct platform_device *pdev)
285{
286 struct msm_fb_data_type *mfd;
287
288 MSM_FB_DEBUG("msm_fb_remove\n");
289
290 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
291
292 if (!mfd)
293 return -ENODEV;
294
295 if (mfd->key != MFD_KEY)
296 return -EINVAL;
297
298 if (msm_fb_suspend_sub(mfd))
299 printk(KERN_ERR "msm_fb_remove: can't stop the device %d\n", mfd->index);
300
301 if (mfd->channel_irq != 0)
302 free_irq(mfd->channel_irq, (void *)mfd);
303
304 if (mfd->vsync_width_boundary)
305 vfree(mfd->vsync_width_boundary);
306
307 if (mfd->vsync_resync_timer.function)
308 del_timer(&mfd->vsync_resync_timer);
309
310 if (mfd->refresh_timer.function)
311 del_timer(&mfd->refresh_timer);
312
313 if (mfd->dma_hrtimer.function)
314 hrtimer_cancel(&mfd->dma_hrtimer);
315
316 /* remove /dev/fb* */
317 unregister_framebuffer(mfd->fbi);
318
319#ifdef CONFIG_FB_BACKLIGHT
320 /* remove /sys/class/backlight */
321 backlight_device_unregister(mfd->fbi->bl_dev);
322#else
323 if (lcd_backlight_registered) {
324 lcd_backlight_registered = 0;
325 led_classdev_unregister(&backlight_led);
326 }
327#endif
328
329#ifdef MSM_FB_ENABLE_DBGFS
330 if (mfd->sub_dir)
331 debugfs_remove(mfd->sub_dir);
332#endif
333
334 return 0;
335}
336
337#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
338static int msm_fb_suspend(struct platform_device *pdev, pm_message_t state)
339{
340 struct msm_fb_data_type *mfd;
341 int ret = 0;
342
343 MSM_FB_DEBUG("msm_fb_suspend\n");
344
345 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
346
347 if ((!mfd) || (mfd->key != MFD_KEY))
348 return 0;
349
350 acquire_console_sem();
351 fb_set_suspend(mfd->fbi, 1);
352
353 ret = msm_fb_suspend_sub(mfd);
354 if (ret != 0) {
355 printk(KERN_ERR "msm_fb: failed to suspend! %d\n", ret);
356 fb_set_suspend(mfd->fbi, 0);
357 } else {
358 pdev->dev.power.power_state = state;
359 }
360
361 release_console_sem();
362 return ret;
363}
364#else
365#define msm_fb_suspend NULL
366#endif
367
368static int msm_fb_suspend_sub(struct msm_fb_data_type *mfd)
369{
370 int ret = 0;
371
372 if ((!mfd) || (mfd->key != MFD_KEY))
373 return 0;
374
375 /*
376 * suspend this channel
377 */
378 mfd->suspend.sw_refreshing_enable = mfd->sw_refreshing_enable;
379 mfd->suspend.op_enable = mfd->op_enable;
380 mfd->suspend.panel_power_on = mfd->panel_power_on;
381
382 if (mfd->op_enable) {
383 ret =
384 msm_fb_blank_sub(FB_BLANK_POWERDOWN, mfd->fbi,
385 mfd->suspend.op_enable);
386 if (ret) {
387 MSM_FB_INFO
388 ("msm_fb_suspend: can't turn off display!\n");
389 return ret;
390 }
391 mfd->op_enable = FALSE;
392 }
393 /*
394 * try to power down
395 */
396 mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
397
398 /*
399 * detach display channel irq if there's any
400 * or wait until vsync-resync completes
401 */
402 if ((mfd->dest == DISPLAY_LCD)) {
403 if (mfd->panel_info.lcd.vsync_enable) {
404 if (mfd->panel_info.lcd.hw_vsync_mode) {
405 if (mfd->channel_irq != 0)
406 disable_irq(mfd->channel_irq);
407 } else {
408 volatile boolean vh_pending;
409 do {
410 vh_pending = mfd->vsync_handler_pending;
411 } while (vh_pending);
412 }
413 }
414 }
415
416 return 0;
417}
418
419#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
420static int msm_fb_resume(struct platform_device *pdev)
421{
422 /* This resume function is called when interrupt is enabled.
423 */
424 int ret = 0;
425 struct msm_fb_data_type *mfd;
426
427 MSM_FB_DEBUG("msm_fb_resume\n");
428
429 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
430
431 if ((!mfd) || (mfd->key != MFD_KEY))
432 return 0;
433
434 acquire_console_sem();
435 ret = msm_fb_resume_sub(mfd);
436 pdev->dev.power.power_state = PMSG_ON;
437 fb_set_suspend(mfd->fbi, 1);
438 release_console_sem();
439
440 return ret;
441}
442#else
443#define msm_fb_resume NULL
444#endif
445
446static int msm_fb_resume_sub(struct msm_fb_data_type *mfd)
447{
448 int ret = 0;
449
450 if ((!mfd) || (mfd->key != MFD_KEY))
451 return 0;
452
453 /* attach display channel irq if there's any */
454 if (mfd->channel_irq != 0)
455 enable_irq(mfd->channel_irq);
456
457 /* resume state var recover */
458 mfd->sw_refreshing_enable = mfd->suspend.sw_refreshing_enable;
459 mfd->op_enable = mfd->suspend.op_enable;
460
461 if (mfd->suspend.panel_power_on) {
462 ret =
463 msm_fb_blank_sub(FB_BLANK_UNBLANK, mfd->fbi,
464 mfd->op_enable);
465 if (ret)
466 MSM_FB_INFO("msm_fb_resume: can't turn on display!\n");
467 }
468
469 return ret;
470}
471
472static struct platform_driver msm_fb_driver = {
473 .probe = msm_fb_probe,
474 .remove = msm_fb_remove,
475#ifndef CONFIG_HAS_EARLYSUSPEND
476 .suspend = msm_fb_suspend,
477 .resume = msm_fb_resume,
478#endif
479 .shutdown = NULL,
480 .driver = {
481 /* Driver name must match the device name added in platform.c. */
482 .name = "msm_fb",
483 },
484};
485
486#ifdef CONFIG_HAS_EARLYSUSPEND
487static void msmfb_early_suspend(struct early_suspend *h)
488{
489 struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
490 early_suspend);
491 msm_fb_suspend_sub(mfd);
492}
493
494static void msmfb_early_resume(struct early_suspend *h)
495{
496 struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
497 early_suspend);
498 msm_fb_resume_sub(mfd);
499}
500#endif
501
502void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl, u32 save)
503{
504 struct msm_fb_panel_data *pdata;
505
506 pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
507
508 if ((pdata) && (pdata->set_backlight)) {
509 down(&mfd->sem);
510 if ((bkl_lvl != mfd->bl_level) || (!save)) {
511 u32 old_lvl;
512
513 old_lvl = mfd->bl_level;
514 mfd->bl_level = bkl_lvl;
515 pdata->set_backlight(mfd);
516
517 if (!save)
518 mfd->bl_level = old_lvl;
519 }
520 up(&mfd->sem);
521 }
522}
523
524static int msm_fb_blank_sub(int blank_mode, struct fb_info *info,
525 boolean op_enable)
526{
527 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
528 struct msm_fb_panel_data *pdata = NULL;
529 int ret = 0;
530
531 if (!op_enable)
532 return -EPERM;
533
534 pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
535 if ((!pdata) || (!pdata->on) || (!pdata->off)) {
536 printk(KERN_ERR "msm_fb_blank_sub: no panel operation detected!\n");
537 return -ENODEV;
538 }
539
540 switch (blank_mode) {
541 case FB_BLANK_UNBLANK:
542 if (!mfd->panel_power_on) {
543 mdelay(100);
544 ret = pdata->on(mfd->pdev);
545 if (ret == 0) {
546 mfd->panel_power_on = TRUE;
547
548 msm_fb_set_backlight(mfd,
549 mfd->bl_level, 0);
550
551/* ToDo: possible conflict with android which doesn't expect sw refresher */
552/*
553 if (!mfd->hw_refresh)
554 {
555 if ((ret = msm_fb_resume_sw_refresher(mfd)) != 0)
556 {
557 MSM_FB_INFO("msm_fb_blank_sub: msm_fb_resume_sw_refresher failed = %d!\n",ret);
558 }
559 }
560*/
561 }
562 }
563 break;
564
565 case FB_BLANK_VSYNC_SUSPEND:
566 case FB_BLANK_HSYNC_SUSPEND:
567 case FB_BLANK_NORMAL:
568 case FB_BLANK_POWERDOWN:
569 default:
570 if (mfd->panel_power_on) {
571 int curr_pwr_state;
572
573 mfd->op_enable = FALSE;
574 curr_pwr_state = mfd->panel_power_on;
575 mfd->panel_power_on = FALSE;
576
577 mdelay(100);
578 ret = pdata->off(mfd->pdev);
579 if (ret)
580 mfd->panel_power_on = curr_pwr_state;
581
582 msm_fb_set_backlight(mfd, 0, 0);
583 mfd->op_enable = TRUE;
584 }
585 break;
586 }
587
588 return ret;
589}
590
591static void msm_fb_fillrect(struct fb_info *info,
592 const struct fb_fillrect *rect)
593{
594 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
595
596 cfb_fillrect(info, rect);
597 if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
598 !mfd->sw_currently_refreshing) {
599 struct fb_var_screeninfo var;
600
601 var = info->var;
602 var.reserved[0] = 0x54445055;
603 var.reserved[1] = (rect->dy << 16) | (rect->dx);
604 var.reserved[2] = ((rect->dy + rect->height) << 16) |
605 (rect->dx + rect->width);
606
607 msm_fb_pan_display(&var, info);
608 }
609}
610
611static void msm_fb_copyarea(struct fb_info *info,
612 const struct fb_copyarea *area)
613{
614 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
615
616 cfb_copyarea(info, area);
617 if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
618 !mfd->sw_currently_refreshing) {
619 struct fb_var_screeninfo var;
620
621 var = info->var;
622 var.reserved[0] = 0x54445055;
623 var.reserved[1] = (area->dy << 16) | (area->dx);
624 var.reserved[2] = ((area->dy + area->height) << 16) |
625 (area->dx + area->width);
626
627 msm_fb_pan_display(&var, info);
628 }
629}
630
631static void msm_fb_imageblit(struct fb_info *info, const struct fb_image *image)
632{
633 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
634
635 cfb_imageblit(info, image);
636 if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
637 !mfd->sw_currently_refreshing) {
638 struct fb_var_screeninfo var;
639
640 var = info->var;
641 var.reserved[0] = 0x54445055;
642 var.reserved[1] = (image->dy << 16) | (image->dx);
643 var.reserved[2] = ((image->dy + image->height) << 16) |
644 (image->dx + image->width);
645
646 msm_fb_pan_display(&var, info);
647 }
648}
649
650static int msm_fb_blank(int blank_mode, struct fb_info *info)
651{
652 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
653 return msm_fb_blank_sub(blank_mode, info, mfd->op_enable);
654}
655
656static int msm_fb_set_lut(struct fb_cmap *cmap, struct fb_info *info)
657{
658 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
659
660 if (!mfd->lut_update)
661 return -ENODEV;
662
663 mfd->lut_update(info, cmap);
664 return 0;
665}
666
667/*
668 * Custom Framebuffer mmap() function for MSM driver.
669 * Differs from standard mmap() function by allowing for customized
670 * page-protection.
671 */
672static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma)
673{
674 /* Get frame buffer memory range. */
675 unsigned long start = info->fix.smem_start;
676 u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
677 unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
678 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
679 if (off >= len) {
680 /* memory mapped io */
681 off -= len;
682 if (info->var.accel_flags) {
683 mutex_unlock(&info->lock);
684 return -EINVAL;
685 }
686 start = info->fix.mmio_start;
687 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
688 }
689
690 /* Set VM flags. */
691 start &= PAGE_MASK;
692 if ((vma->vm_end - vma->vm_start + off) > len)
693 return -EINVAL;
694 off += start;
695 vma->vm_pgoff = off >> PAGE_SHIFT;
696 /* This is an IO map - tell maydump to skip this VMA */
697 vma->vm_flags |= VM_IO | VM_RESERVED;
698
699 /* Set VM page protection */
700 if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
701 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
702 else if (mfd->mdp_fb_page_protection ==
703 MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE)
704 vma->vm_page_prot = pgprot_writethroughcache(vma->vm_page_prot);
705 else if (mfd->mdp_fb_page_protection ==
706 MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE)
707 vma->vm_page_prot = pgprot_writebackcache(vma->vm_page_prot);
708 else if (mfd->mdp_fb_page_protection ==
709 MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE)
710 vma->vm_page_prot = pgprot_writebackwacache(vma->vm_page_prot);
711 else
712 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
713
714 /* Remap the frame buffer I/O range */
715 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
716 vma->vm_end - vma->vm_start,
717 vma->vm_page_prot))
718 return -EAGAIN;
719
720 return 0;
721}
722
723static struct fb_ops msm_fb_ops = {
724 .owner = THIS_MODULE,
725 .fb_open = msm_fb_open,
726 .fb_release = msm_fb_release,
727 .fb_read = NULL,
728 .fb_write = NULL,
729 .fb_cursor = NULL,
730 .fb_check_var = msm_fb_check_var, /* vinfo check */
731 .fb_set_par = msm_fb_set_par, /* set the video mode according to info->var */
732 .fb_setcolreg = NULL, /* set color register */
733 .fb_blank = msm_fb_blank, /* blank display */
734 .fb_pan_display = msm_fb_pan_display, /* pan display */
735 .fb_fillrect = msm_fb_fillrect, /* Draws a rectangle */
736 .fb_copyarea = msm_fb_copyarea, /* Copy data from area to another */
737 .fb_imageblit = msm_fb_imageblit, /* Draws a image to the display */
738 .fb_rotate = NULL,
739 .fb_sync = NULL, /* wait for blit idle, optional */
740 .fb_ioctl = msm_fb_ioctl, /* perform fb specific ioctl (optional) */
741 .fb_mmap = msm_fb_mmap,
742};
743
744static int msm_fb_register(struct msm_fb_data_type *mfd)
745{
746 int ret = -ENODEV;
747 int bpp;
748 struct msm_panel_info *panel_info = &mfd->panel_info;
749 struct fb_info *fbi = mfd->fbi;
750 struct fb_fix_screeninfo *fix;
751 struct fb_var_screeninfo *var;
752 int *id;
753 int fbram_offset;
754
755 /*
756 * fb info initialization
757 */
758 fix = &fbi->fix;
759 var = &fbi->var;
760
761 fix->type_aux = 0; /* if type == FB_TYPE_INTERLEAVED_PLANES */
762 fix->visual = FB_VISUAL_TRUECOLOR; /* True Color */
763 fix->ywrapstep = 0; /* No support */
764 fix->mmio_start = 0; /* No MMIO Address */
765 fix->mmio_len = 0; /* No MMIO Address */
766 fix->accel = FB_ACCEL_NONE;/* FB_ACCEL_MSM needes to be added in fb.h */
767
768 var->xoffset = 0, /* Offset from virtual to visible */
769 var->yoffset = 0, /* resolution */
770 var->grayscale = 0, /* No graylevels */
771 var->nonstd = 0, /* standard pixel format */
772 var->activate = FB_ACTIVATE_VBL, /* activate it at vsync */
773 var->height = -1, /* height of picture in mm */
774 var->width = -1, /* width of picture in mm */
775 var->accel_flags = 0, /* acceleration flags */
776 var->sync = 0, /* see FB_SYNC_* */
777 var->rotate = 0, /* angle we rotate counter clockwise */
778 mfd->op_enable = FALSE;
779
780 switch (mfd->fb_imgType) {
781 case MDP_RGB_565:
782 fix->type = FB_TYPE_PACKED_PIXELS;
783 fix->xpanstep = 1;
784 fix->ypanstep = 1;
785 var->vmode = FB_VMODE_NONINTERLACED;
786 var->blue.offset = 0;
787 var->green.offset = 5;
788 var->red.offset = 11;
789 var->blue.length = 5;
790 var->green.length = 6;
791 var->red.length = 5;
792 var->blue.msb_right = 0;
793 var->green.msb_right = 0;
794 var->red.msb_right = 0;
795 var->transp.offset = 0;
796 var->transp.length = 0;
797 bpp = 2;
798 break;
799
800 case MDP_RGB_888:
801 fix->type = FB_TYPE_PACKED_PIXELS;
802 fix->xpanstep = 1;
803 fix->ypanstep = 1;
804 var->vmode = FB_VMODE_NONINTERLACED;
805 var->blue.offset = 0;
806 var->green.offset = 8;
807 var->red.offset = 16;
808 var->blue.length = 8;
809 var->green.length = 8;
810 var->red.length = 8;
811 var->blue.msb_right = 0;
812 var->green.msb_right = 0;
813 var->red.msb_right = 0;
814 var->transp.offset = 0;
815 var->transp.length = 0;
816 bpp = 3;
817 break;
818
819 case MDP_ARGB_8888:
820 fix->type = FB_TYPE_PACKED_PIXELS;
821 fix->xpanstep = 1;
822 fix->ypanstep = 1;
823 var->vmode = FB_VMODE_NONINTERLACED;
824 var->blue.offset = 0;
825 var->green.offset = 8;
826 var->red.offset = 16;
827 var->blue.length = 8;
828 var->green.length = 8;
829 var->red.length = 8;
830 var->blue.msb_right = 0;
831 var->green.msb_right = 0;
832 var->red.msb_right = 0;
833 var->transp.offset = 24;
834 var->transp.length = 8;
835 bpp = 3;
836 break;
837
838 case MDP_YCRYCB_H2V1:
839 /* ToDo: need to check TV-Out YUV422i framebuffer format */
840 /* we might need to create new type define */
841 fix->type = FB_TYPE_INTERLEAVED_PLANES;
842 fix->xpanstep = 2;
843 fix->ypanstep = 1;
844 var->vmode = FB_VMODE_NONINTERLACED;
845
846 /* how about R/G/B offset? */
847 var->blue.offset = 0;
848 var->green.offset = 5;
849 var->red.offset = 11;
850 var->blue.length = 5;
851 var->green.length = 6;
852 var->red.length = 5;
853 var->blue.msb_right = 0;
854 var->green.msb_right = 0;
855 var->red.msb_right = 0;
856 var->transp.offset = 0;
857 var->transp.length = 0;
858 bpp = 2;
859 break;
860
861 default:
862 MSM_FB_ERR("msm_fb_init: fb %d unkown image type!\n",
863 mfd->index);
864 return ret;
865 }
866
867 /* The adreno GPU hardware requires that the pitch be aligned to
868 32 pixels for color buffers, so for the cases where the GPU
869 is writing directly to fb0, the framebuffer pitch
870 also needs to be 32 pixel aligned */
871
872 if (mfd->index == 0)
873 fix->line_length = ALIGN(panel_info->xres * bpp, 32);
874 else
875 fix->line_length = panel_info->xres * bpp;
876
877 fix->smem_len = fix->line_length * panel_info->yres * mfd->fb_page;
878
879 mfd->var_xres = panel_info->xres;
880 mfd->var_yres = panel_info->yres;
881
882 var->pixclock = mfd->panel_info.clk_rate;
883 mfd->var_pixclock = var->pixclock;
884
885 var->xres = panel_info->xres;
886 var->yres = panel_info->yres;
887 var->xres_virtual = panel_info->xres;
888 var->yres_virtual = panel_info->yres * mfd->fb_page;
889 var->bits_per_pixel = bpp * 8, /* FrameBuffer color depth */
890 /*
891 * id field for fb app
892 */
893 id = (int *)&mfd->panel;
894
895#if defined(CONFIG_FB_MSM_MDP22)
896 snprintf(fix->id, sizeof(fix->id), "msmfb22_%x", (__u32) *id);
897#elif defined(CONFIG_FB_MSM_MDP30)
898 snprintf(fix->id, sizeof(fix->id), "msmfb30_%x", (__u32) *id);
899#elif defined(CONFIG_FB_MSM_MDP31)
900 snprintf(fix->id, sizeof(fix->id), "msmfb31_%x", (__u32) *id);
901#elif defined(CONFIG_FB_MSM_MDP40)
902 snprintf(fix->id, sizeof(fix->id), "msmfb40_%x", (__u32) *id);
903#else
904 error CONFIG_FB_MSM_MDP undefined !
905#endif
906 fbi->fbops = &msm_fb_ops;
907 fbi->flags = FBINFO_FLAG_DEFAULT;
908 fbi->pseudo_palette = msm_fb_pseudo_palette;
909
910 mfd->ref_cnt = 0;
911 mfd->sw_currently_refreshing = FALSE;
912 mfd->sw_refreshing_enable = TRUE;
913 mfd->panel_power_on = FALSE;
914
915 mfd->pan_waiting = FALSE;
916 init_completion(&mfd->pan_comp);
917 init_completion(&mfd->refresher_comp);
918 init_MUTEX(&mfd->sem);
919
920 fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
921 fbram += fbram_offset;
922 fbram_phys += fbram_offset;
923 fbram_size -= fbram_offset;
924
925 if (fbram_size < fix->smem_len) {
926 printk(KERN_ERR "error: no more framebuffer memory!\n");
927 return -ENOMEM;
928 }
929
930 fbi->screen_base = fbram;
931 fbi->fix.smem_start = (unsigned long)fbram_phys;
932
933 memset(fbi->screen_base, 0x0, fix->smem_len);
934
935 mfd->op_enable = TRUE;
936 mfd->panel_power_on = FALSE;
937
938 /* cursor memory allocation */
939 if (mfd->cursor_update) {
940 mfd->cursor_buf = dma_alloc_coherent(NULL,
941 MDP_CURSOR_SIZE,
942 (dma_addr_t *) &mfd->cursor_buf_phys,
943 GFP_KERNEL);
944 if (!mfd->cursor_buf)
945 mfd->cursor_update = 0;
946 }
947
948 if (mfd->lut_update) {
949 ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
950 if (ret)
951 printk(KERN_ERR "%s: fb_alloc_cmap() failed!\n",
952 __func__);
953 }
954
955 if (register_framebuffer(fbi) < 0) {
956 if (mfd->lut_update)
957 fb_dealloc_cmap(&fbi->cmap);
958
959 if (mfd->cursor_buf)
960 dma_free_coherent(NULL,
961 MDP_CURSOR_SIZE,
962 mfd->cursor_buf,
963 (dma_addr_t) mfd->cursor_buf_phys);
964
965 mfd->op_enable = FALSE;
966 return -EPERM;
967 }
968
969 fbram += fix->smem_len;
970 fbram_phys += fix->smem_len;
971 fbram_size -= fix->smem_len;
972
973 MSM_FB_INFO
974 ("FrameBuffer[%d] %dx%d size=%d bytes is registered successfully!\n",
975 mfd->index, fbi->var.xres, fbi->var.yres, fbi->fix.smem_len);
976
977#ifdef CONFIG_FB_MSM_LOGO
978 if (!load_565rle_image(INIT_IMAGE_FILE)) ; /* Flip buffer */
979#endif
980 ret = 0;
981
982#ifdef CONFIG_HAS_EARLYSUSPEND
983 mfd->early_suspend.suspend = msmfb_early_suspend;
984 mfd->early_suspend.resume = msmfb_early_resume;
985 mfd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2;
986 register_early_suspend(&mfd->early_suspend);
987#endif
988
989#ifdef MSM_FB_ENABLE_DBGFS
990 {
991 struct dentry *root;
992 struct dentry *sub_dir;
993 char sub_name[2];
994
995 root = msm_fb_get_debugfs_root();
996 if (root != NULL) {
997 sub_name[0] = (char)(mfd->index + 0x30);
998 sub_name[1] = '\0';
999 sub_dir = debugfs_create_dir(sub_name, root);
1000 } else {
1001 sub_dir = NULL;
1002 }
1003
1004 mfd->sub_dir = sub_dir;
1005
1006 if (sub_dir) {
1007 msm_fb_debugfs_file_create(sub_dir, "op_enable",
1008 (u32 *) &mfd->op_enable);
1009 msm_fb_debugfs_file_create(sub_dir, "panel_power_on",
1010 (u32 *) &mfd->
1011 panel_power_on);
1012 msm_fb_debugfs_file_create(sub_dir, "ref_cnt",
1013 (u32 *) &mfd->ref_cnt);
1014 msm_fb_debugfs_file_create(sub_dir, "fb_imgType",
1015 (u32 *) &mfd->fb_imgType);
1016 msm_fb_debugfs_file_create(sub_dir,
1017 "sw_currently_refreshing",
1018 (u32 *) &mfd->
1019 sw_currently_refreshing);
1020 msm_fb_debugfs_file_create(sub_dir,
1021 "sw_refreshing_enable",
1022 (u32 *) &mfd->
1023 sw_refreshing_enable);
1024
1025 msm_fb_debugfs_file_create(sub_dir, "xres",
1026 (u32 *) &mfd->panel_info.
1027 xres);
1028 msm_fb_debugfs_file_create(sub_dir, "yres",
1029 (u32 *) &mfd->panel_info.
1030 yres);
1031 msm_fb_debugfs_file_create(sub_dir, "bpp",
1032 (u32 *) &mfd->panel_info.
1033 bpp);
1034 msm_fb_debugfs_file_create(sub_dir, "type",
1035 (u32 *) &mfd->panel_info.
1036 type);
1037 msm_fb_debugfs_file_create(sub_dir, "wait_cycle",
1038 (u32 *) &mfd->panel_info.
1039 wait_cycle);
1040 msm_fb_debugfs_file_create(sub_dir, "pdest",
1041 (u32 *) &mfd->panel_info.
1042 pdest);
1043 msm_fb_debugfs_file_create(sub_dir, "backbuff",
1044 (u32 *) &mfd->panel_info.
1045 fb_num);
1046 msm_fb_debugfs_file_create(sub_dir, "clk_rate",
1047 (u32 *) &mfd->panel_info.
1048 clk_rate);
1049 msm_fb_debugfs_file_create(sub_dir, "frame_count",
1050 (u32 *) &mfd->panel_info.
1051 frame_count);
1052
1053
1054 switch (mfd->dest) {
1055 case DISPLAY_LCD:
1056 msm_fb_debugfs_file_create(sub_dir,
1057 "vsync_enable",
1058 (u32 *)&mfd->panel_info.lcd.vsync_enable);
1059 msm_fb_debugfs_file_create(sub_dir,
1060 "refx100",
1061 (u32 *) &mfd->panel_info.lcd. refx100);
1062 msm_fb_debugfs_file_create(sub_dir,
1063 "v_back_porch",
1064 (u32 *) &mfd->panel_info.lcd.v_back_porch);
1065 msm_fb_debugfs_file_create(sub_dir,
1066 "v_front_porch",
1067 (u32 *) &mfd->panel_info.lcd.v_front_porch);
1068 msm_fb_debugfs_file_create(sub_dir,
1069 "v_pulse_width",
1070 (u32 *) &mfd->panel_info.lcd.v_pulse_width);
1071 msm_fb_debugfs_file_create(sub_dir,
1072 "hw_vsync_mode",
1073 (u32 *) &mfd->panel_info.lcd.hw_vsync_mode);
1074 msm_fb_debugfs_file_create(sub_dir,
1075 "vsync_notifier_period", (u32 *)
1076 &mfd->panel_info.lcd.vsync_notifier_period);
1077 break;
1078
1079 case DISPLAY_LCDC:
1080 msm_fb_debugfs_file_create(sub_dir,
1081 "h_back_porch",
1082 (u32 *) &mfd->panel_info.lcdc.h_back_porch);
1083 msm_fb_debugfs_file_create(sub_dir,
1084 "h_front_porch",
1085 (u32 *) &mfd->panel_info.lcdc.h_front_porch);
1086 msm_fb_debugfs_file_create(sub_dir,
1087 "h_pulse_width",
1088 (u32 *) &mfd->panel_info.lcdc.h_pulse_width);
1089 msm_fb_debugfs_file_create(sub_dir,
1090 "v_back_porch",
1091 (u32 *) &mfd->panel_info.lcdc.v_back_porch);
1092 msm_fb_debugfs_file_create(sub_dir,
1093 "v_front_porch",
1094 (u32 *) &mfd->panel_info.lcdc.v_front_porch);
1095 msm_fb_debugfs_file_create(sub_dir,
1096 "v_pulse_width",
1097 (u32 *) &mfd->panel_info.lcdc.v_pulse_width);
1098 msm_fb_debugfs_file_create(sub_dir,
1099 "border_clr",
1100 (u32 *) &mfd->panel_info.lcdc.border_clr);
1101 msm_fb_debugfs_file_create(sub_dir,
1102 "underflow_clr",
1103 (u32 *) &mfd->panel_info.lcdc.underflow_clr);
1104 msm_fb_debugfs_file_create(sub_dir,
1105 "hsync_skew",
1106 (u32 *) &mfd->panel_info.lcdc.hsync_skew);
1107 break;
1108
1109 default:
1110 break;
1111 }
1112 }
1113 }
1114#endif /* MSM_FB_ENABLE_DBGFS */
1115
1116 return ret;
1117}
1118
1119static int msm_fb_open(struct fb_info *info, int user)
1120{
1121 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1122
1123 if (!mfd->ref_cnt) {
1124 mdp_set_dma_pan_info(info, NULL, TRUE);
1125
1126 if (msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable)) {
1127 printk(KERN_ERR "msm_fb_open: can't turn on display!\n");
1128 return -1;
1129 }
1130 }
1131
1132 mfd->ref_cnt++;
1133 return 0;
1134}
1135
1136static int msm_fb_release(struct fb_info *info, int user)
1137{
1138 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1139 int ret = 0;
1140
1141 if (!mfd->ref_cnt) {
1142 MSM_FB_INFO("msm_fb_release: try to close unopened fb %d!\n",
1143 mfd->index);
1144 return -EINVAL;
1145 }
1146
1147 mfd->ref_cnt--;
1148
1149 if (!mfd->ref_cnt) {
1150 if ((ret =
1151 msm_fb_blank_sub(FB_BLANK_POWERDOWN, info,
1152 mfd->op_enable)) != 0) {
1153 printk(KERN_ERR "msm_fb_release: can't turn off display!\n");
1154 return ret;
1155 }
1156 }
1157
1158 return ret;
1159}
1160
1161DECLARE_MUTEX(msm_fb_pan_sem);
1162
1163static int msm_fb_pan_display(struct fb_var_screeninfo *var,
1164 struct fb_info *info)
1165{
1166 struct mdp_dirty_region dirty;
1167 struct mdp_dirty_region *dirtyPtr = NULL;
1168 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1169
1170 if ((!mfd->op_enable) || (!mfd->panel_power_on))
1171 return -EPERM;
1172
1173 if (var->xoffset > (info->var.xres_virtual - info->var.xres))
1174 return -EINVAL;
1175
1176 if (var->yoffset > (info->var.yres_virtual - info->var.yres))
1177 return -EINVAL;
1178
1179 if (info->fix.xpanstep)
1180 info->var.xoffset =
1181 (var->xoffset / info->fix.xpanstep) * info->fix.xpanstep;
1182
1183 if (info->fix.ypanstep)
1184 info->var.yoffset =
1185 (var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;
1186
1187 /* "UPDT" */
1188 if (var->reserved[0] == 0x54445055) {
1189 dirty.xoffset = var->reserved[1] & 0xffff;
1190 dirty.yoffset = (var->reserved[1] >> 16) & 0xffff;
1191
1192 if ((var->reserved[2] & 0xffff) <= dirty.xoffset)
1193 return -EINVAL;
1194 if (((var->reserved[2] >> 16) & 0xffff) <= dirty.yoffset)
1195 return -EINVAL;
1196
1197 dirty.width = (var->reserved[2] & 0xffff) - dirty.xoffset;
1198 dirty.height =
1199 ((var->reserved[2] >> 16) & 0xffff) - dirty.yoffset;
1200 info->var.yoffset = var->yoffset;
1201
1202 if (dirty.xoffset < 0)
1203 return -EINVAL;
1204
1205 if (dirty.yoffset < 0)
1206 return -EINVAL;
1207
1208 if ((dirty.xoffset + dirty.width) > info->var.xres)
1209 return -EINVAL;
1210
1211 if ((dirty.yoffset + dirty.height) > info->var.yres)
1212 return -EINVAL;
1213
1214 if ((dirty.width <= 0) || (dirty.height <= 0))
1215 return -EINVAL;
1216
1217 dirtyPtr = &dirty;
1218 }
1219
1220 /* Flip */
1221 /* A constant value is used to indicate that we should change the DMA
1222 output buffer instead of just panning */
1223
1224 if (var->reserved[0] == 0x466c6970) {
1225 unsigned long length, address;
1226 struct file *p_src_file;
1227 struct mdp_img imgdata;
1228 int bpp;
1229
1230 if (mfd->allow_set_offset) {
1231 imgdata.memory_id = var->reserved[1];
1232 imgdata.priv = var->reserved[2];
1233
1234 /* If there is no memory ID then we want to reset back
1235 to the original fb visibility */
1236 if (var->reserved[1]) {
1237 if (var->reserved[4] == MDP_BLIT_SRC_GEM) {
1238 panic("waaaaaaaaaaaaaah");
1239 if ( /*get_gem_img(&imgdata,
1240 (unsigned long *) &address,
1241 &length)*/ -1 < 0) {
1242 return -1;
1243 }
1244 } else {
1245 /*get_img(&imgdata, info, &address,
1246 &length, &p_src_file);*/
1247 panic("waaaaaah");
1248 }
1249 mfd->ibuf.visible_swapped = TRUE;
1250 } else {
1251 /* Flip back to the original address
1252 adjusted for xoffset and yoffset */
1253
1254 bpp = info->var.bits_per_pixel / 8;
1255 address = (unsigned long) info->fix.smem_start;
1256 address += info->var.xoffset * bpp +
1257 info->var.yoffset * info->fix.line_length;
1258
1259 mfd->ibuf.visible_swapped = FALSE;
1260 }
1261
1262 mdp_set_offset_info(info, address,
1263 (var->activate == FB_ACTIVATE_VBL));
1264
1265 mfd->dma_fnc(mfd);
1266 return 0;
1267 } else
1268 return -EINVAL;
1269 }
1270
1271 down(&msm_fb_pan_sem);
1272 mdp_set_dma_pan_info(info, dirtyPtr,
1273 (var->activate == FB_ACTIVATE_VBL));
1274 mdp_dma_pan_update(info);
1275 up(&msm_fb_pan_sem);
1276
1277 ++mfd->panel_info.frame_count;
1278 return 0;
1279}
1280
1281static int msm_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1282{
1283 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1284
1285 if (var->rotate != FB_ROTATE_UR)
1286 return -EINVAL;
1287 if (var->grayscale != info->var.grayscale)
1288 return -EINVAL;
1289
1290 switch (var->bits_per_pixel) {
1291 case 16:
1292 if ((var->green.offset != 5) ||
1293 !((var->blue.offset == 11)
1294 || (var->blue.offset == 0)) ||
1295 !((var->red.offset == 11)
1296 || (var->red.offset == 0)) ||
1297 (var->blue.length != 5) ||
1298 (var->green.length != 6) ||
1299 (var->red.length != 5) ||
1300 (var->blue.msb_right != 0) ||
1301 (var->green.msb_right != 0) ||
1302 (var->red.msb_right != 0) ||
1303 (var->transp.offset != 0) ||
1304 (var->transp.length != 0))
1305 return -EINVAL;
1306 break;
1307
1308 case 24:
1309 if ((var->blue.offset != 0) ||
1310 (var->green.offset != 8) ||
1311 (var->red.offset != 16) ||
1312 (var->blue.length != 8) ||
1313 (var->green.length != 8) ||
1314 (var->red.length != 8) ||
1315 (var->blue.msb_right != 0) ||
1316 (var->green.msb_right != 0) ||
1317 (var->red.msb_right != 0) ||
1318 !(((var->transp.offset == 0) &&
1319 (var->transp.length == 0)) ||
1320 ((var->transp.offset == 24) &&
1321 (var->transp.length == 8))))
1322 return -EINVAL;
1323 break;
1324
1325 default:
1326 return -EINVAL;
1327 }
1328
1329 if ((var->xres_virtual <= 0) || (var->yres_virtual <= 0))
1330 return -EINVAL;
1331
1332 if (info->fix.smem_len <
1333 (var->xres_virtual*var->yres_virtual*(var->bits_per_pixel/8)))
1334 return -EINVAL;
1335
1336 if ((var->xres == 0) || (var->yres == 0))
1337 return -EINVAL;
1338
1339 if ((var->xres > mfd->panel_info.xres) ||
1340 (var->yres > mfd->panel_info.yres))
1341 return -EINVAL;
1342
1343 if (var->xoffset > (var->xres_virtual - var->xres))
1344 return -EINVAL;
1345
1346 if (var->yoffset > (var->yres_virtual - var->yres))
1347 return -EINVAL;
1348
1349 return 0;
1350}
1351
1352static int msm_fb_set_par(struct fb_info *info)
1353{
1354 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1355 struct fb_var_screeninfo *var = &info->var;
1356 int old_imgType;
1357 int blank = 0;
1358
1359 old_imgType = mfd->fb_imgType;
1360 switch (var->bits_per_pixel) {
1361 case 16:
1362 if (var->red.offset == 0)
1363 mfd->fb_imgType = MDP_BGR_565;
1364 else
1365 mfd->fb_imgType = MDP_RGB_565;
1366 break;
1367
1368 case 24:
1369 if ((var->transp.offset == 0) && (var->transp.length == 0))
1370 mfd->fb_imgType = MDP_RGB_888;
1371 else if ((var->transp.offset == 24) &&
1372 (var->transp.length == 8)) {
1373 mfd->fb_imgType = MDP_ARGB_8888;
1374 info->var.bits_per_pixel = 32;
1375 }
1376 break;
1377
1378 default:
1379 return -EINVAL;
1380 }
1381
1382 if ((mfd->var_pixclock != var->pixclock) ||
1383 (mfd->hw_refresh && ((mfd->fb_imgType != old_imgType) ||
1384 (mfd->var_pixclock != var->pixclock) ||
1385 (mfd->var_xres != var->xres) ||
1386 (mfd->var_yres != var->yres)))) {
1387 mfd->var_xres = var->xres;
1388 mfd->var_yres = var->yres;
1389 mfd->var_pixclock = var->pixclock;
1390 blank = 1;
1391 }
1392
1393 if (blank) {
1394 msm_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable);
1395 msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable);
1396 }
1397
1398 return 0;
1399}
1400
1401static int msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd)
1402{
1403 if (mfd->hw_refresh)
1404 return -EPERM;
1405
1406 if (mfd->sw_currently_refreshing) {
1407 down(&mfd->sem);
1408 mfd->sw_currently_refreshing = FALSE;
1409 up(&mfd->sem);
1410
1411 /* wait until the refresher finishes the last job */
1412 wait_for_completion_killable(&mfd->refresher_comp);
1413 }
1414
1415 return 0;
1416}
1417
1418int msm_fb_resume_sw_refresher(struct msm_fb_data_type *mfd)
1419{
1420 boolean do_refresh;
1421
1422 if (mfd->hw_refresh)
1423 return -EPERM;
1424
1425 down(&mfd->sem);
1426 if ((!mfd->sw_currently_refreshing) && (mfd->sw_refreshing_enable)) {
1427 do_refresh = TRUE;
1428 mfd->sw_currently_refreshing = TRUE;
1429 } else {
1430 do_refresh = FALSE;
1431 }
1432 up(&mfd->sem);
1433
1434 if (do_refresh)
1435 mdp_refresh_screen((unsigned long)mfd);
1436
1437 return 0;
1438}
1439
1440void mdp_ppp_put_img(struct file *p_src_file, struct file *p_dst_file)
1441{
1442#ifdef CONFIG_ANDROID_PMEM
1443 if (p_src_file)
1444 put_pmem_file(p_src_file);
1445 if (p_dst_file)
1446 put_pmem_file(p_dst_file);
1447#endif
1448}
1449
1450int mdp_blit(struct fb_info *info, struct mdp_blit_req *req)
1451{
1452 int ret;
1453 struct file *p_src_file = 0, *p_dst_file = 0;
1454 if (unlikely(req->src_rect.h == 0 || req->src_rect.w == 0)) {
1455 printk(KERN_ERR "mpd_ppp: src img of zero size!\n");
1456 return -EINVAL;
1457 }
1458 if (unlikely(req->dst_rect.h == 0 || req->dst_rect.w == 0))
1459 return 0;
1460
1461 ret = mdp_ppp_blit(info, req, &p_src_file, &p_dst_file);
1462 mdp_ppp_put_img(p_src_file, p_dst_file);
1463 return ret;
1464}
1465
1466typedef void (*msm_dma_barrier_function_pointer) (void *, size_t);
1467
1468static inline void msm_fb_dma_barrier_for_rect(struct fb_info *info,
1469 struct mdp_img *img, struct mdp_rect *rect,
1470 msm_dma_barrier_function_pointer dma_barrier_fp
1471 )
1472{
1473 /*
1474 * Compute the start and end addresses of the rectangles.
1475 * NOTE: As currently implemented, the data between
1476 * the end of one row and the start of the next is
1477 * included in the address range rather than
1478 * doing multiple calls for each row.
1479 */
1480
1481 char * const pmem_start = info->screen_base;
1482/* int bytes_per_pixel = mdp_get_bytes_per_pixel(img->format);
1483 unsigned long start = (unsigned long)pmem_start + img->offset +
1484 (img->width * rect->y + rect->x) * bytes_per_pixel;
1485 size_t size = ((rect->h - 1) * img->width + rect->w) * bytes_per_pixel;
1486 (*dma_barrier_fp) ((void *) start, size);
1487*/
1488 panic("waaaaah");
1489}
1490
1491static inline void msm_dma_nc_pre(void)
1492{
1493 dmb();
1494}
1495static inline void msm_dma_wt_pre(void)
1496{
1497 dmb();
1498}
1499static inline void msm_dma_todevice_wb_pre(void *start, size_t size)
1500{
1501 #warning this
1502// dma_cache_pre_ops(start, size, DMA_TO_DEVICE);
1503}
1504
1505static inline void msm_dma_fromdevice_wb_pre(void *start, size_t size)
1506{
1507 #warning this
1508// dma_cache_pre_ops(start, size, DMA_FROM_DEVICE);
1509}
1510
1511static inline void msm_dma_nc_post(void)
1512{
1513 dmb();
1514}
1515
1516static inline void msm_dma_fromdevice_wt_post(void *start, size_t size)
1517{
1518 #warning this
1519// dma_cache_post_ops(start, size, DMA_FROM_DEVICE);
1520}
1521
1522static inline void msm_dma_todevice_wb_post(void *start, size_t size)
1523{
1524 #warning this
1525// dma_cache_post_ops(start, size, DMA_TO_DEVICE);
1526}
1527
1528static inline void msm_dma_fromdevice_wb_post(void *start, size_t size)
1529{
1530 #warning this
1531// dma_cache_post_ops(start, size, DMA_FROM_DEVICE);
1532}
1533
1534/*
1535 * Do the write barriers required to guarantee data is committed to RAM
1536 * (from CPU cache or internal buffers) before a DMA operation starts.
1537 * NOTE: As currently implemented, the data between
1538 * the end of one row and the start of the next is
1539 * included in the address range rather than
1540 * doing multiple calls for each row.
1541*/
1542static void msm_fb_ensure_memory_coherency_before_dma(struct fb_info *info,
1543 struct mdp_blit_req *req_list,
1544 int req_list_count)
1545{
1546#ifdef CONFIG_ARCH_QSD8X50
1547 int i;
1548
1549 /*
1550 * Normally, do the requested barriers for each address
1551 * range that corresponds to a rectangle.
1552 *
1553 * But if at least one write barrier is requested for data
1554 * going to or from the device but no address range is
1555 * needed for that barrier, then do the barrier, but do it
1556 * only once, no matter how many requests there are.
1557 */
1558 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1559 switch (mfd->mdp_fb_page_protection) {
1560 default:
1561 case MDP_FB_PAGE_PROTECTION_NONCACHED:
1562 case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
1563 /*
1564 * The following barrier is only done at most once,
1565 * since further calls would be redundant.
1566 */
1567 for (i = 0; i < req_list_count; i++) {
1568 if (!(req_list[i].flags
1569 & MDP_NO_DMA_BARRIER_START)) {
1570 msm_dma_nc_pre();
1571 break;
1572 }
1573 }
1574 break;
1575
1576 case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
1577 /*
1578 * The following barrier is only done at most once,
1579 * since further calls would be redundant.
1580 */
1581 for (i = 0; i < req_list_count; i++) {
1582 if (!(req_list[i].flags
1583 & MDP_NO_DMA_BARRIER_START)) {
1584 msm_dma_wt_pre();
1585 break;
1586 }
1587 }
1588 break;
1589
1590 case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
1591 case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
1592 for (i = 0; i < req_list_count; i++) {
1593 if (!(req_list[i].flags &
1594 MDP_NO_DMA_BARRIER_START)) {
1595
1596 msm_fb_dma_barrier_for_rect(info,
1597 &(req_list[i].src),
1598 &(req_list[i].src_rect),
1599 msm_dma_todevice_wb_pre
1600 );
1601
1602 msm_fb_dma_barrier_for_rect(info,
1603 &(req_list[i].dst),
1604 &(req_list[i].dst_rect),
1605 msm_dma_todevice_wb_pre
1606 );
1607 }
1608 }
1609 break;
1610 }
1611#else
1612 dmb();
1613#endif
1614}
1615
1616
1617/*
1618 * Do the write barriers required to guarantee data will be re-read from RAM by
1619 * the CPU after a DMA operation ends.
1620 * NOTE: As currently implemented, the data between
1621 * the end of one row and the start of the next is
1622 * included in the address range rather than
1623 * doing multiple calls for each row.
1624*/
1625static void msm_fb_ensure_memory_coherency_after_dma(struct fb_info *info,
1626 struct mdp_blit_req *req_list,
1627 int req_list_count)
1628{
1629#ifdef CONFIG_ARCH_QSD8X50
1630 int i;
1631
1632 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1633 switch (mfd->mdp_fb_page_protection) {
1634 default:
1635 case MDP_FB_PAGE_PROTECTION_NONCACHED:
1636 case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
1637 /*
1638 * The following barrier is only done at most once,
1639 * since further calls would be redundant.
1640 */
1641 for (i = 0; i < req_list_count; i++) {
1642 if (!(req_list[i].flags
1643 & MDP_NO_DMA_BARRIER_END)) {
1644 msm_dma_nc_post();
1645 break;
1646 }
1647 }
1648 break;
1649
1650 case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
1651 for (i = 0; i < req_list_count; i++) {
1652 if (!(req_list[i].flags &
1653 MDP_NO_DMA_BARRIER_END)) {
1654
1655 msm_fb_dma_barrier_for_rect(info,
1656 &(req_list[i].dst),
1657 &(req_list[i].dst_rect),
1658 msm_dma_fromdevice_wt_post
1659 );
1660 }
1661 }
1662 break;
1663 case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
1664 case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
1665 for (i = 0; i < req_list_count; i++) {
1666 if (!(req_list[i].flags &
1667 MDP_NO_DMA_BARRIER_END)) {
1668
1669 msm_fb_dma_barrier_for_rect(info,
1670 &(req_list[i].dst),
1671 &(req_list[i].dst_rect),
1672 msm_dma_fromdevice_wb_post
1673 );
1674 }
1675 }
1676 break;
1677 }
1678#else
1679 dmb();
1680#endif
1681}
1682
1683#ifdef CONFIG_MDP_PPP_ASYNC_OP
1684void msm_fb_ensure_mem_coherency_after_dma(struct fb_info *info,
1685 struct mdp_blit_req *req_list, int req_list_count)
1686{
1687 BUG_ON(!info);
1688
1689 /*
1690 * Ensure that CPU cache and other internal CPU state is
1691 * updated to reflect any change in memory modified by MDP blit
1692 * DMA.
1693 */
1694 msm_fb_ensure_memory_coherency_after_dma(info,
1695 req_list, req_list_count);
1696}
1697
1698static int msmfb_async_blit(struct fb_info *info, void __user *p)
1699{
1700 /*
1701 * CAUTION: The names of the struct types intentionally *DON'T* match
1702 * the names of the variables declared -- they appear to be swapped.
1703 * Read the code carefully and you should see that the variable names
1704 * make sense.
1705 */
1706 const int MAX_LIST_WINDOW = 16;
1707 struct mdp_blit_req req_list[MAX_LIST_WINDOW];
1708 struct mdp_blit_req_list req_list_header;
1709
1710 int count, i, req_list_count;
1711
1712 /* Get the count size for the total BLIT request. */
1713 if (copy_from_user(&req_list_header, p, sizeof(req_list_header)))
1714 return -EFAULT;
1715 p += sizeof(req_list_header);
1716 count = req_list_header.count;
1717 while (count > 0) {
1718 /*
1719 * Access the requests through a narrow window to decrease copy
1720 * overhead and make larger requests accessible to the
1721 * coherency management code.
1722 * NOTE: The window size is intended to be larger than the
1723 * typical request size, but not require more than 2
1724 * kbytes of stack storage.
1725 */
1726 req_list_count = count;
1727 if (req_list_count > MAX_LIST_WINDOW)
1728 req_list_count = MAX_LIST_WINDOW;
1729 if (copy_from_user(&req_list, p,
1730 sizeof(struct mdp_blit_req)*req_list_count))
1731 return -EFAULT;
1732
1733 /*
1734 * Ensure that any data CPU may have previously written to
1735 * internal state (but not yet committed to memory) is
1736 * guaranteed to be committed to memory now.
1737 */
1738 msm_fb_ensure_memory_coherency_before_dma(info,
1739 req_list, req_list_count);
1740
1741 /*
1742 * Do the blit DMA, if required -- returning early only if
1743 * there is a failure.
1744 */
1745 for (i = 0; i < req_list_count; i++) {
1746 if (!(req_list[i].flags & MDP_NO_BLIT)) {
1747 int ret = 0;
1748 struct mdp_ppp_djob *job = NULL;
1749
1750 if (unlikely(req_list[i].src_rect.h == 0 ||
1751 req_list[i].src_rect.w == 0)) {
1752 MSM_FB_ERR("mpd_ppp: "
1753 "src img of zero size!\n");
1754 return -EINVAL;
1755 }
1756
1757 if (unlikely(req_list[i].dst_rect.h == 0 ||
1758 req_list[i].dst_rect.w == 0))
1759 continue;
1760
1761 /* create a new display job */
1762 job = mdp_ppp_new_djob();
1763 if (unlikely(!job))
1764 return -ENOMEM;
1765
1766 job->info = info;
1767 memcpy(&job->req, &req_list[i],
1768 sizeof(struct mdp_blit_req));
1769
1770 /* Do the actual blit. */
1771 ret = mdp_ppp_blit(info, &job->req,
1772 &job->p_src_file, &job->p_dst_file);
1773
1774 /*
1775 * Note that early returns don't guarantee
1776 * memory coherency.
1777 */
1778 if (ret || mdp_ppp_get_ret_code()) {
1779 mdp_ppp_clear_curr_djob();
1780 return ret;
1781 }
1782 }
1783 }
1784
1785 /* Go to next window of requests. */
1786 count -= req_list_count;
1787 p += sizeof(struct mdp_blit_req)*req_list_count;
1788 }
1789 return 0;
1790}
1791#else
1792
1793/*
1794 * NOTE: The userspace issues blit operations in a sequence, the sequence
1795 * start with a operation marked START and ends in an operation marked
1796 * END. It is guranteed by the userspace that all the blit operations
1797 * between START and END are only within the regions of areas designated
1798 * by the START and END operations and that the userspace doesnt modify
1799 * those areas. Hence it would be enough to perform barrier/cache operations
1800 * only on the START and END operations.
1801 */
1802static int msmfb_blit(struct fb_info *info, void __user *p)
1803{
1804 /*
1805 * CAUTION: The names of the struct types intentionally *DON'T* match
1806 * the names of the variables declared -- they appear to be swapped.
1807 * Read the code carefully and you should see that the variable names
1808 * make sense.
1809 */
1810 const int MAX_LIST_WINDOW = 16;
1811 struct mdp_blit_req req_list[MAX_LIST_WINDOW];
1812 struct mdp_blit_req_list req_list_header;
1813
1814 int count, i, req_list_count;
1815
1816 /* Get the count size for the total BLIT request. */
1817 if (copy_from_user(&req_list_header, p, sizeof(req_list_header)))
1818 return -EFAULT;
1819 p += sizeof(req_list_header);
1820 count = req_list_header.count;
1821 while (count > 0) {
1822 /*
1823 * Access the requests through a narrow window to decrease copy
1824 * overhead and make larger requests accessible to the
1825 * coherency management code.
1826 * NOTE: The window size is intended to be larger than the
1827 * typical request size, but not require more than 2
1828 * kbytes of stack storage.
1829 */
1830 req_list_count = count;
1831 if (req_list_count > MAX_LIST_WINDOW)
1832 req_list_count = MAX_LIST_WINDOW;
1833 if (copy_from_user(&req_list, p,
1834 sizeof(struct mdp_blit_req)*req_list_count))
1835 return -EFAULT;
1836
1837 /*
1838 * Ensure that any data CPU may have previously written to
1839 * internal state (but not yet committed to memory) is
1840 * guaranteed to be committed to memory now.
1841 */
1842 msm_fb_ensure_memory_coherency_before_dma(info,
1843 req_list, req_list_count);
1844
1845 /*
1846 * Do the blit DMA, if required -- returning early only if
1847 * there is a failure.
1848 */
1849 for (i = 0; i < req_list_count; i++) {
1850 if (!(req_list[i].flags & MDP_NO_BLIT)) {
1851 /* Do the actual blit. */
1852 int ret = mdp_blit(info, &(req_list[i]));
1853
1854 /*
1855 * Note that early returns don't guarantee
1856 * memory coherency.
1857 */
1858 if (ret)
1859 return ret;
1860 }
1861 }
1862
1863 /*
1864 * Ensure that CPU cache and other internal CPU state is
1865 * updated to reflect any change in memory modified by MDP blit
1866 * DMA.
1867 */
1868 msm_fb_ensure_memory_coherency_after_dma(info,
1869 req_list,
1870 req_list_count);
1871
1872 /* Go to next window of requests. */
1873 count -= req_list_count;
1874 p += sizeof(struct mdp_blit_req)*req_list_count;
1875 }
1876 return 0;
1877}
1878#endif
1879
1880#ifdef CONFIG_FB_MSM_OVERLAY
1881static int msmfb_overlay_get(struct fb_info *info, void __user *p)
1882{
1883 struct mdp_overlay req;
1884 int ret;
1885
1886 if (copy_from_user(&req, p, sizeof(req)))
1887 return -EFAULT;
1888
1889 ret = mdp4_overlay_get(info, &req);
1890 if (ret) {
1891 printk(KERN_ERR "%s: ioctl failed \n",
1892 __func__);
1893 return ret;
1894 }
1895 if (copy_to_user(p, &req, sizeof(req))) {
1896 printk(KERN_ERR "%s: copy2user failed \n",
1897 __func__);
1898 return -EFAULT;
1899 }
1900
1901 return 0;
1902}
1903
1904static int msmfb_overlay_set(struct fb_info *info, void __user *p)
1905{
1906 struct mdp_overlay req;
1907 int ret;
1908
1909 if (copy_from_user(&req, p, sizeof(req)))
1910 return -EFAULT;
1911
1912 ret = mdp4_overlay_set(info, &req);
1913 if (ret) {
1914 printk(KERN_ERR "%s:ioctl failed \n",
1915 __func__);
1916 return ret;
1917 }
1918
1919 if (copy_to_user(p, &req, sizeof(req))) {
1920 printk(KERN_ERR "%s: copy2user failed \n",
1921 __func__);
1922 return -EFAULT;
1923 }
1924
1925 return 0;
1926}
1927
1928static int msmfb_overlay_unset(struct fb_info *info, unsigned long *argp)
1929{
1930 int ret, ndx;
1931
1932 ret = copy_from_user(&ndx, argp, sizeof(ndx));
1933 if (ret) {
1934 printk(KERN_ERR "%s:msmfb_overlay_unset ioctl failed \n",
1935 __func__);
1936 return ret;
1937 }
1938
1939 return mdp4_overlay_unset(info, ndx);
1940}
1941
1942static int msmfb_overlay_play(struct fb_info *info, unsigned long *argp)
1943{
1944 int ret;
1945 struct msmfb_overlay_data req;
1946 struct file *p_src_file = 0;
1947
1948 ret = copy_from_user(&req, argp, sizeof(req));
1949 if (ret) {
1950 printk(KERN_ERR "%s:msmfb_overlay_play ioctl failed \n",
1951 __func__);
1952 return ret;
1953 }
1954
1955 ret = mdp4_overlay_play(info, &req, &p_src_file);
1956
1957 if (p_src_file)
1958 put_pmem_file(p_src_file);
1959
1960 return ret;
1961}
1962
1963#endif
1964
1965DECLARE_MUTEX(msm_fb_ioctl_ppp_sem);
1966DEFINE_MUTEX(msm_fb_ioctl_lut_sem);
1967DEFINE_MUTEX(msm_fb_ioctl_hist_sem);
1968
1969/* Set color conversion matrix from user space */
1970
1971#ifndef CONFIG_FB_MSM_MDP40
1972static void msmfb_set_color_conv(struct mdp_ccs *p)
1973{
1974 int i;
1975
1976 if (p->direction == MDP_CCS_RGB2YUV) {
1977 /* MDP cmd block enable */
1978 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1979
1980 /* RGB->YUV primary forward matrix */
1981 for (i = 0; i < MDP_CCS_SIZE; i++)
1982 writel(p->ccs[i], MDP_CSC_PFMVn(i));
1983
1984 #ifdef CONFIG_FB_MSM_MDP31
1985 for (i = 0; i < MDP_BV_SIZE; i++)
1986 writel(p->bv[i], MDP_CSC_POST_BV2n(i));
1987 #endif
1988
1989 /* MDP cmd block disable */
1990 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1991 } else {
1992 /* MDP cmd block enable */
1993 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1994
1995 /* YUV->RGB primary reverse matrix */
1996 for (i = 0; i < MDP_CCS_SIZE; i++)
1997 writel(p->ccs[i], MDP_CSC_PRMVn(i));
1998 for (i = 0; i < MDP_BV_SIZE; i++)
1999 writel(p->bv[i], MDP_CSC_PRE_BV1n(i));
2000
2001 /* MDP cmd block disable */
2002 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
2003 }
2004}
2005#endif
2006
2007
2008static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd,
2009 unsigned long arg)
2010{
2011 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2012 void __user *argp = (void __user *)arg;
2013 struct fb_cursor cursor;
2014 struct fb_cmap cmap;
2015 struct mdp_histogram hist;
2016#ifndef CONFIG_FB_MSM_MDP40
2017 struct mdp_ccs ccs_matrix;
2018#endif
2019 struct mdp_page_protection fb_page_protection;
2020 int ret = 0;
2021
2022 if (!mfd->op_enable)
2023 return -EPERM;
2024
2025 switch (cmd) {
2026#ifdef CONFIG_FB_MSM_OVERLAY
2027 case MSMFB_OVERLAY_GET:
2028 down(&msm_fb_ioctl_ppp_sem);
2029 ret = msmfb_overlay_get(info, argp);
2030 up(&msm_fb_ioctl_ppp_sem);
2031 break;
2032 case MSMFB_OVERLAY_SET:
2033 down(&msm_fb_ioctl_ppp_sem);
2034 ret = msmfb_overlay_set(info, argp);
2035 up(&msm_fb_ioctl_ppp_sem);
2036 break;
2037 case MSMFB_OVERLAY_UNSET:
2038 down(&msm_fb_ioctl_ppp_sem);
2039 ret = msmfb_overlay_unset(info, argp);
2040 up(&msm_fb_ioctl_ppp_sem);
2041 break;
2042 case MSMFB_OVERLAY_PLAY:
2043 down(&msm_fb_ioctl_ppp_sem);
2044 ret = msmfb_overlay_play(info, argp);
2045 up(&msm_fb_ioctl_ppp_sem);
2046 break;
2047#endif
2048 case MSMFB_BLIT:
2049 down(&msm_fb_ioctl_ppp_sem);
2050#ifdef CONFIG_MDP_PPP_ASYNC_OP
2051 ret = msmfb_async_blit(info, argp);
2052 mdp_ppp_wait(); /* Wait for all blits to be finished. */
2053#else
2054 ret = msmfb_blit(info, argp);
2055#endif
2056 up(&msm_fb_ioctl_ppp_sem);
2057
2058 break;
2059
2060 /* Ioctl for setting ccs matrix from user space */
2061 case MSMFB_SET_CCS_MATRIX:
2062#ifndef CONFIG_FB_MSM_MDP40
2063 ret = copy_from_user(&ccs_matrix, argp, sizeof(ccs_matrix));
2064 if (ret) {
2065 printk(KERN_ERR
2066 "%s:MSMFB_SET_CCS_MATRIX ioctl failed \n",
2067 __func__);
2068 return ret;
2069 }
2070
2071 down(&msm_fb_ioctl_ppp_sem);
2072 if (ccs_matrix.direction == MDP_CCS_RGB2YUV)
2073 mdp_ccs_rgb2yuv = ccs_matrix;
2074 else
2075 mdp_ccs_yuv2rgb = ccs_matrix;
2076
2077 msmfb_set_color_conv(&ccs_matrix) ;
2078 up(&msm_fb_ioctl_ppp_sem);
2079#else
2080 ret = -EINVAL;
2081#endif
2082
2083 break;
2084
2085 /* Ioctl for getting ccs matrix to user space */
2086 case MSMFB_GET_CCS_MATRIX:
2087#ifndef CONFIG_FB_MSM_MDP40
2088 ret = copy_from_user(&ccs_matrix, argp, sizeof(ccs_matrix)) ;
2089 if (ret) {
2090 printk(KERN_ERR
2091 "%s:MSMFB_GET_CCS_MATRIX ioctl failed \n",
2092 __func__);
2093 return ret;
2094 }
2095
2096 down(&msm_fb_ioctl_ppp_sem);
2097 if (ccs_matrix.direction == MDP_CCS_RGB2YUV)
2098 ccs_matrix = mdp_ccs_rgb2yuv;
2099 else
2100 ccs_matrix = mdp_ccs_yuv2rgb;
2101
2102 ret = copy_to_user(argp, &ccs_matrix, sizeof(ccs_matrix));
2103
2104 if (ret) {
2105 printk(KERN_ERR
2106 "%s:MSMFB_GET_CCS_MATRIX ioctl failed \n",
2107 __func__);
2108 return ret ;
2109 }
2110 up(&msm_fb_ioctl_ppp_sem);
2111#else
2112 ret = -EINVAL;
2113#endif
2114
2115 break;
2116
2117#ifdef CONFIG_MDP_PPP_ASYNC_OP
2118 case MSMFB_ASYNC_BLIT:
2119 down(&msm_fb_ioctl_ppp_sem);
2120 ret = msmfb_async_blit(info, argp);
2121 up(&msm_fb_ioctl_ppp_sem);
2122 break;
2123
2124 case MSMFB_BLIT_FLUSH:
2125 down(&msm_fb_ioctl_ppp_sem);
2126 mdp_ppp_wait();
2127 up(&msm_fb_ioctl_ppp_sem);
2128 break;
2129#endif
2130
2131 case MSMFB_GRP_DISP:
2132#ifdef CONFIG_FB_MSM_MDP22
2133 {
2134 unsigned long grp_id;
2135
2136 ret = copy_from_user(&grp_id, argp, sizeof(grp_id));
2137 if (ret)
2138 return ret;
2139
2140 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
2141 writel(grp_id, MDP_FULL_BYPASS_WORD43);
2142 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF,
2143 FALSE);
2144 break;
2145 }
2146#else
2147 return -EFAULT;
2148#endif
2149 case MSMFB_SUSPEND_SW_REFRESHER:
2150 if (!mfd->panel_power_on)
2151 return -EPERM;
2152
2153 mfd->sw_refreshing_enable = FALSE;
2154 ret = msm_fb_stop_sw_refresher(mfd);
2155 break;
2156
2157 case MSMFB_RESUME_SW_REFRESHER:
2158 if (!mfd->panel_power_on)
2159 return -EPERM;
2160
2161 mfd->sw_refreshing_enable = TRUE;
2162 ret = msm_fb_resume_sw_refresher(mfd);
2163 break;
2164
2165 case MSMFB_CURSOR:
2166 ret = copy_from_user(&cursor, argp, sizeof(cursor));
2167 if (ret)
2168 return ret;
2169
2170 ret = msm_fb_cursor(info, &cursor);
2171 break;
2172
2173 case MSMFB_SET_LUT:
2174 ret = copy_from_user(&cmap, argp, sizeof(cmap));
2175 if (ret)
2176 return ret;
2177
2178 mutex_lock(&msm_fb_ioctl_lut_sem);
2179 ret = msm_fb_set_lut(&cmap, info);
2180 mutex_unlock(&msm_fb_ioctl_lut_sem);
2181 break;
2182
2183 case MSMFB_HISTOGRAM:
2184 if (!mfd->do_histogram)
2185 return -ENODEV;
2186
2187 ret = copy_from_user(&hist, argp, sizeof(hist));
2188 if (ret)
2189 return ret;
2190
2191 mutex_lock(&msm_fb_ioctl_hist_sem);
2192 ret = mfd->do_histogram(info, &hist);
2193 mutex_unlock(&msm_fb_ioctl_hist_sem);
2194 break;
2195
2196 case MSMFB_GET_PAGE_PROTECTION:
2197 fb_page_protection.page_protection
2198 = mfd->mdp_fb_page_protection;
2199 ret = copy_to_user(argp, &fb_page_protection,
2200 sizeof(fb_page_protection));
2201 if (ret)
2202 return ret;
2203 break;
2204
2205 case MSMFB_SET_PAGE_PROTECTION:
2206#ifdef CONFIG_ARCH_QSD8X50
2207 ret = copy_from_user(&fb_page_protection, argp,
2208 sizeof(fb_page_protection));
2209 if (ret)
2210 return ret;
2211
2212 /* Validate the proposed page protection settings. */
2213 switch (fb_page_protection.page_protection) {
2214 case MDP_FB_PAGE_PROTECTION_NONCACHED:
2215 case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
2216 case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
2217 /* Write-back cache (read allocate) */
2218 case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
2219 /* Write-back cache (write allocate) */
2220 case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
2221 mfd->mdp_fb_page_protection =
2222 fb_page_protection.page_protection;
2223 break;
2224 default:
2225 ret = -EINVAL;
2226 break;
2227 }
2228#else
2229 /*
2230 * Don't allow caching until 7k DMA cache operations are
2231 * available.
2232 */
2233 ret = -EINVAL;
2234#endif
2235 break;
2236
2237 default:
2238 MSM_FB_INFO("MDP: unknown ioctl (cmd=%d) received!\n", cmd);
2239 ret = -EINVAL;
2240 break;
2241 }
2242
2243 return ret;
2244}
2245
2246static int msm_fb_register_driver(void)
2247{
2248 return platform_driver_register(&msm_fb_driver);
2249}
2250
2251void msm_fb_add_device(struct platform_device *pdev)
2252{
2253 struct msm_fb_panel_data *pdata;
2254 struct platform_device *this_dev = NULL;
2255 struct fb_info *fbi;
2256 struct msm_fb_data_type *mfd = NULL;
2257 u32 type, id, fb_num;
2258
2259 if (!pdev)
2260 return;
2261 id = pdev->id;
2262
2263 pdata = pdev->dev.platform_data;
2264 if (!pdata)
2265 return;
2266 type = pdata->panel_info.type;
2267 fb_num = pdata->panel_info.fb_num;
2268
2269 if (fb_num <= 0)
2270 return;
2271
2272 if (fbi_list_index >= MAX_FBI_LIST) {
2273 printk(KERN_ERR "msm_fb: no more framebuffer info list!\n");
2274 return;
2275 }
2276 /*
2277 * alloc panel device data
2278 */
2279 this_dev = msm_fb_device_alloc(pdata, type, id);
2280
2281 if (!this_dev) {
2282 printk(KERN_ERR
2283 "%s: msm_fb_device_alloc failed!\n", __func__);
2284 return;
2285 }
2286
2287 /*
2288 * alloc framebuffer info + par data
2289 */
2290 fbi = framebuffer_alloc(sizeof(struct msm_fb_data_type), NULL);
2291 if (fbi == NULL) {
2292 platform_device_put(this_dev);
2293 printk(KERN_ERR "msm_fb: can't alloca framebuffer info data!\n");
2294 return;
2295 }
2296
2297 mfd = (struct msm_fb_data_type *)fbi->par;
2298 mfd->key = MFD_KEY;
2299 mfd->fbi = fbi;
2300 mfd->panel.type = type;
2301 mfd->panel.id = id;
2302 mfd->fb_page = fb_num;
2303 mfd->index = fbi_list_index;
2304 mfd->mdp_fb_page_protection = MDP_FB_PAGE_PROTECTION_WRITECOMBINE;
2305
2306 /* link to the latest pdev */
2307 mfd->pdev = this_dev;
2308
2309 mfd_list[mfd_list_index++] = mfd;
2310 fbi_list[fbi_list_index++] = fbi;
2311
2312 /*
2313 * set driver data
2314 */
2315 platform_set_drvdata(this_dev, mfd);
2316
2317 if (platform_device_add(this_dev)) {
2318 printk(KERN_ERR "msm_fb: platform_device_add failed!\n");
2319 platform_device_put(this_dev);
2320 framebuffer_release(fbi);
2321 fbi_list_index--;
2322 return;
2323 }
2324}
2325EXPORT_SYMBOL(msm_fb_add_device);
2326
2327int __init msm_fb_init(void)
2328{
2329 int rc = -ENODEV;
2330
2331 if (msm_fb_register_driver())
2332 return rc;
2333
2334#ifdef MSM_FB_ENABLE_DBGFS
2335 {
2336 struct dentry *root;
2337
2338 if ((root = msm_fb_get_debugfs_root()) != NULL) {
2339 msm_fb_debugfs_file_create(root,
2340 "msm_fb_msg_printing_level",
2341 (u32 *) &msm_fb_msg_level);
2342 msm_fb_debugfs_file_create(root,
2343 "mddi_msg_printing_level",
2344 (u32 *) &mddi_msg_level);
2345 msm_fb_debugfs_file_create(root, "msm_fb_debug_enabled",
2346 (u32 *) &msm_fb_debug_enabled);
2347 }
2348 }
2349#endif
2350
2351 return 0;
2352}
2353
2354module_init(msm_fb_init);
diff --git a/drivers/staging/msm/msm_fb.h b/drivers/staging/msm/msm_fb.h
new file mode 100644
index 000000000000..f93913800475
--- /dev/null
+++ b/drivers/staging/msm/msm_fb.h
@@ -0,0 +1,174 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef MSM_FB_H
30#define MSM_FB_H
31
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/sched.h>
35#include <linux/time.h>
36#include <linux/init.h>
37#include <linux/interrupt.h>
38#include "linux/proc_fs.h"
39
40#include <mach/hardware.h>
41#include <linux/io.h>
42#include <mach/board.h>
43
44#include <asm/system.h>
45#include <asm/mach-types.h>
46#include <mach/memory.h>
47#include <linux/semaphore.h>
48#include <linux/spinlock.h>
49#include <linux/workqueue.h>
50#include <linux/hrtimer.h>
51
52#include <linux/fb.h>
53
54#ifdef CONFIG_HAS_EARLYSUSPEND
55#include <linux/earlysuspend.h>
56#endif
57
58#include "msm_fb_panel.h"
59#include "mdp.h"
60
61#define MSM_FB_DEFAULT_PAGE_SIZE 2
62#define MFD_KEY 0x11161126
63#define MSM_FB_MAX_DEV_LIST 32
64
65struct disp_info_type_suspend {
66 boolean op_enable;
67 boolean sw_refreshing_enable;
68 boolean panel_power_on;
69};
70
71struct msm_fb_data_type {
72 __u32 key;
73 __u32 index;
74 __u32 ref_cnt;
75 __u32 fb_page;
76
77 panel_id_type panel;
78 struct msm_panel_info panel_info;
79
80 DISP_TARGET dest;
81 struct fb_info *fbi;
82
83 boolean op_enable;
84 uint32 fb_imgType;
85 boolean sw_currently_refreshing;
86 boolean sw_refreshing_enable;
87 boolean hw_refresh;
88
89 MDPIBUF ibuf;
90 boolean ibuf_flushed;
91 struct timer_list refresh_timer;
92 struct completion refresher_comp;
93
94 boolean pan_waiting;
95 struct completion pan_comp;
96
97 /* vsync */
98 boolean use_mdp_vsync;
99 __u32 vsync_gpio;
100 __u32 total_lcd_lines;
101 __u32 total_porch_lines;
102 __u32 lcd_ref_usec_time;
103 __u32 refresh_timer_duration;
104
105 struct hrtimer dma_hrtimer;
106
107 boolean panel_power_on;
108 struct work_struct dma_update_worker;
109 struct semaphore sem;
110
111 struct timer_list vsync_resync_timer;
112 boolean vsync_handler_pending;
113 struct work_struct vsync_resync_worker;
114
115 ktime_t last_vsync_timetick;
116
117 __u32 *vsync_width_boundary;
118
119 unsigned int pmem_id;
120 struct disp_info_type_suspend suspend;
121
122 __u32 channel_irq;
123
124 struct mdp_dma_data *dma;
125 void (*dma_fnc) (struct msm_fb_data_type *mfd);
126 int (*cursor_update) (struct fb_info *info,
127 struct fb_cursor *cursor);
128 int (*lut_update) (struct fb_info *info,
129 struct fb_cmap *cmap);
130 int (*do_histogram) (struct fb_info *info,
131 struct mdp_histogram *hist);
132 void *cursor_buf;
133 void *cursor_buf_phys;
134
135 void *cmd_port;
136 void *data_port;
137 void *data_port_phys;
138
139 __u32 bl_level;
140
141 struct platform_device *pdev;
142
143 __u32 var_xres;
144 __u32 var_yres;
145 __u32 var_pixclock;
146
147#ifdef MSM_FB_ENABLE_DBGFS
148 struct dentry *sub_dir;
149#endif
150
151#ifdef CONFIG_HAS_EARLYSUSPEND
152 struct early_suspend early_suspend;
153 struct early_suspend mddi_early_suspend;
154 struct early_suspend mddi_ext_early_suspend;
155#endif
156 u32 mdp_fb_page_protection;
157 int allow_set_offset;
158};
159
160struct dentry *msm_fb_get_debugfs_root(void);
161void msm_fb_debugfs_file_create(struct dentry *root, const char *name,
162 u32 *var);
163void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl,
164 u32 save);
165
166void msm_fb_add_device(struct platform_device *pdev);
167
168int msm_fb_detect_client(const char *name);
169
170#ifdef CONFIG_FB_BACKLIGHT
171void msm_fb_config_backlight(struct msm_fb_data_type *mfd);
172#endif
173
174#endif /* MSM_FB_H */
diff --git a/drivers/staging/msm/msm_fb_bl.c b/drivers/staging/msm/msm_fb_bl.c
new file mode 100644
index 000000000000..033fc9486e01
--- /dev/null
+++ b/drivers/staging/msm/msm_fb_bl.c
@@ -0,0 +1,79 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/slab.h>
22#include <linux/fb.h>
23#include <linux/string.h>
24#include <linux/version.h>
25#include <linux/backlight.h>
26
27#include "msm_fb.h"
28
29static int msm_fb_bl_get_brightness(struct backlight_device *pbd)
30{
31 return pbd->props.brightness;
32}
33
34static int msm_fb_bl_update_status(struct backlight_device *pbd)
35{
36 struct msm_fb_data_type *mfd = bl_get_data(pbd);
37 __u32 bl_lvl;
38
39 bl_lvl = pbd->props.brightness;
40 bl_lvl = mfd->fbi->bl_curve[bl_lvl];
41 msm_fb_set_backlight(mfd, bl_lvl, 1);
42 return 0;
43}
44
45static struct backlight_ops msm_fb_bl_ops = {
46 .get_brightness = msm_fb_bl_get_brightness,
47 .update_status = msm_fb_bl_update_status,
48};
49
50void msm_fb_config_backlight(struct msm_fb_data_type *mfd)
51{
52 struct msm_fb_panel_data *pdata;
53 struct backlight_device *pbd;
54 struct fb_info *fbi;
55 char name[16];
56
57 fbi = mfd->fbi;
58 pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
59
60 if ((pdata) && (pdata->set_backlight)) {
61 snprintf(name, sizeof(name), "msmfb_bl%d", mfd->index);
62 pbd =
63 backlight_device_register(name, fbi->dev, mfd,
64 &msm_fb_bl_ops);
65 if (!IS_ERR(pbd)) {
66 fbi->bl_dev = pbd;
67 fb_bl_default_curve(fbi,
68 0,
69 mfd->panel_info.bl_min,
70 mfd->panel_info.bl_max);
71 pbd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
72 pbd->props.brightness = FB_BACKLIGHT_LEVELS - 1;
73 backlight_update_status(pbd);
74 } else {
75 fbi->bl_dev = NULL;
76 printk(KERN_ERR "msm_fb: backlight_device_register failed!\n");
77 }
78 }
79}
diff --git a/drivers/staging/msm/msm_fb_def.h b/drivers/staging/msm/msm_fb_def.h
new file mode 100644
index 000000000000..6de440937422
--- /dev/null
+++ b/drivers/staging/msm/msm_fb_def.h
@@ -0,0 +1,201 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef MSM_FB_DEF_H
30#define MSM_FB_DEF_H
31
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/kernel.h>
35#include <linux/slab.h>
36#include <linux/delay.h>
37#include <linux/mm.h>
38#include <linux/fb.h>
39#include "msm_mdp.h"
40#include <linux/init.h>
41#include <linux/ioport.h>
42#include <linux/device.h>
43#include <linux/dma-mapping.h>
44#include <linux/uaccess.h>
45#include <linux/workqueue.h>
46#include <linux/string.h>
47#include <linux/version.h>
48#include <linux/proc_fs.h>
49#include <linux/vmalloc.h>
50#include <linux/debugfs.h>
51#include <linux/console.h>
52
53#include <linux/kernel.h>
54#include <linux/sched.h>
55#include <linux/time.h>
56#include <linux/init.h>
57#include <linux/interrupt.h>
58#include "linux/proc_fs.h"
59#include <mach/hardware.h>
60#include <linux/io.h>
61#include <linux/fb.h>
62#include <asm/system.h>
63#include <asm/mach-types.h>
64#include <linux/platform_device.h>
65
66typedef s64 int64;
67typedef s32 int32;
68typedef s16 int16;
69typedef s8 int8;
70
71typedef u64 uint64;
72typedef u32 uint32;
73typedef u16 uint16;
74typedef u8 uint8;
75
76typedef s32 int4;
77typedef s16 int2;
78typedef s8 int1;
79
80typedef u32 uint4;
81typedef u16 uint2;
82typedef u8 uint1;
83
84typedef u32 dword;
85typedef u16 word;
86typedef u8 byte;
87
88typedef unsigned int boolean;
89
90#ifndef TRUE
91#define TRUE 1
92#endif
93
94#ifndef FALSE
95#define FALSE 0
96#endif
97
98#define MSM_FB_ENABLE_DBGFS
99#define FEATURE_MDDI
100
101#define outp32(addr, val) writel(val, addr)
102#define outp16(addr, val) writew(val, addr)
103#define outp8(addr, val) writeb(val, addr)
104#define outp(addr, val) outp32(addr, val)
105
106#ifndef MAX
107#define MAX( x, y ) (((x) > (y)) ? (x) : (y))
108#endif
109
110#ifndef MIN
111#define MIN( x, y ) (((x) < (y)) ? (x) : (y))
112#endif
113
114/*--------------------------------------------------------------------------*/
115
116#define inp32(addr) readl(addr)
117#define inp16(addr) readw(addr)
118#define inp8(addr) readb(addr)
119#define inp(addr) inp32(addr)
120
121#define inpw(port) readw(port)
122#define outpw(port, val) writew(val, port)
123#define inpdw(port) readl(port)
124#define outpdw(port, val) writel(val, port)
125
126
127#define clk_busy_wait(x) msleep_interruptible((x)/1000)
128
129#define memory_barrier()
130
131#define assert(expr) \
132 if(!(expr)) { \
133 printk(KERN_ERR "msm_fb: assertion failed! %s,%s,%s,line=%d\n",\
134 #expr, __FILE__, __func__, __LINE__); \
135 }
136
137#define ASSERT(x) assert(x)
138
139#define DISP_EBI2_LOCAL_DEFINE
140#ifdef DISP_EBI2_LOCAL_DEFINE
141#define LCD_PRIM_BASE_PHYS 0x98000000
142#define LCD_SECD_BASE_PHYS 0x9c000000
143#define EBI2_PRIM_LCD_RS_PIN 0x20000
144#define EBI2_SECD_LCD_RS_PIN 0x20000
145
146#define EBI2_PRIM_LCD_CLR 0xC0
147#define EBI2_PRIM_LCD_SEL 0x40
148
149#define EBI2_SECD_LCD_CLR 0x300
150#define EBI2_SECD_LCD_SEL 0x100
151#endif
152
153extern u32 msm_fb_msg_level;
154
155/*
156 * Message printing priorities:
157 * LEVEL 0 KERN_EMERG (highest priority)
158 * LEVEL 1 KERN_ALERT
159 * LEVEL 2 KERN_CRIT
160 * LEVEL 3 KERN_ERR
161 * LEVEL 4 KERN_WARNING
162 * LEVEL 5 KERN_NOTICE
163 * LEVEL 6 KERN_INFO
164 * LEVEL 7 KERN_DEBUG (Lowest priority)
165 */
166#define MSM_FB_EMERG(msg, ...) \
167 if (msm_fb_msg_level > 0) \
168 printk(KERN_EMERG msg, ## __VA_ARGS__);
169#define MSM_FB_ALERT(msg, ...) \
170 if (msm_fb_msg_level > 1) \
171 printk(KERN_ALERT msg, ## __VA_ARGS__);
172#define MSM_FB_CRIT(msg, ...) \
173 if (msm_fb_msg_level > 2) \
174 printk(KERN_CRIT msg, ## __VA_ARGS__);
175#define MSM_FB_ERR(msg, ...) \
176 if (msm_fb_msg_level > 3) \
177 printk(KERN_ERR msg, ## __VA_ARGS__);
178#define MSM_FB_WARNING(msg, ...) \
179 if (msm_fb_msg_level > 4) \
180 printk(KERN_WARNING msg, ## __VA_ARGS__);
181#define MSM_FB_NOTICE(msg, ...) \
182 if (msm_fb_msg_level > 5) \
183 printk(KERN_NOTICE msg, ## __VA_ARGS__);
184#define MSM_FB_INFO(msg, ...) \
185 if (msm_fb_msg_level > 6) \
186 printk(KERN_INFO msg, ## __VA_ARGS__);
187#define MSM_FB_DEBUG(msg, ...) \
188 if (msm_fb_msg_level > 7) \
189 printk(KERN_DEBUG msg, ## __VA_ARGS__);
190
191#ifdef MSM_FB_C
192unsigned char *msm_mdp_base;
193unsigned char *msm_pmdh_base;
194unsigned char *msm_emdh_base;
195#else
196extern unsigned char *msm_mdp_base;
197extern unsigned char *msm_pmdh_base;
198extern unsigned char *msm_emdh_base;
199#endif
200
201#endif /* MSM_FB_DEF_H */
diff --git a/drivers/staging/msm/msm_fb_panel.c b/drivers/staging/msm/msm_fb_panel.c
new file mode 100644
index 000000000000..b17a239a1bc7
--- /dev/null
+++ b/drivers/staging/msm/msm_fb_panel.c
@@ -0,0 +1,136 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/mm.h>
24#include <linux/fb.h>
25#include <linux/init.h>
26#include <linux/ioport.h>
27#include <linux/device.h>
28#include <linux/dma-mapping.h>
29#include <linux/uaccess.h>
30#include <linux/workqueue.h>
31#include <linux/string.h>
32#include <linux/version.h>
33#include <linux/proc_fs.h>
34#include <linux/vmalloc.h>
35#include <linux/debugfs.h>
36
37#include "msm_fb_panel.h"
38
39int panel_next_on(struct platform_device *pdev)
40{
41 int ret = 0;
42 struct msm_fb_panel_data *pdata;
43 struct msm_fb_panel_data *next_pdata;
44 struct platform_device *next_pdev;
45
46 pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
47
48 if (pdata) {
49 next_pdev = pdata->next;
50 if (next_pdev) {
51 next_pdata =
52 (struct msm_fb_panel_data *)next_pdev->dev.
53 platform_data;
54 if ((next_pdata) && (next_pdata->on))
55 ret = next_pdata->on(next_pdev);
56 }
57 }
58
59 return ret;
60}
61
62int panel_next_off(struct platform_device *pdev)
63{
64 int ret = 0;
65 struct msm_fb_panel_data *pdata;
66 struct msm_fb_panel_data *next_pdata;
67 struct platform_device *next_pdev;
68
69 pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
70
71 if (pdata) {
72 next_pdev = pdata->next;
73 if (next_pdev) {
74 next_pdata =
75 (struct msm_fb_panel_data *)next_pdev->dev.
76 platform_data;
77 if ((next_pdata) && (next_pdata->on))
78 ret = next_pdata->off(next_pdev);
79 }
80 }
81
82 return ret;
83}
84
85struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata,
86 u32 type, u32 id)
87{
88 struct platform_device *this_dev = NULL;
89 char dev_name[16];
90
91 switch (type) {
92 case EBI2_PANEL:
93 snprintf(dev_name, sizeof(dev_name), "ebi2_lcd");
94 break;
95
96 case MDDI_PANEL:
97 snprintf(dev_name, sizeof(dev_name), "mddi");
98 break;
99
100 case EXT_MDDI_PANEL:
101 snprintf(dev_name, sizeof(dev_name), "mddi_ext");
102 break;
103
104 case TV_PANEL:
105 snprintf(dev_name, sizeof(dev_name), "tvenc");
106 break;
107
108 case HDMI_PANEL:
109 case LCDC_PANEL:
110 snprintf(dev_name, sizeof(dev_name), "lcdc");
111 break;
112
113 default:
114 return NULL;
115 }
116
117 if (pdata != NULL)
118 pdata->next = NULL;
119 else
120 return NULL;
121
122 this_dev =
123 platform_device_alloc(dev_name, ((u32) type << 16) | (u32) id);
124
125 if (this_dev) {
126 if (platform_device_add_data
127 (this_dev, pdata, sizeof(struct msm_fb_panel_data))) {
128 printk
129 ("msm_fb_device_alloc: platform_device_add_data failed!\n");
130 platform_device_put(this_dev);
131 return NULL;
132 }
133 }
134
135 return this_dev;
136}
diff --git a/drivers/staging/msm/msm_fb_panel.h b/drivers/staging/msm/msm_fb_panel.h
new file mode 100644
index 000000000000..ab458310c3a2
--- /dev/null
+++ b/drivers/staging/msm/msm_fb_panel.h
@@ -0,0 +1,145 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef MSM_FB_PANEL_H
30#define MSM_FB_PANEL_H
31
32#include "msm_fb_def.h"
33
34struct msm_fb_data_type;
35
36typedef void (*msm_fb_vsync_handler_type) (void *arg);
37
38/* panel id type */
39typedef struct panel_id_s {
40 uint16 id;
41 uint16 type;
42} panel_id_type;
43
44/* panel type list */
45#define NO_PANEL 0xffff /* No Panel */
46#define MDDI_PANEL 1 /* MDDI */
47#define EBI2_PANEL 2 /* EBI2 */
48#define LCDC_PANEL 3 /* internal LCDC type */
49#define EXT_MDDI_PANEL 4 /* Ext.MDDI */
50#define TV_PANEL 5 /* TV */
51#define HDMI_PANEL 6 /* HDMI TV */
52
53/* panel class */
54typedef enum {
55 DISPLAY_LCD = 0, /* lcd = ebi2/mddi */
56 DISPLAY_LCDC, /* lcdc */
57 DISPLAY_TV, /* TV Out */
58 DISPLAY_EXT_MDDI, /* External MDDI */
59} DISP_TARGET;
60
61/* panel device locaiton */
62typedef enum {
63 DISPLAY_1 = 0, /* attached as first device */
64 DISPLAY_2, /* attached on second device */
65 MAX_PHYS_TARGET_NUM,
66} DISP_TARGET_PHYS;
67
68/* panel info type */
69struct lcd_panel_info {
70 __u32 vsync_enable;
71 __u32 refx100;
72 __u32 v_back_porch;
73 __u32 v_front_porch;
74 __u32 v_pulse_width;
75 __u32 hw_vsync_mode;
76 __u32 vsync_notifier_period;
77};
78
79struct lcdc_panel_info {
80 __u32 h_back_porch;
81 __u32 h_front_porch;
82 __u32 h_pulse_width;
83 __u32 v_back_porch;
84 __u32 v_front_porch;
85 __u32 v_pulse_width;
86 __u32 border_clr;
87 __u32 underflow_clr;
88 __u32 hsync_skew;
89};
90
91struct mddi_panel_info {
92 __u32 vdopkt;
93};
94
95struct msm_panel_info {
96 __u32 xres;
97 __u32 yres;
98 __u32 bpp;
99 __u32 type;
100 __u32 wait_cycle;
101 DISP_TARGET_PHYS pdest;
102 __u32 bl_max;
103 __u32 bl_min;
104 __u32 fb_num;
105 __u32 clk_rate;
106 __u32 clk_min;
107 __u32 clk_max;
108 __u32 frame_count;
109
110 union {
111 struct mddi_panel_info mddi;
112 };
113
114 union {
115 struct lcd_panel_info lcd;
116 struct lcdc_panel_info lcdc;
117 };
118};
119
120struct msm_fb_panel_data {
121 struct msm_panel_info panel_info;
122 void (*set_rect) (int x, int y, int xres, int yres);
123 void (*set_vsync_notifier) (msm_fb_vsync_handler_type, void *arg);
124 void (*set_backlight) (struct msm_fb_data_type *);
125
126 /* function entry chain */
127 int (*on) (struct platform_device *pdev);
128 int (*off) (struct platform_device *pdev);
129 struct platform_device *next;
130};
131
132/*===========================================================================
133 FUNCTIONS PROTOTYPES
134============================================================================*/
135struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata,
136 u32 type, u32 id);
137int panel_next_on(struct platform_device *pdev);
138int panel_next_off(struct platform_device *pdev);
139
140int lcdc_device_register(struct msm_panel_info *pinfo);
141
142int mddi_toshiba_device_register(struct msm_panel_info *pinfo,
143 u32 channel, u32 panel);
144
145#endif /* MSM_FB_PANEL_H */
diff --git a/drivers/staging/msm/msm_mdp.h b/drivers/staging/msm/msm_mdp.h
new file mode 100644
index 000000000000..2d5323f5b62d
--- /dev/null
+++ b/drivers/staging/msm/msm_mdp.h
@@ -0,0 +1,245 @@
1/* include/linux/msm_mdp.h
2 *
3 * Copyright (C) 2007 Google Incorporated
4 * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
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#ifndef _MSM_MDP_H_
16#define _MSM_MDP_H_
17
18#include <linux/types.h>
19#include <linux/fb.h>
20
21#define MSMFB_IOCTL_MAGIC 'm'
22#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int)
23#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int)
24#define MSMFB_SUSPEND_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 128, unsigned int)
25#define MSMFB_RESUME_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 129, unsigned int)
26#define MSMFB_CURSOR _IOW(MSMFB_IOCTL_MAGIC, 130, struct fb_cursor)
27#define MSMFB_SET_LUT _IOW(MSMFB_IOCTL_MAGIC, 131, struct fb_cmap)
28#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram)
29/* new ioctls's for set/get ccs matrix */
30#define MSMFB_GET_CCS_MATRIX _IOWR(MSMFB_IOCTL_MAGIC, 133, struct mdp_ccs)
31#define MSMFB_SET_CCS_MATRIX _IOW(MSMFB_IOCTL_MAGIC, 134, struct mdp_ccs)
32#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \
33 struct mdp_overlay)
34#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int)
35#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \
36 struct msmfb_overlay_data)
37#define MSMFB_GET_PAGE_PROTECTION _IOR(MSMFB_IOCTL_MAGIC, 138, \
38 struct mdp_page_protection)
39#define MSMFB_SET_PAGE_PROTECTION _IOW(MSMFB_IOCTL_MAGIC, 139, \
40 struct mdp_page_protection)
41#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \
42 struct mdp_overlay)
43
44/* new ioctls for async MDP ops */
45#define MSMFB_ASYNC_BLIT _IOW(MSMFB_IOCTL_MAGIC, 141, unsigned int)
46#define MSMFB_BLIT_FLUSH _IOR(MSMFB_IOCTL_MAGIC, 142, unsigned int)
47
48#define MDP_IMGTYPE2_START 0x10000
49
50enum {
51 MDP_RGB_565, /* RGB 565 planer */
52 MDP_XRGB_8888, /* RGB 888 padded */
53 MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planer w/ Cb is in MSB */
54 MDP_ARGB_8888, /* ARGB 888 */
55 MDP_RGB_888, /* RGB 888 planer */
56 MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planer w/ Cr is in MSB */
57 MDP_YCRYCB_H2V1, /* YCrYCb interleave */
58 MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */
59 MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */
60 MDP_RGBA_8888, /* ARGB 888 */
61 MDP_BGRA_8888, /* ABGR 888 */
62 MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */
63 MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */
64 MDP_IMGTYPE_LIMIT,
65 MDP_BGR_565 = MDP_IMGTYPE2_START, /* BGR 565 planer */
66 MDP_FB_FORMAT, /* framebuffer format */
67 MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */
68};
69
70enum {
71 PMEM_IMG,
72 FB_IMG,
73};
74
75/* mdp_blit_req flag values */
76#define MDP_ROT_NOP 0
77#define MDP_FLIP_LR 0x1
78#define MDP_FLIP_UD 0x2
79#define MDP_ROT_90 0x4
80#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR)
81#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR)
82#define MDP_DITHER 0x8
83#define MDP_BLUR 0x10
84#define MDP_BLEND_FG_PREMULT 0x20000
85
86#define MDP_DEINTERLACE 0x80000000
87#define MDP_SHARPENING 0x40000000
88
89#define MDP_NO_DMA_BARRIER_START 0x20000000
90#define MDP_NO_DMA_BARRIER_END 0x10000000
91#define MDP_NO_BLIT 0x08000000
92#define MDP_BLIT_WITH_DMA_BARRIERS 0x000
93#define MDP_BLIT_WITH_NO_DMA_BARRIERS \
94 (MDP_NO_DMA_BARRIER_START | MDP_NO_DMA_BARRIER_END)
95#define MDP_TRANSP_NOP 0xffffffff
96#define MDP_ALPHA_NOP 0xff
97
98#define MDP_BLIT_SRC_GEM 0x02000000 /* set for GEM, clear for PMEM */
99#define MDP_BLIT_DST_GEM 0x01000000 /* set for GEM, clear for PMEM */
100
101#define MDP_FB_PAGE_PROTECTION_NONCACHED (0)
102#define MDP_FB_PAGE_PROTECTION_WRITECOMBINE (1)
103#define MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE (2)
104#define MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE (3)
105#define MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE (4)
106/* Sentinel: Don't use! */
107#define MDP_FB_PAGE_PROTECTION_INVALID (5)
108/* Count of the number of MDP_FB_PAGE_PROTECTION_... values. */
109#define MDP_NUM_FB_PAGE_PROTECTION_VALUES (5)
110
111struct mdp_rect {
112 uint32_t x;
113 uint32_t y;
114 uint32_t w;
115 uint32_t h;
116};
117
118struct mdp_img {
119 uint32_t width;
120 uint32_t height;
121 uint32_t format;
122 uint32_t offset;
123 int memory_id; /* the file descriptor */
124 uint32_t priv;
125};
126
127/*
128 * {3x3} + {3} ccs matrix
129 */
130
131#define MDP_CCS_RGB2YUV 0
132#define MDP_CCS_YUV2RGB 1
133
134#define MDP_CCS_SIZE 9
135#define MDP_BV_SIZE 3
136
137struct mdp_ccs {
138 int direction; /* MDP_CCS_RGB2YUV or YUV2RGB */
139 uint16_t ccs[MDP_CCS_SIZE]; /* 3x3 color coefficients */
140 uint16_t bv[MDP_BV_SIZE]; /* 1x3 bias vector */
141};
142
143/* The version of the mdp_blit_req structure so that
144 * user applications can selectively decide which functionality
145 * to include
146 */
147
148#define MDP_BLIT_REQ_VERSION 2
149
150struct mdp_blit_req {
151 struct mdp_img src;
152 struct mdp_img dst;
153 struct mdp_rect src_rect;
154 struct mdp_rect dst_rect;
155 uint32_t alpha;
156 uint32_t transp_mask;
157 uint32_t flags;
158 int sharpening_strength; /* -127 <--> 127, default 64 */
159};
160
161struct mdp_blit_req_list {
162 uint32_t count;
163 struct mdp_blit_req req[];
164};
165
166struct msmfb_data {
167 uint32_t offset;
168 int memory_id;
169 int id;
170};
171
172#define MSMFB_NEW_REQUEST -1
173
174struct msmfb_overlay_data {
175 uint32_t id;
176 struct msmfb_data data;
177};
178
179struct msmfb_img {
180 uint32_t width;
181 uint32_t height;
182 uint32_t format;
183};
184
185struct mdp_overlay {
186 struct msmfb_img src;
187 struct mdp_rect src_rect;
188 struct mdp_rect dst_rect;
189 uint32_t z_order; /* stage number */
190 uint32_t is_fg; /* control alpha & transp */
191 uint32_t alpha;
192 uint32_t transp_mask;
193 uint32_t flags;
194 uint32_t id;
195 uint32_t user_data[8];
196};
197
198struct mdp_histogram {
199 uint32_t frame_cnt;
200 uint32_t bin_cnt;
201 uint32_t *r;
202 uint32_t *g;
203 uint32_t *b;
204};
205
206struct mdp_page_protection {
207 uint32_t page_protection;
208};
209
210
211struct msm_panel_common_pdata {
212 int gpio;
213 int (*backlight_level)(int level, int max, int min);
214 int (*pmic_backlight)(int level);
215 int (*panel_num)(void);
216 void (*panel_config_gpio)(int);
217 int *gpio_num;
218};
219
220struct lcdc_platform_data {
221 int (*lcdc_gpio_config)(int on);
222 void (*lcdc_power_save)(int);
223};
224
225struct tvenc_platform_data {
226 int (*pm_vid_en)(int on);
227};
228
229struct mddi_platform_data {
230 void (*mddi_power_save)(int on);
231 int (*mddi_sel_clk)(u32 *clk_rate);
232};
233
234struct msm_fb_platform_data {
235 int (*detect_client)(const char *name);
236 int mddi_prescan;
237 int (*allow_set_offset)(void);
238};
239
240struct msm_hdmi_platform_data {
241 int irq;
242 int (*cable_detect)(int insert);
243};
244
245#endif /*_MSM_MDP_H_*/
diff --git a/drivers/staging/msm/staging-devices.c b/drivers/staging/msm/staging-devices.c
new file mode 100644
index 000000000000..0f8ec3e26013
--- /dev/null
+++ b/drivers/staging/msm/staging-devices.c
@@ -0,0 +1,323 @@
1#include <linux/kernel.h>
2#include <linux/irq.h>
3#include <linux/gpio.h>
4#include <linux/platform_device.h>
5#include <linux/bootmem.h>
6#include <linux/delay.h>
7
8#include <asm/mach-types.h>
9#include <asm/mach/arch.h>
10#include <asm/io.h>
11#include <asm/setup.h>
12
13#include <mach/board.h>
14#include <mach/irqs.h>
15#include <mach/sirc.h>
16#include <mach/gpio.h>
17
18#include "msm_mdp.h"
19#include "memory_ll.h"
20//#include "android_pmem.h"
21#include <mach/board.h>
22
23#ifdef CONFIG_MSM_SOC_REV_A
24#define MSM_SMI_BASE 0xE0000000
25#else
26#define MSM_SMI_BASE 0x00000000
27#endif
28
29
30#define TOUCHPAD_SUSPEND 34
31#define TOUCHPAD_IRQ 38
32
33#define MSM_PMEM_MDP_SIZE 0x1591000
34
35#ifdef CONFIG_MSM_SOC_REV_A
36#define SMEM_SPINLOCK_I2C "D:I2C02000021"
37#else
38#define SMEM_SPINLOCK_I2C "S:6"
39#endif
40
41#define MSM_PMEM_ADSP_SIZE 0x1C00000
42
43#define MSM_FB_SIZE 0x500000
44#define MSM_FB_SIZE_ST15 0x800000
45#define MSM_AUDIO_SIZE 0x80000
46#define MSM_GPU_PHYS_SIZE SZ_2M
47
48#ifdef CONFIG_MSM_SOC_REV_A
49#define MSM_SMI_BASE 0xE0000000
50#else
51#define MSM_SMI_BASE 0x00000000
52#endif
53
54#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000)
55
56#define MSM_PMEM_SMI_BASE (MSM_SMI_BASE + 0x02B00000)
57#define MSM_PMEM_SMI_SIZE 0x01500000
58
59#define MSM_FB_BASE MSM_PMEM_SMI_BASE
60#define MSM_GPU_PHYS_BASE (MSM_FB_BASE + MSM_FB_SIZE)
61#define MSM_PMEM_SMIPOOL_BASE (MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE)
62#define MSM_PMEM_SMIPOOL_SIZE (MSM_PMEM_SMI_SIZE - MSM_FB_SIZE \
63 - MSM_GPU_PHYS_SIZE)
64
65#if defined(CONFIG_FB_MSM_MDP40)
66#define MDP_BASE 0xA3F00000
67#define PMDH_BASE 0xAD600000
68#define EMDH_BASE 0xAD700000
69#define TVENC_BASE 0xAD400000
70#else
71#define MDP_BASE 0xAA200000
72#define PMDH_BASE 0xAA600000
73#define EMDH_BASE 0xAA700000
74#define TVENC_BASE 0xAA400000
75#endif
76
77#define PMEM_KERNEL_EBI1_SIZE (CONFIG_PMEM_KERNEL_SIZE * 1024 * 1024)
78
79static struct resource msm_fb_resources[] = {
80 {
81 .flags = IORESOURCE_DMA,
82 }
83};
84
85static struct resource msm_mdp_resources[] = {
86 {
87 .name = "mdp",
88 .start = MDP_BASE,
89 .end = MDP_BASE + 0x000F0000 - 1,
90 .flags = IORESOURCE_MEM,
91 }
92};
93
94static struct platform_device msm_mdp_device = {
95 .name = "mdp",
96 .id = 0,
97 .num_resources = ARRAY_SIZE(msm_mdp_resources),
98 .resource = msm_mdp_resources,
99};
100
101static struct platform_device msm_lcdc_device = {
102 .name = "lcdc",
103 .id = 0,
104};
105
106static int msm_fb_detect_panel(const char *name)
107{
108 int ret = -EPERM;
109
110 if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) {
111 if (!strncmp(name, "mddi_toshiba_wvga_pt", 20))
112 ret = 0;
113 else
114 ret = -ENODEV;
115 } else if ((machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf())
116 && !strcmp(name, "lcdc_external"))
117 ret = 0;
118 else if (0 /*machine_is_qsd8x50_grapefruit() */) {
119 if (!strcmp(name, "lcdc_grapefruit_vga"))
120 ret = 0;
121 else
122 ret = -ENODEV;
123 } else if (machine_is_qsd8x50_st1()) {
124 if (!strcmp(name, "lcdc_st1_wxga"))
125 ret = 0;
126 else
127 ret = -ENODEV;
128 } else if (machine_is_qsd8x50a_st1_5()) {
129 if (!strcmp(name, "lcdc_st15") ||
130 !strcmp(name, "hdmi_sii9022"))
131 ret = 0;
132 else
133 ret = -ENODEV;
134 }
135
136 return ret;
137}
138
139/* Only allow a small subset of machines to set the offset via
140 FB PAN_DISPLAY */
141
142static int msm_fb_allow_set_offset(void)
143{
144 return (machine_is_qsd8x50_st1() ||
145 machine_is_qsd8x50a_st1_5()) ? 1 : 0;
146}
147
148
149static struct msm_fb_platform_data msm_fb_pdata = {
150 .detect_client = msm_fb_detect_panel,
151 .allow_set_offset = msm_fb_allow_set_offset,
152};
153
154static struct platform_device msm_fb_device = {
155 .name = "msm_fb",
156 .id = 0,
157 .num_resources = ARRAY_SIZE(msm_fb_resources),
158 .resource = msm_fb_resources,
159 .dev = {
160 .platform_data = &msm_fb_pdata,
161 }
162};
163
164static void __init qsd8x50_allocate_memory_regions(void)
165{
166 void *addr;
167 unsigned long size;
168 if (machine_is_qsd8x50a_st1_5())
169 size = MSM_FB_SIZE_ST15;
170 else
171 size = MSM_FB_SIZE;
172
173 addr = alloc_bootmem(size); // (void *)MSM_FB_BASE;
174 if (!addr)
175 printk("Failed to allocate bootmem for framebuffer\n");
176
177
178 msm_fb_resources[0].start = __pa(addr);
179 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
180 pr_info(KERN_ERR "using %lu bytes of SMI at %lx physical for fb\n",
181 size, (unsigned long)addr);
182}
183
184static int msm_fb_lcdc_gpio_config(int on)
185{
186// return 0;
187 if (machine_is_qsd8x50_st1()) {
188 if (on) {
189 gpio_set_value(32, 1);
190 mdelay(100);
191 gpio_set_value(20, 1);
192 gpio_set_value(17, 1);
193 gpio_set_value(19, 1);
194 } else {
195 gpio_set_value(17, 0);
196 gpio_set_value(19, 0);
197 gpio_set_value(20, 0);
198 mdelay(100);
199 gpio_set_value(32, 0);
200 }
201 } else if (machine_is_qsd8x50a_st1_5()) {
202 if (on) {
203 gpio_set_value(17, 1);
204 gpio_set_value(19, 1);
205 gpio_set_value(20, 1);
206 gpio_set_value(22, 0);
207 gpio_set_value(32, 1);
208 gpio_set_value(155, 1);
209 //st15_hdmi_power(1);
210 gpio_set_value(22, 1);
211
212 } else {
213 gpio_set_value(17, 0);
214 gpio_set_value(19, 0);
215 gpio_set_value(22, 0);
216 gpio_set_value(32, 0);
217 gpio_set_value(155, 0);
218 // st15_hdmi_power(0);
219 }
220 }
221 return 0;
222}
223
224
225static struct lcdc_platform_data lcdc_pdata = {
226 .lcdc_gpio_config = msm_fb_lcdc_gpio_config,
227};
228
229static struct msm_gpio msm_fb_st15_gpio_config_data[] = {
230 { GPIO_CFG(17, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en0" },
231 { GPIO_CFG(19, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "dat_pwr_sv" },
232 { GPIO_CFG(20, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lvds_pwr_dn" },
233 { GPIO_CFG(22, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en1" },
234 { GPIO_CFG(32, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en2" },
235 { GPIO_CFG(103, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_irq" },
236 { GPIO_CFG(155, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_3v3" },
237};
238
239static struct msm_panel_common_pdata mdp_pdata = {
240 .gpio = 98,
241};
242
243static struct platform_device *devices[] __initdata = {
244 &msm_fb_device,
245};
246
247
248static void __init msm_register_device(struct platform_device *pdev, void *data)
249{
250 int ret;
251
252 pdev->dev.platform_data = data;
253
254 ret = platform_device_register(pdev);
255 if (ret)
256 dev_err(&pdev->dev,
257 "%s: platform_device_register() failed = %d\n",
258 __func__, ret);
259}
260
261void __init msm_fb_register_device(char *name, void *data)
262{
263 if (!strncmp(name, "mdp", 3))
264 msm_register_device(&msm_mdp_device, data);
265/*
266 else if (!strncmp(name, "pmdh", 4))
267 msm_register_device(&msm_mddi_device, data);
268 else if (!strncmp(name, "emdh", 4))
269 msm_register_device(&msm_mddi_ext_device, data);
270 else if (!strncmp(name, "ebi2", 4))
271 msm_register_device(&msm_ebi2_lcd_device, data);
272 else if (!strncmp(name, "tvenc", 5))
273 msm_register_device(&msm_tvenc_device, data);
274 else */
275
276 if (!strncmp(name, "lcdc", 4))
277 msm_register_device(&msm_lcdc_device, data);
278 /*else
279 printk(KERN_ERR "%s: unknown device! %s\n", __func__, name);
280*/
281}
282
283static void __init msm_fb_add_devices(void)
284{
285 int rc;
286 msm_fb_register_device("mdp", &mdp_pdata);
287// msm_fb_register_device("pmdh", &mddi_pdata);
288// msm_fb_register_device("emdh", &mddi_pdata);
289// msm_fb_register_device("tvenc", 0);
290
291 if (machine_is_qsd8x50a_st1_5()) {
292/* rc = st15_hdmi_vreg_init();
293 if (rc)
294 return;
295*/
296 rc = msm_gpios_request_enable(
297 msm_fb_st15_gpio_config_data,
298 ARRAY_SIZE(msm_fb_st15_gpio_config_data));
299 if (rc) {
300 printk(KERN_ERR "%s: unable to init lcdc gpios\n",
301 __func__);
302 return;
303 }
304 msm_fb_register_device("lcdc", &lcdc_pdata);
305 } else
306 msm_fb_register_device("lcdc", 0);
307}
308
309int __init staging_init_pmem(void)
310{
311 qsd8x50_allocate_memory_regions();
312 return 0;
313}
314
315int __init staging_init_devices(void)
316{
317 platform_add_devices(devices, ARRAY_SIZE(devices));
318 msm_fb_add_devices();
319 return 0;
320}
321
322arch_initcall(staging_init_pmem);
323arch_initcall(staging_init_devices);
diff --git a/drivers/staging/msm/tv_ntsc.c b/drivers/staging/msm/tv_ntsc.c
new file mode 100644
index 000000000000..5eb67611661a
--- /dev/null
+++ b/drivers/staging/msm/tv_ntsc.c
@@ -0,0 +1,163 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/uaccess.h>
33#include <linux/clk.h>
34
35#include "msm_fb.h"
36#include "tvenc.h"
37
38#define NTSC_TV_DIMENSION_WIDTH 720
39#define NTSC_TV_DIMENSION_HEIGHT 480
40
41static int ntsc_off(struct platform_device *pdev);
42static int ntsc_on(struct platform_device *pdev);
43
44static int ntsc_on(struct platform_device *pdev)
45{
46 uint32 reg = 0;
47 int ret = 0;
48 struct msm_fb_data_type *mfd;
49
50 mfd = platform_get_drvdata(pdev);
51
52 if (!mfd)
53 return -ENODEV;
54
55 if (mfd->key != MFD_KEY)
56 return -EINVAL;
57
58 TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
59
60 if (mfd->panel.id == NTSC_M) {
61 /* Cr gain 11, Cb gain C6, y_gain 97 */
62 TV_OUT(TV_GAIN, 0x0081B697);
63 } else {
64 /* Cr gain 11, Cb gain C6, y_gain 97 */
65 TV_OUT(TV_GAIN, 0x008bc4a3);
66 reg |= TVENC_CTL_NTSCJ_MODE;
67 }
68
69 TV_OUT(TV_CGMS, 0x0);
70 /* NTSC Timing */
71 TV_OUT(TV_SYNC_1, 0x0020009e);
72 TV_OUT(TV_SYNC_2, 0x011306B4);
73 TV_OUT(TV_SYNC_3, 0x0006000C);
74 TV_OUT(TV_SYNC_4, 0x0028020D);
75 TV_OUT(TV_SYNC_5, 0x005E02FB);
76 TV_OUT(TV_SYNC_6, 0x0006000C);
77 TV_OUT(TV_SYNC_7, 0x00000012);
78 TV_OUT(TV_BURST_V1, 0x0013020D);
79 TV_OUT(TV_BURST_V2, 0x0014020C);
80 TV_OUT(TV_BURST_V3, 0x0013020D);
81 TV_OUT(TV_BURST_V4, 0x0014020C);
82 TV_OUT(TV_BURST_H, 0x00AE00F2);
83 TV_OUT(TV_SOL_REQ_ODD, 0x00280208);
84 TV_OUT(TV_SOL_REQ_EVEN, 0x00290209);
85
86 reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60;
87
88 reg |= TVENC_CTL_Y_FILTER_EN |
89 TVENC_CTL_CR_FILTER_EN |
90 TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN;
91#ifdef CONFIG_FB_MSM_TVOUT_SVIDEO
92 reg |= TVENC_CTL_S_VIDEO_EN;
93#endif
94
95 TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */
96 TV_OUT(TV_OFFSET, 0x008080f0);
97
98#ifdef CONFIG_FB_MSM_MDP31
99 TV_OUT(TV_DAC_INTF, 0x29);
100#endif
101 TV_OUT(TV_ENC_CTL, reg);
102
103 reg |= TVENC_CTL_ENC_EN;
104 TV_OUT(TV_ENC_CTL, reg);
105
106 return ret;
107}
108
109static int ntsc_off(struct platform_device *pdev)
110{
111 TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
112 return 0;
113}
114
115static int __init ntsc_probe(struct platform_device *pdev)
116{
117 msm_fb_add_device(pdev);
118
119 return 0;
120}
121
122static struct platform_driver this_driver = {
123 .probe = ntsc_probe,
124 .driver = {
125 .name = "tv_ntsc",
126 },
127};
128
129static struct msm_fb_panel_data ntsc_panel_data = {
130 .panel_info.xres = NTSC_TV_DIMENSION_WIDTH,
131 .panel_info.yres = NTSC_TV_DIMENSION_HEIGHT,
132 .panel_info.type = TV_PANEL,
133 .panel_info.pdest = DISPLAY_1,
134 .panel_info.wait_cycle = 0,
135 .panel_info.bpp = 16,
136 .panel_info.fb_num = 2,
137 .on = ntsc_on,
138 .off = ntsc_off,
139};
140
141static struct platform_device this_device = {
142 .name = "tv_ntsc",
143 .id = 0,
144 .dev = {
145 .platform_data = &ntsc_panel_data,
146 }
147};
148
149static int __init ntsc_init(void)
150{
151 int ret;
152
153 ret = platform_driver_register(&this_driver);
154 if (!ret) {
155 ret = platform_device_register(&this_device);
156 if (ret)
157 platform_driver_unregister(&this_driver);
158 }
159
160 return ret;
161}
162
163module_init(ntsc_init); \ No newline at end of file
diff --git a/drivers/staging/msm/tv_pal.c b/drivers/staging/msm/tv_pal.c
new file mode 100644
index 000000000000..204da514660e
--- /dev/null
+++ b/drivers/staging/msm/tv_pal.c
@@ -0,0 +1,213 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/time.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/spinlock.h>
24#include <linux/delay.h>
25#include <mach/hardware.h>
26#include <linux/io.h>
27
28#include <asm/system.h>
29#include <asm/mach-types.h>
30#include <linux/semaphore.h>
31#include <linux/uaccess.h>
32#include <linux/clk.h>
33
34#include "msm_fb.h"
35#include "tvenc.h"
36
37#ifdef CONFIG_FB_MSM_TVOUT_PAL_M
38#define PAL_TV_DIMENSION_WIDTH 720
39#define PAL_TV_DIMENSION_HEIGHT 480
40#else
41#define PAL_TV_DIMENSION_WIDTH 720
42#define PAL_TV_DIMENSION_HEIGHT 576
43#endif
44
45static int pal_on(struct platform_device *pdev)
46{
47 uint32 reg = 0;
48 int ret = 0;
49 struct msm_fb_data_type *mfd;
50
51 mfd = platform_get_drvdata(pdev);
52
53 if (!mfd)
54 return -ENODEV;
55
56 if (mfd->key != MFD_KEY)
57 return -EINVAL;
58
59 TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
60
61 switch (mfd->panel.id) {
62 case PAL_BDGHIN:
63 /* Cr gain 11, Cb gain C6, y_gain 97 */
64 TV_OUT(TV_GAIN, 0x0088c1a0);
65 TV_OUT(TV_CGMS, 0x00012345);
66 TV_OUT(TV_TEST_MUX, 0x0);
67 /* PAL Timing */
68 TV_OUT(TV_SYNC_1, 0x00180097);
69 TV_OUT(TV_SYNC_2, 0x011f06c0);
70 TV_OUT(TV_SYNC_3, 0x0005000a);
71 TV_OUT(TV_SYNC_4, 0x00320271);
72 TV_OUT(TV_SYNC_5, 0x005602f9);
73 TV_OUT(TV_SYNC_6, 0x0005000a);
74 TV_OUT(TV_SYNC_7, 0x0000000f);
75 TV_OUT(TV_BURST_V1, 0x0012026e);
76 TV_OUT(TV_BURST_V2, 0x0011026d);
77 TV_OUT(TV_BURST_V3, 0x00100270);
78 TV_OUT(TV_BURST_V4, 0x0013026f);
79 TV_OUT(TV_BURST_H, 0x00af00ea);
80 TV_OUT(TV_SOL_REQ_ODD, 0x0030026e);
81 TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f);
82
83 reg |= TVENC_CTL_TV_MODE_PAL_BDGHIN;
84 break;
85 case PAL_M:
86 /* Cr gain 11, Cb gain C6, y_gain 97 */
87 TV_OUT(TV_GAIN, 0x0081b697);
88 TV_OUT(TV_CGMS, 0x000af317);
89 TV_OUT(TV_TEST_MUX, 0x000001c3);
90 TV_OUT(TV_TEST_MODE, 0x00000002);
91 /* PAL Timing */
92 TV_OUT(TV_SYNC_1, 0x0020009e);
93 TV_OUT(TV_SYNC_2, 0x011306b4);
94 TV_OUT(TV_SYNC_3, 0x0006000c);
95 TV_OUT(TV_SYNC_4, 0x0028020D);
96 TV_OUT(TV_SYNC_5, 0x005e02fb);
97 TV_OUT(TV_SYNC_6, 0x0006000c);
98 TV_OUT(TV_SYNC_7, 0x00000012);
99 TV_OUT(TV_BURST_V1, 0x0012020b);
100 TV_OUT(TV_BURST_V2, 0x0016020c);
101 TV_OUT(TV_BURST_V3, 0x00150209);
102 TV_OUT(TV_BURST_V4, 0x0013020c);
103 TV_OUT(TV_BURST_H, 0x00bf010b);
104 TV_OUT(TV_SOL_REQ_ODD, 0x00280208);
105 TV_OUT(TV_SOL_REQ_EVEN, 0x00290209);
106
107 reg |= TVENC_CTL_TV_MODE_PAL_M;
108 break;
109 case PAL_N:
110 /* Cr gain 11, Cb gain C6, y_gain 97 */
111 TV_OUT(TV_GAIN, 0x0081b697);
112 TV_OUT(TV_CGMS, 0x000af317);
113 TV_OUT(TV_TEST_MUX, 0x000001c3);
114 TV_OUT(TV_TEST_MODE, 0x00000002);
115 /* PAL Timing */
116 TV_OUT(TV_SYNC_1, 0x00180097);
117 TV_OUT(TV_SYNC_2, 0x12006c0);
118 TV_OUT(TV_SYNC_3, 0x0005000a);
119 TV_OUT(TV_SYNC_4, 0x00320271);
120 TV_OUT(TV_SYNC_5, 0x005602f9);
121 TV_OUT(TV_SYNC_6, 0x0005000a);
122 TV_OUT(TV_SYNC_7, 0x0000000f);
123 TV_OUT(TV_BURST_V1, 0x0012026e);
124 TV_OUT(TV_BURST_V2, 0x0011026d);
125 TV_OUT(TV_BURST_V3, 0x00100270);
126 TV_OUT(TV_BURST_V4, 0x0013026f);
127 TV_OUT(TV_BURST_H, 0x00af00fa);
128 TV_OUT(TV_SOL_REQ_ODD, 0x0030026e);
129 TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f);
130
131 reg |= TVENC_CTL_TV_MODE_PAL_N;
132 break;
133
134 default:
135 return -ENODEV;
136 }
137
138 reg |= TVENC_CTL_Y_FILTER_EN |
139 TVENC_CTL_CR_FILTER_EN |
140 TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN;
141#ifdef CONFIG_FB_MSM_TVOUT_SVIDEO
142 reg |= TVENC_CTL_S_VIDEO_EN;
143#endif
144
145 TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */
146 TV_OUT(TV_OFFSET, 0x008080f0);
147
148#ifdef CONFIG_FB_MSM_MDP31
149 TV_OUT(TV_DAC_INTF, 0x29);
150#endif
151 TV_OUT(TV_ENC_CTL, reg);
152
153 reg |= TVENC_CTL_ENC_EN;
154 TV_OUT(TV_ENC_CTL, reg);
155
156 return ret;
157}
158
159static int pal_off(struct platform_device *pdev)
160{
161 TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
162 return 0;
163}
164
165static int __init pal_probe(struct platform_device *pdev)
166{
167 msm_fb_add_device(pdev);
168
169 return 0;
170}
171
172static struct platform_driver this_driver = {
173 .probe = pal_probe,
174 .driver = {
175 .name = "tv_pal",
176 },
177};
178
179static struct msm_fb_panel_data pal_panel_data = {
180 .panel_info.xres = PAL_TV_DIMENSION_WIDTH,
181 .panel_info.yres = PAL_TV_DIMENSION_HEIGHT,
182 .panel_info.type = TV_PANEL,
183 .panel_info.pdest = DISPLAY_1,
184 .panel_info.wait_cycle = 0,
185 .panel_info.bpp = 16,
186 .panel_info.fb_num = 2,
187 .on = pal_on,
188 .off = pal_off,
189};
190
191static struct platform_device this_device = {
192 .name = "tv_pal",
193 .id = 0,
194 .dev = {
195 .platform_data = &pal_panel_data,
196 }
197};
198
199static int __init pal_init(void)
200{
201 int ret;
202
203 ret = platform_driver_register(&this_driver);
204 if (!ret) {
205 ret = platform_device_register(&this_device);
206 if (ret)
207 platform_driver_unregister(&this_driver);
208 }
209
210 return ret;
211}
212
213module_init(pal_init);
diff --git a/drivers/staging/msm/tvenc.c b/drivers/staging/msm/tvenc.c
new file mode 100644
index 000000000000..f41c5ac22f25
--- /dev/null
+++ b/drivers/staging/msm/tvenc.c
@@ -0,0 +1,295 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/uaccess.h>
33#include <linux/clk.h>
34#include <linux/platform_device.h>
35#include <linux/pm_qos_params.h>
36
37#define TVENC_C
38#include "tvenc.h"
39#include "msm_fb.h"
40
41static int tvenc_probe(struct platform_device *pdev);
42static int tvenc_remove(struct platform_device *pdev);
43
44static int tvenc_off(struct platform_device *pdev);
45static int tvenc_on(struct platform_device *pdev);
46
47static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
48static int pdev_list_cnt;
49
50static struct clk *tvenc_clk;
51static struct clk *tvdac_clk;
52
53static struct platform_driver tvenc_driver = {
54 .probe = tvenc_probe,
55 .remove = tvenc_remove,
56 .suspend = NULL,
57// .suspend_late = NULL,
58// .resume_early = NULL,
59 .resume = NULL,
60 .shutdown = NULL,
61 .driver = {
62 .name = "tvenc",
63 },
64};
65
66static struct tvenc_platform_data *tvenc_pdata;
67
68static int tvenc_off(struct platform_device *pdev)
69{
70 int ret = 0;
71
72 ret = panel_next_off(pdev);
73
74 clk_disable(tvenc_clk);
75 clk_disable(tvdac_clk);
76
77 if (tvenc_pdata && tvenc_pdata->pm_vid_en)
78 ret = tvenc_pdata->pm_vid_en(0);
79
80 //pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc",
81 // PM_QOS_DEFAULT_VALUE);
82
83 if (ret)
84 printk(KERN_ERR "%s: pm_vid_en(off) failed! %d\n",
85 __func__, ret);
86
87 return ret;
88}
89
90static int tvenc_on(struct platform_device *pdev)
91{
92 int ret = 0;
93
94// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc",
95// 128000);
96 if (tvenc_pdata && tvenc_pdata->pm_vid_en)
97 ret = tvenc_pdata->pm_vid_en(1);
98
99 if (ret) {
100 printk(KERN_ERR "%s: pm_vid_en(on) failed! %d\n",
101 __func__, ret);
102 return ret;
103 }
104
105 clk_enable(tvenc_clk);
106 clk_enable(tvdac_clk);
107
108 ret = panel_next_on(pdev);
109
110 return ret;
111}
112
113void tvenc_gen_test_pattern(struct msm_fb_data_type *mfd)
114{
115 uint32 reg = 0, i;
116
117 reg = readl(MSM_TV_ENC_CTL);
118 reg |= TVENC_CTL_TEST_PATT_EN;
119
120 for (i = 0; i < 3; i++) {
121 TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
122
123 switch (i) {
124 /*
125 * TV Encoder - Color Bar Test Pattern
126 */
127 case 0:
128 reg |= TVENC_CTL_TPG_CLRBAR;
129 break;
130 /*
131 * TV Encoder - Red Frame Test Pattern
132 */
133 case 1:
134 reg |= TVENC_CTL_TPG_REDCLR;
135 break;
136 /*
137 * TV Encoder - Modulated Ramp Test Pattern
138 */
139 default:
140 reg |= TVENC_CTL_TPG_MODRAMP;
141 break;
142 }
143
144 TV_OUT(TV_ENC_CTL, reg);
145 mdelay(5000);
146
147 switch (i) {
148 /*
149 * TV Encoder - Color Bar Test Pattern
150 */
151 case 0:
152 reg &= ~TVENC_CTL_TPG_CLRBAR;
153 break;
154 /*
155 * TV Encoder - Red Frame Test Pattern
156 */
157 case 1:
158 reg &= ~TVENC_CTL_TPG_REDCLR;
159 break;
160 /*
161 * TV Encoder - Modulated Ramp Test Pattern
162 */
163 default:
164 reg &= ~TVENC_CTL_TPG_MODRAMP;
165 break;
166 }
167 }
168}
169
170static int tvenc_resource_initialized;
171
172static int tvenc_probe(struct platform_device *pdev)
173{
174 struct msm_fb_data_type *mfd;
175 struct platform_device *mdp_dev = NULL;
176 struct msm_fb_panel_data *pdata = NULL;
177 int rc;
178
179 if (pdev->id == 0) {
180 tvenc_base = ioremap(pdev->resource[0].start,
181 pdev->resource[0].end -
182 pdev->resource[0].start + 1);
183 if (!tvenc_base) {
184 printk(KERN_ERR
185 "tvenc_base ioremap failed!\n");
186 return -ENOMEM;
187 }
188 tvenc_pdata = pdev->dev.platform_data;
189 tvenc_resource_initialized = 1;
190 return 0;
191 }
192
193 if (!tvenc_resource_initialized)
194 return -EPERM;
195
196 mfd = platform_get_drvdata(pdev);
197
198 if (!mfd)
199 return -ENODEV;
200
201 if (mfd->key != MFD_KEY)
202 return -EINVAL;
203
204 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
205 return -ENOMEM;
206
207 if (tvenc_base == NULL)
208 return -ENOMEM;
209
210 mdp_dev = platform_device_alloc("mdp", pdev->id);
211 if (!mdp_dev)
212 return -ENOMEM;
213
214 /*
215 * link to the latest pdev
216 */
217 mfd->pdev = mdp_dev;
218 mfd->dest = DISPLAY_TV;
219
220 /*
221 * alloc panel device data
222 */
223 if (platform_device_add_data
224 (mdp_dev, pdev->dev.platform_data,
225 sizeof(struct msm_fb_panel_data))) {
226 printk(KERN_ERR "tvenc_probe: platform_device_add_data failed!\n");
227 platform_device_put(mdp_dev);
228 return -ENOMEM;
229 }
230 /*
231 * data chain
232 */
233 pdata = mdp_dev->dev.platform_data;
234 pdata->on = tvenc_on;
235 pdata->off = tvenc_off;
236 pdata->next = pdev;
237
238 /*
239 * get/set panel specific fb info
240 */
241 mfd->panel_info = pdata->panel_info;
242 mfd->fb_imgType = MDP_YCRYCB_H2V1;
243
244 /*
245 * set driver data
246 */
247 platform_set_drvdata(mdp_dev, mfd);
248
249 /*
250 * register in mdp driver
251 */
252 rc = platform_device_add(mdp_dev);
253 if (rc)
254 goto tvenc_probe_err;
255
256 pdev_list[pdev_list_cnt++] = pdev;
257 return 0;
258
259tvenc_probe_err:
260 platform_device_put(mdp_dev);
261 return rc;
262}
263
264static int tvenc_remove(struct platform_device *pdev)
265{
266// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc");
267 return 0;
268}
269
270static int tvenc_register_driver(void)
271{
272 return platform_driver_register(&tvenc_driver);
273}
274
275static int __init tvenc_driver_init(void)
276{
277 tvenc_clk = clk_get(NULL, "tv_enc_clk");
278 tvdac_clk = clk_get(NULL, "tv_dac_clk");
279
280 if (IS_ERR(tvenc_clk)) {
281 printk(KERN_ERR "error: can't get tvenc_clk!\n");
282 return IS_ERR(tvenc_clk);
283 }
284
285 if (IS_ERR(tvdac_clk)) {
286 printk(KERN_ERR "error: can't get tvdac_clk!\n");
287 return IS_ERR(tvdac_clk);
288 }
289
290// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc",
291// PM_QOS_DEFAULT_VALUE);
292 return tvenc_register_driver();
293}
294
295module_init(tvenc_driver_init);
diff --git a/drivers/staging/msm/tvenc.h b/drivers/staging/msm/tvenc.h
new file mode 100644
index 000000000000..a682dbebcf7d
--- /dev/null
+++ b/drivers/staging/msm/tvenc.h
@@ -0,0 +1,117 @@
1/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of Code Aurora nor
11 * the names of its contributors may be used to endorse or promote
12 * products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#ifndef TVENC_H
30#define TVENC_H
31
32#include <linux/kernel.h>
33#include <linux/sched.h>
34#include <linux/time.h>
35#include <linux/init.h>
36#include <linux/interrupt.h>
37#include <linux/fb.h>
38
39#include <mach/hardware.h>
40#include <linux/io.h>
41
42#include <asm/system.h>
43#include <asm/mach-types.h>
44
45#include "msm_fb_panel.h"
46
47#define NTSC_M 0 /* North America, Korea */
48#define NTSC_J 1 /* Japan */
49#define PAL_BDGHIN 2 /* Non-argentina PAL-N */
50#define PAL_M 3 /* PAL-M */
51#define PAL_N 4 /* Argentina PAL-N */
52
53/* 3.57954545 Mhz */
54#define TVENC_CTL_TV_MODE_NTSC_M_PAL60 0
55/* 3.57961149 Mhz */
56#define TVENC_CTL_TV_MODE_PAL_M BIT(0)
57/*non-Argintina = 4.3361875 Mhz */
58#define TVENC_CTL_TV_MODE_PAL_BDGHIN BIT(1)
59/*Argentina = 3.582055625 Mhz */
60#define TVENC_CTL_TV_MODE_PAL_N (BIT(1)|BIT(0))
61
62#define TVENC_CTL_ENC_EN BIT(2)
63#define TVENC_CTL_CC_EN BIT(3)
64#define TVENC_CTL_CGMS_EN BIT(4)
65#define TVENC_CTL_MACRO_EN BIT(5)
66#define TVENC_CTL_Y_FILTER_W_NOTCH BIT(6)
67#define TVENC_CTL_Y_FILTER_WO_NOTCH 0
68#define TVENC_CTL_Y_FILTER_EN BIT(7)
69#define TVENC_CTL_CR_FILTER_EN BIT(8)
70#define TVENC_CTL_CB_FILTER_EN BIT(9)
71#define TVENC_CTL_SINX_FILTER_EN BIT(10)
72#define TVENC_CTL_TEST_PATT_EN BIT(11)
73#define TVENC_CTL_OUTPUT_INV BIT(12)
74#define TVENC_CTL_PAL60_MODE BIT(13)
75#define TVENC_CTL_NTSCJ_MODE BIT(14)
76#define TVENC_CTL_TPG_CLRBAR 0
77#define TVENC_CTL_TPG_MODRAMP BIT(15)
78#define TVENC_CTL_TPG_REDCLR BIT(16)
79#define TVENC_CTL_S_VIDEO_EN BIT(19)
80
81#ifdef TVENC_C
82void *tvenc_base;
83#else
84extern void *tvenc_base;
85#endif
86
87#define TV_OUT(reg, v) writel(v, tvenc_base + MSM_##reg)
88
89#define MSM_TV_ENC_CTL 0x00
90#define MSM_TV_LEVEL 0x04
91#define MSM_TV_GAIN 0x08
92#define MSM_TV_OFFSET 0x0c
93#define MSM_TV_CGMS 0x10
94#define MSM_TV_SYNC_1 0x14
95#define MSM_TV_SYNC_2 0x18
96#define MSM_TV_SYNC_3 0x1c
97#define MSM_TV_SYNC_4 0x20
98#define MSM_TV_SYNC_5 0x24
99#define MSM_TV_SYNC_6 0x28
100#define MSM_TV_SYNC_7 0x2c
101#define MSM_TV_BURST_V1 0x30
102#define MSM_TV_BURST_V2 0x34
103#define MSM_TV_BURST_V3 0x38
104#define MSM_TV_BURST_V4 0x3c
105#define MSM_TV_BURST_H 0x40
106#define MSM_TV_SOL_REQ_ODD 0x44
107#define MSM_TV_SOL_REQ_EVEN 0x48
108#define MSM_TV_DAC_CTL 0x4c
109#define MSM_TV_TEST_MUX 0x50
110#define MSM_TV_TEST_MODE 0x54
111#define MSM_TV_TEST_MISR_RESET 0x58
112#define MSM_TV_TEST_EXPORT_MISR 0x5c
113#define MSM_TV_TEST_MISR_CURR_VAL 0x60
114#define MSM_TV_TEST_SOF_CFG 0x64
115#define MSM_TV_DAC_INTF 0x100
116
117#endif /* TVENC_H */
diff --git a/drivers/staging/phison/Kconfig b/drivers/staging/phison/Kconfig
index d3c65d315a2e..1b56119a7657 100644
--- a/drivers/staging/phison/Kconfig
+++ b/drivers/staging/phison/Kconfig
@@ -1,5 +1,5 @@
1config IDE_PHISON 1config IDE_PHISON
2 tristate "PCIE ATA PS5000 IDE support" 2 tristate "PCIE ATA PS5000 IDE support"
3 depends on PCI && ATA && ATA_SFF 3 depends on PCI && ATA && ATA_SFF && ATA_BMDMA
4 ---help--- 4 ---help---
5 This is an experimental driver for PS5000 IDE driver. 5 This is an experimental driver for PS5000 IDE driver.
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index 112da7a6c417..6b8268d3dc75 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -2522,6 +2522,8 @@ int rt28xx_sta_ioctl(IN struct net_device *net_dev,
2522 Status = 2522 Status =
2523 copy_to_user(erq->pointer, pAd->nickname, 2523 copy_to_user(erq->pointer, pAd->nickname,
2524 erq->length); 2524 erq->length);
2525 if (Status)
2526 Status = -EFAULT;
2525 break; 2527 break;
2526 } 2528 }
2527 case SIOCGIWRATE: /*get default bit rate (bps) */ 2529 case SIOCGIWRATE: /*get default bit rate (bps) */
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
index 0332c370fd82..ecbde3467b1b 100644
--- a/drivers/staging/sep/sep_driver.c
+++ b/drivers/staging/sep/sep_driver.c
@@ -594,8 +594,10 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
594 dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n"); 594 dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n");
595 595
596 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t)); 596 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t));
597 if (error) 597 if (error) {
598 error = -EFAULT;
598 goto end_function; 599 goto end_function;
600 }
599 601
600 /* allocate memory */ 602 /* allocate memory */
601 if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { 603 if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
@@ -609,8 +611,10 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
609 611
610 /* write the memory back to the user space */ 612 /* write the memory back to the user space */
611 error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t)); 613 error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t));
612 if (error) 614 if (error) {
615 error = -EFAULT;
613 goto end_function; 616 goto end_function;
617 }
614 618
615 /* set the allocation */ 619 /* set the allocation */
616 sep->data_pool_bytes_allocated += command_args.num_bytes; 620 sep->data_pool_bytes_allocated += command_args.num_bytes;
@@ -661,6 +665,8 @@ static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned lon
661 } 665 }
662 /* copy the application data */ 666 /* copy the application data */
663 error = copy_from_user(virt_address, (void *) app_in_address, num_bytes); 667 error = copy_from_user(virt_address, (void *) app_in_address, num_bytes);
668 if (error)
669 error = -EFAULT;
664end_function: 670end_function:
665 dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n"); 671 dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n");
666 return error; 672 return error;
@@ -711,6 +717,8 @@ static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long
711 717
712 /* copy the application data */ 718 /* copy the application data */
713 error = copy_to_user((void *) app_out_address, virt_address, num_bytes); 719 error = copy_to_user((void *) app_out_address, virt_address, num_bytes);
720 if (error)
721 error = -EFAULT;
714end_function: 722end_function:
715 dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n"); 723 dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n");
716 return error; 724 return error;
@@ -1448,8 +1456,10 @@ static int sep_create_sync_dma_tables_handler(struct sep_device *sep,
1448 dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n"); 1456 dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n");
1449 1457
1450 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t)); 1458 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t));
1451 if (error) 1459 if (error) {
1460 error = -EFAULT;
1452 goto end_function; 1461 goto end_function;
1462 }
1453 1463
1454 edbg("app_in_address is %08lx\n", command_args.app_in_address); 1464 edbg("app_in_address is %08lx\n", command_args.app_in_address);
1455 edbg("app_out_address is %08lx\n", command_args.app_out_address); 1465 edbg("app_out_address is %08lx\n", command_args.app_out_address);
@@ -1799,8 +1809,10 @@ static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
1799 goto end_function; 1809 goto end_function;
1800 1810
1801 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t)); 1811 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t));
1802 if (error) 1812 if (error) {
1813 error = -EFAULT;
1803 goto end_function; 1814 goto end_function;
1815 }
1804 1816
1805 /* create flow tables */ 1817 /* create flow tables */
1806 error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress); 1818 error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
@@ -1819,8 +1831,10 @@ static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
1819 1831
1820 /* send the parameters to user application */ 1832 /* send the parameters to user application */
1821 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t)); 1833 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t));
1822 if (error) 1834 if (error) {
1835 error = -EFAULT;
1823 goto end_function_with_error; 1836 goto end_function_with_error;
1837 }
1824 1838
1825 /* all the flow created - update the flow entry with temp id */ 1839 /* all the flow created - update the flow entry with temp id */
1826 flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID; 1840 flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID;
@@ -1861,8 +1875,10 @@ static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg
1861 1875
1862 /* get input parameters */ 1876 /* get input parameters */
1863 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t)); 1877 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t));
1864 if (error) 1878 if (error) {
1879 error = -EFAULT;
1865 goto end_function; 1880 goto end_function;
1881 }
1866 1882
1867 /* find the flow structure for the flow id */ 1883 /* find the flow structure for the flow id */
1868 flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id); 1884 flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
@@ -1933,6 +1949,8 @@ static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg
1933 1949
1934 /* send the parameters to user application */ 1950 /* send the parameters to user application */
1935 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t)); 1951 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t));
1952 if (error)
1953 error = -EFAULT;
1936end_function_with_error: 1954end_function_with_error:
1937 /* free the allocated tables */ 1955 /* free the allocated tables */
1938 sep_deallocated_flow_tables(&first_table_data); 1956 sep_deallocated_flow_tables(&first_table_data);
@@ -1953,8 +1971,10 @@ static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned
1953 dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n"); 1971 dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n");
1954 1972
1955 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t)); 1973 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t));
1956 if (error) 1974 if (error) {
1975 error = -EFAULT;
1957 goto end_function; 1976 goto end_function;
1977 }
1958 1978
1959 /* check input */ 1979 /* check input */
1960 if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) { 1980 if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) {
@@ -1970,6 +1990,8 @@ static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned
1970 /* copy the message into context */ 1990 /* copy the message into context */
1971 flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes; 1991 flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes;
1972 error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes); 1992 error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes);
1993 if (error)
1994 error = -EFAULT;
1973end_function: 1995end_function:
1974 dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n"); 1996 dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n");
1975 return error; 1997 return error;
@@ -1994,6 +2016,8 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned lon
1994 2016
1995 /* send the parameters to user application */ 2017 /* send the parameters to user application */
1996 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t)); 2018 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t));
2019 if (error)
2020 error = -EFAULT;
1997 dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n"); 2021 dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n");
1998 return error; 2022 return error;
1999} 2023}
@@ -2010,8 +2034,10 @@ static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsign
2010 dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n"); 2034 dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n");
2011 2035
2012 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t)); 2036 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t));
2013 if (error) 2037 if (error) {
2038 error = -EFAULT;
2014 goto end_function; 2039 goto end_function;
2040 }
2015 2041
2016 if (command_args.physical_address < sep->shared_bus) { 2042 if (command_args.physical_address < sep->shared_bus) {
2017 error = -EINVAL; 2043 error = -EINVAL;
@@ -2025,6 +2051,8 @@ static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsign
2025 2051
2026 /* send the parameters to user application */ 2052 /* send the parameters to user application */
2027 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t)); 2053 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t));
2054 if (error)
2055 error = -EFAULT;
2028end_function: 2056end_function:
2029 dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n"); 2057 dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n");
2030 return error; 2058 return error;
@@ -2070,11 +2098,11 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg)
2070 error = 0; 2098 error = 0;
2071 2099
2072 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t)); 2100 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t));
2073 2101 if (error) {
2074 dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user \n"); 2102 error = -EFAULT;
2075
2076 if (error)
2077 goto end_function; 2103 goto end_function;
2104 }
2105 dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user\n");
2078 2106
2079 /* PATCH - configure the DMA to single -burst instead of multi-burst */ 2107 /* PATCH - configure the DMA to single -burst instead of multi-burst */
2080 /*sep_configure_dma_burst(); */ 2108 /*sep_configure_dma_burst(); */
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig
index 5fe759cc2ee9..3657e33e8817 100644
--- a/drivers/staging/tm6000/Kconfig
+++ b/drivers/staging/tm6000/Kconfig
@@ -2,7 +2,8 @@ config VIDEO_TM6000
2 tristate "TV Master TM5600/6000/6010 driver" 2 tristate "TV Master TM5600/6000/6010 driver"
3 depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL 3 depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL
4 select VIDEO_TUNER 4 select VIDEO_TUNER
5 select TUNER_XC2028 5 select MEDIA_TUNER_XC2028
6 select MEDIA_TUNER_XC5000
6 select VIDEOBUF_VMALLOC 7 select VIDEOBUF_VMALLOC
7 help 8 help
8 Support for TM5600/TM6000/TM6010 USB Device 9 Support for TM5600/TM6000/TM6010 USB Device
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index bc89f9d28002..ce081cd44ad4 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -410,5 +410,28 @@ error:
410 snd_card_free(card); 410 snd_card_free(card);
411 return rc; 411 return rc;
412} 412}
413EXPORT_SYMBOL_GPL(tm6000_audio_init);
414 413
414static int tm6000_audio_fini(struct tm6000_core *dev)
415{
416 return 0;
417}
418
419struct tm6000_ops audio_ops = {
420 .id = TM6000_AUDIO,
421 .name = "TM6000 Audio Extension",
422 .init = tm6000_audio_init,
423 .fini = tm6000_audio_fini,
424};
425
426static int __init tm6000_alsa_register(void)
427{
428 return tm6000_register_extension(&audio_ops);
429}
430
431static void __exit tm6000_alsa_unregister(void)
432{
433 tm6000_unregister_extension(&audio_ops);
434}
435
436module_init(tm6000_alsa_register);
437module_exit(tm6000_alsa_unregister);
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 6143e20d139d..cedd9044022f 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -363,13 +363,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
363 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 363 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
364 0x02, arg); 364 0x02, arg);
365 msleep(10); 365 msleep(10);
366 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, 366 rc = tm6000_i2c_reset(dev, 10);
367 TM6000_GPIO_CLK, 0);
368 if (rc < 0)
369 return rc;
370 msleep(10);
371 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
372 TM6000_GPIO_CLK, 1);
373 break; 367 break;
374 case XC2028_TUNER_RESET: 368 case XC2028_TUNER_RESET:
375 /* Reset codes during load firmware */ 369 /* Reset codes during load firmware */
@@ -423,14 +417,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
423 break; 417 break;
424 418
425 case 2: 419 case 2:
426 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, 420 rc = tm6000_i2c_reset(dev, 100);
427 TM6000_GPIO_CLK, 0);
428 if (rc < 0)
429 return rc;
430 msleep(100);
431 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
432 TM6000_GPIO_CLK, 1);
433 msleep(100);
434 break; 421 break;
435 } 422 }
436 } 423 }
@@ -563,7 +550,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
563 550
564 switch (dev->tuner_type) { 551 switch (dev->tuner_type) {
565 case TUNER_XC2028: 552 case TUNER_XC2028:
566 tun_setup.tuner_callback = tm6000_tuner_callback;; 553 tun_setup.tuner_callback = tm6000_tuner_callback;
567 break; 554 break;
568 case TUNER_XC5000: 555 case TUNER_XC5000:
569 tun_setup.tuner_callback = tm6000_xc5000_callback; 556 tun_setup.tuner_callback = tm6000_xc5000_callback;
@@ -692,6 +679,10 @@ static int tm6000_init_dev(struct tm6000_core *dev)
692 if (rc < 0) 679 if (rc < 0)
693 goto err; 680 goto err;
694 681
682 tm6000_add_into_devlist(dev);
683
684 tm6000_init_extension(dev);
685
695 if (dev->caps.has_dvb) { 686 if (dev->caps.has_dvb) {
696 dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL); 687 dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL);
697 if (!dev->dvb) { 688 if (!dev->dvb) {
@@ -921,6 +912,25 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
921 } 912 }
922#endif 913#endif
923 914
915 if (dev->gpio.power_led) {
916 switch (dev->model) {
917 case TM6010_BOARD_HAUPPAUGE_900H:
918 case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
919 case TM6010_BOARD_TWINHAN_TU501:
920 /* Power led off */
921 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
922 dev->gpio.power_led, 0x01);
923 msleep(15);
924 break;
925 case TM6010_BOARD_BEHOLD_WANDER:
926 case TM6010_BOARD_BEHOLD_VOYAGER:
927 /* Power led off */
928 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
929 dev->gpio.power_led, 0x00);
930 msleep(15);
931 break;
932 }
933 }
924 tm6000_v4l2_unregister(dev); 934 tm6000_v4l2_unregister(dev);
925 935
926 tm6000_i2c_unregister(dev); 936 tm6000_i2c_unregister(dev);
@@ -931,6 +941,9 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
931 941
932 usb_put_dev(dev->udev); 942 usb_put_dev(dev->udev);
933 943
944 tm6000_remove_from_devlist(dev);
945 tm6000_close_extension(dev);
946
934 mutex_unlock(&dev->lock); 947 mutex_unlock(&dev->lock);
935 kfree(dev); 948 kfree(dev);
936} 949}
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index bfbc53bd2912..27f3f551b545 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -153,6 +153,22 @@ int tm6000_get_reg32 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
153 return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24; 153 return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24;
154} 154}
155 155
156int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep)
157{
158 int rc;
159
160 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 0);
161 if (rc < 0)
162 return rc;
163
164 msleep(tsleep);
165
166 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1);
167 msleep(tsleep);
168
169 return rc;
170}
171
156void tm6000_set_fourcc_format(struct tm6000_core *dev) 172void tm6000_set_fourcc_format(struct tm6000_core *dev)
157{ 173{
158 if (dev->dev_type == TM6010) { 174 if (dev->dev_type == TM6010) {
@@ -323,6 +339,12 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
323 tm6000_set_standard (dev, &dev->norm); 339 tm6000_set_standard (dev, &dev->norm);
324 tm6000_set_audio_bitrate (dev,48000); 340 tm6000_set_audio_bitrate (dev,48000);
325 341
342 /* switch dvb led off */
343 if (dev->gpio.dvb_led) {
344 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
345 dev->gpio.dvb_led, 0x01);
346 }
347
326 return 0; 348 return 0;
327} 349}
328 350
@@ -375,6 +397,13 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
375 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00); 397 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
376 msleep(100); 398 msleep(100);
377 } 399 }
400
401 /* switch dvb led on */
402 if (dev->gpio.dvb_led) {
403 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
404 dev->gpio.dvb_led, 0x00);
405 }
406
378 return 0; 407 return 0;
379} 408}
380 409
@@ -600,3 +629,95 @@ printk("Original value=%d\n",val);
600 return val; 629 return val;
601} 630}
602EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); 631EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
632
633static LIST_HEAD(tm6000_devlist);
634static DEFINE_MUTEX(tm6000_devlist_mutex);
635
636/*
637 * tm6000_realease_resource()
638 */
639
640void tm6000_remove_from_devlist(struct tm6000_core *dev)
641{
642 mutex_lock(&tm6000_devlist_mutex);
643 list_del(&dev->devlist);
644 mutex_unlock(&tm6000_devlist_mutex);
645};
646
647void tm6000_add_into_devlist(struct tm6000_core *dev)
648{
649 mutex_lock(&tm6000_devlist_mutex);
650 list_add_tail(&dev->devlist, &tm6000_devlist);
651 mutex_unlock(&tm6000_devlist_mutex);
652};
653
654/*
655 * Extension interface
656 */
657
658static LIST_HEAD(tm6000_extension_devlist);
659static DEFINE_MUTEX(tm6000_extension_devlist_lock);
660
661int tm6000_register_extension(struct tm6000_ops *ops)
662{
663 struct tm6000_core *dev = NULL;
664
665 mutex_lock(&tm6000_devlist_mutex);
666 mutex_lock(&tm6000_extension_devlist_lock);
667 list_add_tail(&ops->next, &tm6000_extension_devlist);
668 list_for_each_entry(dev, &tm6000_devlist, devlist) {
669 if (dev)
670 ops->init(dev);
671 }
672 printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name);
673 mutex_unlock(&tm6000_extension_devlist_lock);
674 mutex_unlock(&tm6000_devlist_mutex);
675 return 0;
676}
677EXPORT_SYMBOL(tm6000_register_extension);
678
679void tm6000_unregister_extension(struct tm6000_ops *ops)
680{
681 struct tm6000_core *dev = NULL;
682
683 mutex_lock(&tm6000_devlist_mutex);
684 list_for_each_entry(dev, &tm6000_devlist, devlist) {
685 if (dev)
686 ops->fini(dev);
687 }
688
689 mutex_lock(&tm6000_extension_devlist_lock);
690 printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name);
691 list_del(&ops->next);
692 mutex_unlock(&tm6000_extension_devlist_lock);
693 mutex_unlock(&tm6000_devlist_mutex);
694}
695EXPORT_SYMBOL(tm6000_unregister_extension);
696
697void tm6000_init_extension(struct tm6000_core *dev)
698{
699 struct tm6000_ops *ops = NULL;
700
701 mutex_lock(&tm6000_extension_devlist_lock);
702 if (!list_empty(&tm6000_extension_devlist)) {
703 list_for_each_entry(ops, &tm6000_extension_devlist, next) {
704 if (ops->init)
705 ops->init(dev);
706 }
707 }
708 mutex_unlock(&tm6000_extension_devlist_lock);
709}
710
711void tm6000_close_extension(struct tm6000_core *dev)
712{
713 struct tm6000_ops *ops = NULL;
714
715 mutex_lock(&tm6000_extension_devlist_lock);
716 if (!list_empty(&tm6000_extension_devlist)) {
717 list_for_each_entry(ops, &tm6000_extension_devlist, next) {
718 if (ops->fini)
719 ops->fini(dev);
720 }
721 }
722 mutex_unlock(&tm6000_extension_devlist_lock);
723}
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c
index eafc89c22b6b..261e66acbe46 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -28,6 +28,7 @@
28#include <media/tuner.h> 28#include <media/tuner.h>
29 29
30#include "tuner-xc2028.h" 30#include "tuner-xc2028.h"
31#include "xc5000.h"
31 32
32static void inline print_err_status (struct tm6000_core *dev, 33static void inline print_err_status (struct tm6000_core *dev,
33 int packet, int status) 34 int packet, int status)
@@ -100,7 +101,10 @@ int tm6000_start_stream(struct tm6000_core *dev)
100 101
101 printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__); 102 printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
102 103
103 tm6000_init_digital_mode(dev); 104 if (dev->mode != TM6000_MODE_DIGITAL) {
105 tm6000_init_digital_mode(dev);
106 dev->mode = TM6000_MODE_DIGITAL;
107 }
104 108
105 dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); 109 dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
106 if(dvb->bulk_urb == NULL) { 110 if(dvb->bulk_urb == NULL) {
@@ -254,27 +258,55 @@ int tm6000_dvb_register(struct tm6000_core *dev)
254 dvb->adapter.priv = dev; 258 dvb->adapter.priv = dev;
255 259
256 if (dvb->frontend) { 260 if (dvb->frontend) {
257 struct xc2028_config cfg = { 261 switch (dev->tuner_type) {
258 .i2c_adap = &dev->i2c_adap, 262 case TUNER_XC2028: {
259 .i2c_addr = dev->tuner_addr, 263 struct xc2028_config cfg = {
260 }; 264 .i2c_adap = &dev->i2c_adap,
261 265 .i2c_addr = dev->tuner_addr,
262 dvb->frontend->callback = tm6000_tuner_callback; 266 };
263 ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); 267
264 if (ret < 0) { 268 dvb->frontend->callback = tm6000_tuner_callback;
265 printk(KERN_ERR 269 ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
266 "tm6000: couldn't register frontend\n"); 270 if (ret < 0) {
267 goto adapter_err; 271 printk(KERN_ERR
268 } 272 "tm6000: couldn't register frontend\n");
269 273 goto adapter_err;
270 if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { 274 }
271 printk(KERN_ERR "tm6000: couldn't register " 275
272 "frontend (xc3028)\n"); 276 if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) {
273 ret = -EINVAL; 277 printk(KERN_ERR "tm6000: couldn't register "
274 goto frontend_err; 278 "frontend (xc3028)\n");
279 ret = -EINVAL;
280 goto frontend_err;
281 }
282 printk(KERN_INFO "tm6000: XC2028/3028 asked to be "
283 "attached to frontend!\n");
284 break;
285 }
286 case TUNER_XC5000: {
287 struct xc5000_config cfg = {
288 .i2c_address = dev->tuner_addr,
289 };
290
291 dvb->frontend->callback = tm6000_xc5000_callback;
292 ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
293 if (ret < 0) {
294 printk(KERN_ERR
295 "tm6000: couldn't register frontend\n");
296 goto adapter_err;
297 }
298
299 if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) {
300 printk(KERN_ERR "tm6000: couldn't register "
301 "frontend (xc5000)\n");
302 ret = -EINVAL;
303 goto frontend_err;
304 }
305 printk(KERN_INFO "tm6000: XC5000 asked to be "
306 "attached to frontend!\n");
307 break;
308 }
275 } 309 }
276 printk(KERN_INFO "tm6000: XC2028/3028 asked to be "
277 "attached to frontend!\n");
278 } else { 310 } else {
279 printk(KERN_ERR "tm6000: no frontend found\n"); 311 printk(KERN_ERR "tm6000: no frontend found\n");
280 } 312 }
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index f2b7fe4a3581..56fa371e08c8 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -48,7 +48,7 @@
48#define TM6000_MIN_BUF 4 48#define TM6000_MIN_BUF 4
49#define TM6000_DEF_BUF 8 49#define TM6000_DEF_BUF 8
50 50
51#define TM6000_MAX_ISO_PACKETS 40 /* Max number of ISO packets */ 51#define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */
52 52
53/* Declare static vars that will be used as parameters */ 53/* Declare static vars that will be used as parameters */
54static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 54static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
@@ -205,7 +205,11 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
205 c = (header >> 24) & 0xff; 205 c = (header >> 24) & 0xff;
206 206
207 /* split the header fields */ 207 /* split the header fields */
208 size = (((header & 0x7e) << 1) -1) *4; 208 size = ((header & 0x7e) << 1);
209
210 if (size > 0)
211 size -= 4;
212
209 block = (header >> 7) & 0xf; 213 block = (header >> 7) & 0xf;
210 field = (header >> 11) & 0x1; 214 field = (header >> 11) & 0x1;
211 line = (header >> 12) & 0x1ff; 215 line = (header >> 12) & 0x1ff;
@@ -307,10 +311,12 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
307 case TM6000_URB_MSG_PTS: 311 case TM6000_URB_MSG_PTS:
308 break; 312 break;
309 case TM6000_URB_MSG_AUDIO: 313 case TM6000_URB_MSG_AUDIO:
310/* Need some code to process audio */ 314 /* Need some code to process audio */
311printk ("%ld: cmd=%s, size=%d\n", jiffies, 315 printk ("%ld: cmd=%s, size=%d\n", jiffies,
312 tm6000_msg_type[cmd],size); 316 tm6000_msg_type[cmd],size);
313 break; 317 break;
318 case TM6000_URB_MSG_VBI:
319 break;
314 default: 320 default:
315 dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n", 321 dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
316 tm6000_msg_type[cmd],size); 322 tm6000_msg_type[cmd],size);
@@ -333,14 +339,23 @@ printk ("%ld: cmd=%s, size=%d\n", jiffies,
333 return rc; 339 return rc;
334} 340}
335 341
336static int copy_streams(u8 *data, u8 *out_p, unsigned long len, 342static int copy_streams(u8 *data, unsigned long len,
337 struct urb *urb, struct tm6000_buffer **buf) 343 struct urb *urb)
338{ 344{
339 struct tm6000_dmaqueue *dma_q = urb->context; 345 struct tm6000_dmaqueue *dma_q = urb->context;
340 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); 346 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
341 u8 *ptr=data, *endp=data+len; 347 u8 *ptr=data, *endp=data+len;
342 unsigned long header=0; 348 unsigned long header=0;
343 int rc=0; 349 int rc=0;
350 struct tm6000_buffer *buf;
351 char *outp = NULL;
352
353 get_next_buf(dma_q, &buf);
354 if (buf)
355 outp = videobuf_to_vmalloc(&buf->vb);
356
357 if (!outp)
358 return 0;
344 359
345 for (ptr=data; ptr<endp;) { 360 for (ptr=data; ptr<endp;) {
346 if (!dev->isoc_ctl.cmd) { 361 if (!dev->isoc_ctl.cmd) {
@@ -388,14 +403,14 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len,
388 } 403 }
389HEADER: 404HEADER:
390 /* Copy or continue last copy */ 405 /* Copy or continue last copy */
391 rc=copy_packet(urb,header,&ptr,endp,out_p,buf); 406 rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
392 if (rc<0) { 407 if (rc<0) {
393 buf=NULL; 408 buf=NULL;
394 printk(KERN_ERR "tm6000: buffer underrun at %ld\n", 409 printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
395 jiffies); 410 jiffies);
396 return rc; 411 return rc;
397 } 412 }
398 if (!*buf) 413 if (!buf)
399 return 0; 414 return 0;
400 } 415 }
401 416
@@ -404,31 +419,40 @@ HEADER:
404/* 419/*
405 * Identify the tm5600/6000 buffer header type and properly handles 420 * Identify the tm5600/6000 buffer header type and properly handles
406 */ 421 */
407static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len, 422static int copy_multiplexed(u8 *ptr, unsigned long len,
408 struct urb *urb, struct tm6000_buffer **buf) 423 struct urb *urb)
409{ 424{
410 struct tm6000_dmaqueue *dma_q = urb->context; 425 struct tm6000_dmaqueue *dma_q = urb->context;
411 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); 426 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
412 unsigned int pos=dev->isoc_ctl.pos,cpysize; 427 unsigned int pos=dev->isoc_ctl.pos,cpysize;
413 int rc=1; 428 int rc=1;
429 struct tm6000_buffer *buf;
430 char *outp = NULL;
431
432 get_next_buf(dma_q, &buf);
433 if (buf)
434 outp = videobuf_to_vmalloc(&buf->vb);
435
436 if (!outp)
437 return 0;
414 438
415 while (len>0) { 439 while (len>0) {
416 cpysize=min(len,(*buf)->vb.size-pos); 440 cpysize=min(len,buf->vb.size-pos);
417//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos); 441 //printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
418 memcpy(&out_p[pos], ptr, cpysize); 442 memcpy(&outp[pos], ptr, cpysize);
419 pos+=cpysize; 443 pos+=cpysize;
420 ptr+=cpysize; 444 ptr+=cpysize;
421 len-=cpysize; 445 len-=cpysize;
422 if (pos >= (*buf)->vb.size) { 446 if (pos >= buf->vb.size) {
423 pos=0; 447 pos=0;
424 /* Announces that a new buffer were filled */ 448 /* Announces that a new buffer were filled */
425 buffer_filled (dev, dma_q, *buf); 449 buffer_filled (dev, dma_q, buf);
426 dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n"); 450 dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n");
427 get_next_buf (dma_q, buf); 451 get_next_buf (dma_q, &buf);
428 if (!*buf) 452 if (!buf)
429 break; 453 break;
430 out_p = videobuf_to_vmalloc(&((*buf)->vb)); 454 outp = videobuf_to_vmalloc(&(buf->vb));
431 if (!out_p) 455 if (!outp)
432 return rc; 456 return rc;
433 pos = 0; 457 pos = 0;
434 } 458 }
@@ -487,52 +511,36 @@ static inline int tm6000_isoc_copy(struct urb *urb)
487 struct tm6000_dmaqueue *dma_q = urb->context; 511 struct tm6000_dmaqueue *dma_q = urb->context;
488 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); 512 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
489 struct tm6000_buffer *buf; 513 struct tm6000_buffer *buf;
490 int i, len=0, rc=1; 514 int i, len=0, rc=1, status;
491 int size; 515 char *p;
492 char *outp = NULL, *p;
493 unsigned long copied;
494
495 get_next_buf(dma_q, &buf);
496 if (buf)
497 outp = videobuf_to_vmalloc(&buf->vb);
498 516
499 if (!outp) 517 if (urb->status < 0) {
500 return 0; 518 print_err_status (dev, -1, urb->status);
501
502 size = buf->vb.size;
503
504 copied=0;
505
506 if (urb->status<0) {
507 print_err_status (dev,-1,urb->status);
508 return 0; 519 return 0;
509 } 520 }
510 521
511 for (i = 0; i < urb->number_of_packets; i++) { 522 for (i = 0; i < urb->number_of_packets; i++) {
512 int status = urb->iso_frame_desc[i].status; 523 status = urb->iso_frame_desc[i].status;
513 524
514 if (status<0) { 525 if (status<0) {
515 print_err_status (dev,i,status); 526 print_err_status (dev,i,status);
516 continue; 527 continue;
517 } 528 }
518 529
519 len=urb->iso_frame_desc[i].actual_length; 530 len = urb->iso_frame_desc[i].actual_length;
520 531
521// if (len>=TM6000_URB_MSG_LEN) { 532 if (len > 0) {
522 p=urb->transfer_buffer + urb->iso_frame_desc[i].offset; 533 p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
523 if (!urb->iso_frame_desc[i].status) { 534 if (!urb->iso_frame_desc[i].status) {
524 if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) { 535 if ((dev->fourcc)==V4L2_PIX_FMT_TM6000) {
525 rc=copy_multiplexed(p, outp, len, urb, &buf); 536 rc=copy_multiplexed(p, len, urb);
526 if (rc<=0) 537 if (rc<=0)
527 return rc; 538 return rc;
528 } else { 539 } else {
529 copy_streams(p, outp, len, urb, &buf); 540 copy_streams(p, len, urb);
530 } 541 }
531 } 542 }
532 copied += len; 543 }
533 if (copied >= size || !buf)
534 break;
535// }
536 } 544 }
537 return rc; 545 return rc;
538} 546}
@@ -612,7 +620,7 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
612static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize) 620static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
613{ 621{
614 struct tm6000_dmaqueue *dma_q = &dev->vidq; 622 struct tm6000_dmaqueue *dma_q = &dev->vidq;
615 int i, j, sb_size, pipe, size, max_packets, num_bufs = 5; 623 int i, j, sb_size, pipe, size, max_packets, num_bufs = 8;
616 struct urb *urb; 624 struct urb *urb;
617 625
618 /* De-allocates all pending stuff */ 626 /* De-allocates all pending stuff */
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 6812d6867d57..7bbaf26dea14 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -168,6 +168,10 @@ struct tm6000_core {
168 struct i2c_adapter i2c_adap; 168 struct i2c_adapter i2c_adap;
169 struct i2c_client i2c_client; 169 struct i2c_client i2c_client;
170 170
171
172 /* extension */
173 struct list_head devlist;
174
171 /* video for linux */ 175 /* video for linux */
172 int users; 176 int users;
173 177
@@ -203,6 +207,16 @@ struct tm6000_core {
203 spinlock_t slock; 207 spinlock_t slock;
204}; 208};
205 209
210#define TM6000_AUDIO 0x10
211
212struct tm6000_ops {
213 struct list_head next;
214 char *name;
215 int id;
216 int (*init)(struct tm6000_core *);
217 int (*fini)(struct tm6000_core *);
218};
219
206struct tm6000_fh { 220struct tm6000_fh {
207 struct tm6000_core *dev; 221 struct tm6000_core *dev;
208 222
@@ -232,6 +246,8 @@ int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
232int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index); 246int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index);
233int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index); 247int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index);
234int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index); 248int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
249int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
250
235int tm6000_init (struct tm6000_core *dev); 251int tm6000_init (struct tm6000_core *dev);
236 252
237int tm6000_init_analog_mode (struct tm6000_core *dev); 253int tm6000_init_analog_mode (struct tm6000_core *dev);
@@ -246,6 +262,13 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev);
246int tm6000_v4l2_exit(void); 262int tm6000_v4l2_exit(void);
247void tm6000_set_fourcc_format(struct tm6000_core *dev); 263void tm6000_set_fourcc_format(struct tm6000_core *dev);
248 264
265void tm6000_remove_from_devlist(struct tm6000_core *dev);
266void tm6000_add_into_devlist(struct tm6000_core *dev);
267int tm6000_register_extension(struct tm6000_ops *ops);
268void tm6000_unregister_extension(struct tm6000_ops *ops);
269void tm6000_init_extension(struct tm6000_core *dev);
270void tm6000_close_extension(struct tm6000_core *dev);
271
249/* In tm6000-stds.c */ 272/* In tm6000-stds.c */
250void tm6000_get_std_res(struct tm6000_core *dev); 273void tm6000_get_std_res(struct tm6000_core *dev);
251int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm); 274int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm);
@@ -275,7 +298,7 @@ unsigned int tm6000_v4l2_poll(struct file *file,
275int tm6000_queue_init(struct tm6000_core *dev); 298int tm6000_queue_init(struct tm6000_core *dev);
276 299
277/* In tm6000-alsa.c */ 300/* In tm6000-alsa.c */
278int tm6000_audio_init(struct tm6000_core *dev, int idx); 301/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/
279 302
280 303
281/* Debug stuff */ 304/* Debug stuff */
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c
index 0c82eb47a28d..0f9ea58ff717 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.c
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -523,7 +523,7 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
523 } 523 }
524 524
525 if (image->bus_resource.name == NULL) { 525 if (image->bus_resource.name == NULL) {
526 image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); 526 image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC);
527 if (image->bus_resource.name == NULL) { 527 if (image->bus_resource.name == NULL) {
528 dev_err(ca91cx42_bridge->parent, "Unable to allocate " 528 dev_err(ca91cx42_bridge->parent, "Unable to allocate "
529 "memory for resource name\n"); 529 "memory for resource name\n");
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index abe88a380b72..f09cac163139 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -828,7 +828,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
828 return 0; 828 return 0;
829 829
830 if (image->bus_resource.name == NULL) { 830 if (image->bus_resource.name == NULL) {
831 image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); 831 image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC);
832 if (image->bus_resource.name == NULL) { 832 if (image->bus_resource.name == NULL) {
833 dev_err(tsi148_bridge->parent, "Unable to allocate " 833 dev_err(tsi148_bridge->parent, "Unable to allocate "
834 "memory for resource name\n"); 834 "memory for resource name\n");
diff --git a/drivers/staging/wlags49_h2/Kconfig b/drivers/staging/wlags49_h2/Kconfig
index b6fc2ca7d85c..3efcbf8afedf 100644
--- a/drivers/staging/wlags49_h2/Kconfig
+++ b/drivers/staging/wlags49_h2/Kconfig
@@ -1,9 +1,11 @@
1config WLAGS49_H2 1config WLAGS49_H2
2 tristate "Agere Systems HERMES II Wireless PC Card Model 0110" 2 tristate "Agere Systems HERMES II Wireless PC Card Model 0110"
3 depends on WLAN && WIRELESS_EXT && PCMCIA 3 depends on WLAN && PCMCIA
4 select WIRELESS_EXT
4 select WEXT_SPY 5 select WEXT_SPY
6 select WEXT_PRIV
5 ---help--- 7 ---help---
6 Driver for wireless cards using Agere's HERMES II chipset 8 Driver for wireless cards using Agere's HERMES II chipset
7 which are identified with Manufacture ID: 0156,0003 9 which are identified with Manufacture ID: 0156,0003
8 The software is a modified version of wl_lkm_722_abg.tar.gz 10 The software is a modified version of wl_lkm_722_abg.tar.gz
9 from the Agere Systems website, addapted for Ubuntu 9.04. 11 from the Agere Systems website, addapted for Ubuntu 9.04.
diff --git a/drivers/staging/wlags49_h25/Kconfig b/drivers/staging/wlags49_h25/Kconfig
index dcc170929c13..bf5664a51cd4 100644
--- a/drivers/staging/wlags49_h25/Kconfig
+++ b/drivers/staging/wlags49_h25/Kconfig
@@ -1,9 +1,11 @@
1config WLAGS49_H25 1config WLAGS49_H25
2 tristate "Linksys HERMES II.5 WCF54G_Wireless-G_CompactFlash_Card" 2 tristate "Linksys HERMES II.5 WCF54G_Wireless-G_CompactFlash_Card"
3 depends on WLAN && WIRELESS_EXT && PCMCIA 3 depends on WLAN && PCMCIA
4 select WIRELESS_EXT
4 select WEXT_SPY 5 select WEXT_SPY
6 select WEXT_PRIV
5 ---help--- 7 ---help---
6 Driver for wireless cards using Agere's HERMES II.5 chipset 8 Driver for wireless cards using Agere's HERMES II.5 chipset
7 which are identified with Manufacture ID: 0156,0004 9 which are identified with Manufacture ID: 0156,0004
8 The software is a modified version of wl_lkm_722_abg.tar.gz 10 The software is a modified version of wl_lkm_722_abg.tar.gz
9 from the Agere Systems website, addapted for Ubuntu 9.04. 11 from the Agere Systems website, addapted for Ubuntu 9.04.
diff --git a/drivers/staging/xgifb/Kconfig b/drivers/staging/xgifb/Kconfig
new file mode 100644
index 000000000000..bb0ca5974ea0
--- /dev/null
+++ b/drivers/staging/xgifb/Kconfig
@@ -0,0 +1,11 @@
1config FB_XGI
2 tristate "XGI display support"
3 depends on FB && PCI
4 select FB_CFB_FILLRECT
5 select FB_CFB_COPYAREA
6 select FB_CFB_IMAGEBLIT
7 help
8 This driver supports notebooks with XGI Z7,Z9,Z11 PCI chips.
9 Say Y if you have such a graphics card.
10 To compile this driver as a module, choose M here: the
11 module will be called xgifb.ko
diff --git a/drivers/staging/xgifb/Makefile b/drivers/staging/xgifb/Makefile
new file mode 100644
index 000000000000..2a317707de0f
--- /dev/null
+++ b/drivers/staging/xgifb/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_FB_XGI) += xgifb.o
2
3xgifb-objs := XGI_main_26.o XGI_accel.o vb_init.o vb_setmode.o vb_util.o vb_ext.o
4
diff --git a/drivers/staging/xgifb/TODO b/drivers/staging/xgifb/TODO
new file mode 100644
index 000000000000..7d71019b84c2
--- /dev/null
+++ b/drivers/staging/xgifb/TODO
@@ -0,0 +1,15 @@
1This drivers still need a lot of work. I can list all cleanups to do but it's
2going to be long. So, I'm writing "cleanups" and not the list.
3
4Arnaud
5
6TODO:
7- clean ups
8- fix build warnings when module
9- sort out dup ids with SiS driver
10- remove useless/wrong/unused #ifdef/code/...
11- fix printk usages
12- get rid of non-linux related stuff
13
14Please send patches to:
15Arnaud Patard <apatard@mandriva.com>
diff --git a/drivers/staging/xgifb/XGI.h b/drivers/staging/xgifb/XGI.h
new file mode 100644
index 000000000000..87803dd032de
--- /dev/null
+++ b/drivers/staging/xgifb/XGI.h
@@ -0,0 +1,10 @@
1#ifndef _XGI_H
2#define _XGI_H
3
4#if 1
5#define TWDEBUG(x)
6#else
7#define TWDEBUG(x) printk(KERN_INFO x "\n");
8#endif
9
10#endif
diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c
new file mode 100644
index 000000000000..86ec3421942f
--- /dev/null
+++ b/drivers/staging/xgifb/XGI_accel.c
@@ -0,0 +1,596 @@
1/*
2 * XGI 300/630/730/540/315/550/650/740 frame buffer driver
3 * for Linux kernels 2.4.x and 2.5.x
4 *
5 * 2D acceleration part
6 *
7 * Based on the X driver's XGI300_accel.c which is
8 * Copyright Xavier Ducoin <x.ducoin@lectra.com>
9 * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
10 * and XGI310_accel.c which is
11 * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
12 *
13 * Author: Thomas Winischhofer <thomas@winischhofer.net>
14 * (see http://www.winischhofer.net/
15 * for more information and updates)
16 */
17
18//#include <linux/config.h>
19#include <linux/version.h>
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/errno.h>
23#include <linux/string.h>
24#include <linux/mm.h>
25#include <linux/tty.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28#include <linux/fb.h>
29#include <linux/console.h>
30#include <linux/selection.h>
31#include <linux/ioport.h>
32#include <linux/init.h>
33#include <linux/pci.h>
34#include <linux/vt_kern.h>
35#include <linux/capability.h>
36#include <linux/fs.h>
37#include <linux/agp_backend.h>
38
39#include <linux/types.h>
40/*
41#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
42#include <linux/XGIfb.h>
43#else
44#include <video/XGIfb.h>
45#endif
46*/
47#include <asm/io.h>
48
49#ifdef CONFIG_MTRR
50#include <asm/mtrr.h>
51#endif
52
53#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
54#include <video/fbcon.h>
55#include <video/fbcon-cfb8.h>
56#include <video/fbcon-cfb16.h>
57#include <video/fbcon-cfb24.h>
58#include <video/fbcon-cfb32.h>
59#endif
60
61#include "osdef.h"
62#include "vgatypes.h"
63#include "vb_struct.h"
64#include "XGIfb.h"
65#include "XGI_accel.h"
66
67
68extern struct video_info xgi_video_info;
69extern int XGIfb_accel;
70
71static const int XGIALUConv[] =
72{
73 0x00, /* dest = 0; 0, GXclear, 0 */
74 0x88, /* dest &= src; DSa, GXand, 0x1 */
75 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
76 0xCC, /* dest = src; S, GXcopy, 0x3 */
77 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
78 0xAA, /* dest = dest; D, GXnoop, 0x5 */
79 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
80 0xEE, /* dest |= src; DSo, GXor, 0x7 */
81 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
82 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
83 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
84 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
85 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
86 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
87 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
88 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
89};
90/* same ROP but with Pattern as Source */
91static const int XGIPatALUConv[] =
92{
93 0x00, /* dest = 0; 0, GXclear, 0 */
94 0xA0, /* dest &= src; DPa, GXand, 0x1 */
95 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
96 0xF0, /* dest = src; P, GXcopy, 0x3 */
97 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
98 0xAA, /* dest = dest; D, GXnoop, 0x5 */
99 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
100 0xFA, /* dest |= src; DPo, GXor, 0x7 */
101 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
102 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
103 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
104 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
105 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
106 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
107 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
108 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
109};
110
111#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
112static const unsigned char myrops[] = {
113 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
114 };
115#endif
116
117/* 300 series */
118#if 0
119static void
120XGI300Sync(void)
121{
122 XGI300Idle
123}
124#endif
125static void
126XGI310Sync(void)
127{
128 XGI310Idle
129}
130#if 0
131static void
132XGI300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
133 unsigned int planemask, int trans_color)
134{
135 XGI300SetupDSTColorDepth(xgi_video_info.DstColor);
136 XGI300SetupSRCPitch(xgi_video_info.video_linelength)
137 XGI300SetupDSTRect(xgi_video_info.video_linelength, 0xFFF)
138
139 if(trans_color != -1) {
140 XGI300SetupROP(0x0A)
141 XGI300SetupSRCTrans(trans_color)
142 XGI300SetupCMDFlag(TRANSPARENT_BITBLT)
143 } else {
144 XGI300SetupROP(XGIALUConv[rop])
145 }
146 if(xdir > 0) {
147 XGI300SetupCMDFlag(X_INC)
148 }
149 if(ydir > 0) {
150 XGI300SetupCMDFlag(Y_INC)
151 }
152}
153
154static void
155XGI300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
156 int width, int height)
157{
158 long srcbase, dstbase;
159
160 srcbase = dstbase = 0;
161 if (src_y >= 2048) {
162 srcbase = xgi_video_info.video_linelength * src_y;
163 src_y = 0;
164 }
165 if (dst_y >= 2048) {
166 dstbase = xgi_video_info.video_linelength * dst_y;
167 dst_y = 0;
168 }
169
170 XGI300SetupSRCBase(srcbase);
171 XGI300SetupDSTBase(dstbase);
172
173 if(!(xgi_video_info.CommandReg & X_INC)) {
174 src_x += width-1;
175 dst_x += width-1;
176 }
177 if(!(xgi_video_info.CommandReg & Y_INC)) {
178 src_y += height-1;
179 dst_y += height-1;
180 }
181 XGI300SetupRect(width, height)
182 XGI300SetupSRCXY(src_x, src_y)
183 XGI300SetupDSTXY(dst_x, dst_y)
184 XGI300DoCMD
185}
186
187static void
188XGI300SetupForSolidFill(int color, int rop, unsigned int planemask)
189{
190 XGI300SetupPATFG(color)
191 XGI300SetupDSTRect(xgi_video_info.video_linelength, 0xFFF)
192 XGI300SetupDSTColorDepth(xgi_video_info.DstColor);
193 XGI300SetupROP(XGIPatALUConv[rop])
194 XGI300SetupCMDFlag(PATFG)
195}
196
197static void
198XGI300SubsequentSolidFillRect(int x, int y, int w, int h)
199{
200 long dstbase;
201
202 dstbase = 0;
203 if(y >= 2048) {
204 dstbase = xgi_video_info.video_linelength * y;
205 y = 0;
206 }
207 XGI300SetupDSTBase(dstbase)
208 XGI300SetupDSTXY(x,y)
209 XGI300SetupRect(w,h)
210 XGI300SetupCMDFlag(X_INC | Y_INC | BITBLT)
211 XGI300DoCMD
212}
213#endif
214/* 310/325 series ------------------------------------------------ */
215
216static void
217XGI310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
218 unsigned int planemask, int trans_color)
219{
220 XGI310SetupDSTColorDepth(xgi_video_info.DstColor);
221 XGI310SetupSRCPitch(xgi_video_info.video_linelength)
222 XGI310SetupDSTRect(xgi_video_info.video_linelength, 0xFFF)
223 if (trans_color != -1) {
224 XGI310SetupROP(0x0A)
225 XGI310SetupSRCTrans(trans_color)
226 XGI310SetupCMDFlag(TRANSPARENT_BITBLT)
227 } else {
228 XGI310SetupROP(XGIALUConv[rop])
229 /* Set command - not needed, both 0 */
230 /* XGISetupCMDFlag(BITBLT | SRCVIDEO) */
231 }
232 XGI310SetupCMDFlag(xgi_video_info.XGI310_AccelDepth)
233 /* TW: The 310/325 series is smart enough to know the direction */
234}
235
236static void
237XGI310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
238 int width, int height)
239{
240 long srcbase, dstbase;
241 int mymin, mymax;
242
243 srcbase = dstbase = 0;
244 mymin = min(src_y, dst_y);
245 mymax = max(src_y, dst_y);
246
247 /* Although the chip knows the direction to use
248 * if the source and destination areas overlap,
249 * that logic fails if we fiddle with the bitmap
250 * addresses. Therefore, we check if the source
251 * and destination blitting areas overlap and
252 * adapt the bitmap addresses synchronously
253 * if the coordinates exceed the valid range.
254 * The the areas do not overlap, we do our
255 * normal check.
256 */
257 if((mymax - mymin) < height) {
258 if((src_y >= 2048) || (dst_y >= 2048)) {
259 srcbase = xgi_video_info.video_linelength * mymin;
260 dstbase = xgi_video_info.video_linelength * mymin;
261 src_y -= mymin;
262 dst_y -= mymin;
263 }
264 } else {
265 if(src_y >= 2048) {
266 srcbase = xgi_video_info.video_linelength * src_y;
267 src_y = 0;
268 }
269 if(dst_y >= 2048) {
270 dstbase = xgi_video_info.video_linelength * dst_y;
271 dst_y = 0;
272 }
273 }
274
275 XGI310SetupSRCBase(srcbase);
276 XGI310SetupDSTBase(dstbase);
277 XGI310SetupRect(width, height)
278 XGI310SetupSRCXY(src_x, src_y)
279 XGI310SetupDSTXY(dst_x, dst_y)
280 XGI310DoCMD
281}
282
283static void
284XGI310SetupForSolidFill(int color, int rop, unsigned int planemask)
285{
286 XGI310SetupPATFG(color)
287 XGI310SetupDSTRect(xgi_video_info.video_linelength, 0xFFF)
288 XGI310SetupDSTColorDepth(xgi_video_info.DstColor);
289 XGI310SetupROP(XGIPatALUConv[rop])
290 XGI310SetupCMDFlag(PATFG | xgi_video_info.XGI310_AccelDepth)
291}
292
293static void
294XGI310SubsequentSolidFillRect(int x, int y, int w, int h)
295{
296 long dstbase;
297
298 dstbase = 0;
299 if(y >= 2048) {
300 dstbase = xgi_video_info.video_linelength * y;
301 y = 0;
302 }
303 XGI310SetupDSTBase(dstbase)
304 XGI310SetupDSTXY(x,y)
305 XGI310SetupRect(w,h)
306 XGI310SetupCMDFlag(BITBLT)
307 XGI310DoCMD
308}
309
310/* --------------------------------------------------------------------- */
311
312/* The exported routines */
313
314int XGIfb_initaccel(void)
315{
316#ifdef XGIFB_USE_SPINLOCKS
317 spin_lock_init(&xgi_video_info.lockaccel);
318#endif
319 return(0);
320}
321
322void XGIfb_syncaccel(void)
323{
324
325 XGI310Sync();
326
327}
328
329#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) /* --- KERNEL 2.5.34 and later --- */
330
331int fbcon_XGI_sync(struct fb_info *info)
332{
333 if(!XGIfb_accel) return 0;
334 CRITFLAGS
335
336 XGI310Sync();
337
338 CRITEND
339 return 0;
340}
341
342void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
343{
344 int col=0;
345 CRITFLAGS
346
347
348 if(!rect->width || !rect->height)
349 return;
350
351 if(!XGIfb_accel) {
352 cfb_fillrect(info, rect);
353 return;
354 }
355
356 switch(info->var.bits_per_pixel) {
357 case 8: col = rect->color;
358 break;
359 case 16: col = ((u32 *)(info->pseudo_palette))[rect->color];
360 break;
361 case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
362 break;
363 }
364
365
366 CRITBEGIN
367 XGI310SetupForSolidFill(col, myrops[rect->rop], 0);
368 XGI310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
369 CRITEND
370 XGI310Sync();
371
372
373}
374
375void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area)
376{
377 int xdir, ydir;
378 CRITFLAGS
379
380
381 if(!XGIfb_accel) {
382 cfb_copyarea(info, area);
383 return;
384 }
385
386 if(!area->width || !area->height)
387 return;
388
389 if(area->sx < area->dx) xdir = 0;
390 else xdir = 1;
391 if(area->sy < area->dy) ydir = 0;
392 else ydir = 1;
393
394 CRITBEGIN
395 XGI310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
396 XGI310SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
397 CRITEND
398 XGI310Sync();
399
400}
401
402#endif
403
404#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33) /* ------ KERNEL <2.5.34 ------ */
405
406void fbcon_XGI_bmove(struct display *p, int srcy, int srcx,
407 int dsty, int dstx, int height, int width)
408{
409 int xdir, ydir;
410 CRITFLAGS
411
412 if(!xgi_video_info.accel) {
413 switch(xgi_video_info.video_bpp) {
414 case 8:
415#ifdef FBCON_HAS_CFB8
416 fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
417#endif
418 break;
419 case 16:
420#ifdef FBCON_HAS_CFB16
421 fbcon_cfb16_bmove(p, srcy, srcx, dsty, dstx, height, width);
422#endif
423 break;
424 case 32:
425#ifdef FBCON_HAS_CFB32
426 fbcon_cfb32_bmove(p, srcy, srcx, dsty, dstx, height, width);
427#endif
428 break;
429 }
430 return;
431 }
432
433 srcx *= fontwidth(p);
434 srcy *= fontheight(p);
435 dstx *= fontwidth(p);
436 dsty *= fontheight(p);
437 width *= fontwidth(p);
438 height *= fontheight(p);
439
440 if(srcx < dstx) xdir = 0;
441 else xdir = 1;
442 if(srcy < dsty) ydir = 0;
443 else ydir = 1;
444
445
446 CRITBEGIN
447 XGI310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
448 XGI310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
449 CRITEND
450 XGI310Sync();
451#if 0
452 printk(KERN_INFO "XGI_bmove sx %d sy %d dx %d dy %d w %d h %d\n",
453 srcx, srcy, dstx, dsty, width, height);
454#endif
455
456}
457
458
459static void fbcon_XGI_clear(struct vc_data *conp, struct display *p,
460 int srcy, int srcx, int height, int width, int color)
461{
462 CRITFLAGS
463
464 srcx *= fontwidth(p);
465 srcy *= fontheight(p);
466 width *= fontwidth(p);
467 height *= fontheight(p);
468
469
470 CRITBEGIN
471 XGI310SetupForSolidFill(color, 3, 0);
472 XGI310SubsequentSolidFillRect(srcx, srcy, width, height);
473 CRITEND
474 XGI310Sync();
475
476}
477
478void fbcon_XGI_clear8(struct vc_data *conp, struct display *p,
479 int srcy, int srcx, int height, int width)
480{
481 u32 bgx;
482
483 if(!xgi_video_info.accel) {
484#ifdef FBCON_HAS_CFB8
485 fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
486#endif
487 return;
488 }
489
490 bgx = attr_bgcol_ec(p, conp);
491 fbcon_XGI_clear(conp, p, srcy, srcx, height, width, bgx);
492}
493
494void fbcon_XGI_clear16(struct vc_data *conp, struct display *p,
495 int srcy, int srcx, int height, int width)
496{
497 u32 bgx;
498 if(!xgi_video_info.accel) {
499#ifdef FBCON_HAS_CFB16
500 fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
501#endif
502 return;
503 }
504
505 bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
506 fbcon_XGI_clear(conp, p, srcy, srcx, height, width, bgx);
507}
508
509void fbcon_XGI_clear32(struct vc_data *conp, struct display *p,
510 int srcy, int srcx, int height, int width)
511{
512 u32 bgx;
513
514 if(!xgi_video_info.accel) {
515#ifdef FBCON_HAS_CFB32
516 fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
517#endif
518 return;
519 }
520
521 bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
522 fbcon_XGI_clear(conp, p, srcy, srcx, height, width, bgx);
523}
524
525void fbcon_XGI_revc(struct display *p, int srcx, int srcy)
526{
527 CRITFLAGS
528
529 if(!xgi_video_info.accel) {
530 switch(xgi_video_info.video_bpp) {
531 case 16:
532#ifdef FBCON_HAS_CFB16
533 fbcon_cfb16_revc(p, srcx, srcy);
534#endif
535 break;
536 case 32:
537#ifdef FBCON_HAS_CFB32
538 fbcon_cfb32_revc(p, srcx, srcy);
539#endif
540 break;
541 }
542 return;
543 }
544
545 srcx *= fontwidth(p);
546 srcy *= fontheight(p);
547
548
549 CRITBEGIN
550 XGI310SetupForSolidFill(0, 0x0a, 0);
551 XGI310SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
552 CRITEND
553 XGI310Sync();
554
555}
556
557#ifdef FBCON_HAS_CFB8
558struct display_switch fbcon_XGI8 = {
559 setup: fbcon_cfb8_setup,
560 bmove: fbcon_XGI_bmove,
561 clear: fbcon_XGI_clear8,
562 putc: fbcon_cfb8_putc,
563 putcs: fbcon_cfb8_putcs,
564 revc: fbcon_cfb8_revc,
565 clear_margins: fbcon_cfb8_clear_margins,
566 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
567};
568#endif
569#ifdef FBCON_HAS_CFB16
570struct display_switch fbcon_XGI16 = {
571 setup: fbcon_cfb16_setup,
572 bmove: fbcon_XGI_bmove,
573 clear: fbcon_XGI_clear16,
574 putc: fbcon_cfb16_putc,
575 putcs: fbcon_cfb16_putcs,
576 revc: fbcon_XGI_revc,
577 clear_margins: fbcon_cfb16_clear_margins,
578 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
579};
580#endif
581#ifdef FBCON_HAS_CFB32
582struct display_switch fbcon_XGI32 = {
583 setup: fbcon_cfb32_setup,
584 bmove: fbcon_XGI_bmove,
585 clear: fbcon_XGI_clear32,
586 putc: fbcon_cfb32_putc,
587 putcs: fbcon_cfb32_putcs,
588 revc: fbcon_XGI_revc,
589 clear_margins: fbcon_cfb32_clear_margins,
590 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
591};
592#endif
593
594#endif /* KERNEL VERSION */
595
596
diff --git a/drivers/staging/xgifb/XGI_accel.h b/drivers/staging/xgifb/XGI_accel.h
new file mode 100644
index 000000000000..04e126772bb8
--- /dev/null
+++ b/drivers/staging/xgifb/XGI_accel.h
@@ -0,0 +1,511 @@
1/*
2 * XGI 300/630/730/540/315/550/650/740 frame buffer driver
3 * for Linux kernels 2.4.x and 2.5.x
4 *
5 * 2D acceleration part
6 *
7 * Based on the X driver's XGI300_accel.h which is
8 * Copyright Xavier Ducoin <x.ducoin@lectra.com>
9 * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
10 * and XGI310_accel.h which is
11 * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
12 *
13 * Author: Thomas Winischhofer <thomas@winischhofer.net>:
14 * (see http://www.winischhofer.net/
15 * for more information and updates)
16 */
17
18#ifndef _XGIFB_ACCEL_H
19#define _XGIFB_ACCEL_H
20
21/* Guard accelerator accesses with spin_lock_irqsave? Works well without. */
22#undef XGIFB_USE_SPINLOCKS
23
24#ifdef XGIFB_USE_SPINLOCKS
25#include <linux/spinlock.h>
26#define CRITBEGIN spin_lock_irqsave(&xgi_video_info.lockaccel), critflags);
27#define CRITEND spin_unlock_irqrestore(&xgi_video_info.lockaccel), critflags);
28#define CRITFLAGS unsigned long critflags;
29#else
30#define CRITBEGIN
31#define CRITEND
32#define CRITFLAGS
33#endif
34
35/* Definitions for the XGI engine communication. */
36
37#define PATREGSIZE 384 /* Pattern register size. 384 bytes @ 0x8300 */
38#define BR(x) (0x8200 | (x) << 2)
39#define PBR(x) (0x8300 | (x) << 2)
40
41/* XGI300 engine commands */
42#define BITBLT 0x00000000 /* Blit */
43#define COLOREXP 0x00000001 /* Color expand */
44#define ENCOLOREXP 0x00000002 /* Enhanced color expand */
45#define MULTIPLE_SCANLINE 0x00000003 /* ? */
46#define LINE 0x00000004 /* Draw line */
47#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */
48#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */
49
50/* Additional engine commands for 310/325 */
51#define ALPHA_BLEND 0x00000007 /* Alpha blend ? */
52#define A3D_FUNCTION 0x00000008 /* 3D command ? */
53#define CLEAR_Z_BUFFER 0x00000009 /* ? */
54#define GRADIENT_FILL 0x0000000A /* Gradient fill */
55#define STRETCH_BITBLT 0x0000000B /* Stretched Blit */
56
57/* source select */
58#define SRCVIDEO 0x00000000 /* source is video RAM */
59#define SRCSYSTEM 0x00000010 /* source is system memory */
60#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */
61#define SRCAGP 0x00000020 /* source is AGP memory (?) */
62
63/* Pattern flags */
64#define PATFG 0x00000000 /* foreground color */
65#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */
66#define PATMONO 0x00000080 /* mono pattern */
67
68/* blitting direction (300 series only) */
69#define X_INC 0x00010000
70#define X_DEC 0x00000000
71#define Y_INC 0x00020000
72#define Y_DEC 0x00000000
73
74/* Clipping flags */
75#define NOCLIP 0x00000000
76#define NOMERGECLIP 0x04000000
77#define CLIPENABLE 0x00040000
78#define CLIPWITHOUTMERGE 0x04040000
79
80/* Transparency */
81#define OPAQUE 0x00000000
82#define TRANSPARENT 0x00100000
83
84/* ? */
85#define DSTAGP 0x02000000
86#define DSTVIDEO 0x02000000
87
88/* Line */
89#define LINE_STYLE 0x00800000
90#define NO_RESET_COUNTER 0x00400000
91#define NO_LAST_PIXEL 0x00200000
92
93/* Subfunctions for Color/Enhanced Color Expansion (310/325 only) */
94#define COLOR_TO_MONO 0x00100000
95#define AA_TEXT 0x00200000
96
97/* Some general registers for 310/325 series */
98#define SRC_ADDR 0x8200
99#define SRC_PITCH 0x8204
100#define AGP_BASE 0x8206 /* color-depth dependent value */
101#define SRC_Y 0x8208
102#define SRC_X 0x820A
103#define DST_Y 0x820C
104#define DST_X 0x820E
105#define DST_ADDR 0x8210
106#define DST_PITCH 0x8214
107#define DST_HEIGHT 0x8216
108#define RECT_WIDTH 0x8218
109#define RECT_HEIGHT 0x821A
110#define PAT_FGCOLOR 0x821C
111#define PAT_BGCOLOR 0x8220
112#define SRC_FGCOLOR 0x8224
113#define SRC_BGCOLOR 0x8228
114#define MONO_MASK 0x822C
115#define LEFT_CLIP 0x8234
116#define TOP_CLIP 0x8236
117#define RIGHT_CLIP 0x8238
118#define BOTTOM_CLIP 0x823A
119#define COMMAND_READY 0x823C
120#define FIRE_TRIGGER 0x8240
121
122#define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */
123
124/* Line registers */
125#define LINE_X0 SRC_Y
126#define LINE_X1 DST_Y
127#define LINE_Y0 SRC_X
128#define LINE_Y1 DST_X
129#define LINE_COUNT RECT_WIDTH
130#define LINE_STYLE_PERIOD RECT_HEIGHT
131#define LINE_STYLE_0 MONO_MASK
132#define LINE_STYLE_1 0x8230
133#define LINE_XN PATTERN_REG
134#define LINE_YN PATTERN_REG+2
135
136/* Transparent bitblit registers */
137#define TRANS_DST_KEY_HIGH PAT_FGCOLOR
138#define TRANS_DST_KEY_LOW PAT_BGCOLOR
139#define TRANS_SRC_KEY_HIGH SRC_FGCOLOR
140#define TRANS_SRC_KEY_LOW SRC_BGCOLOR
141
142/* Queue */
143#define Q_BASE_ADDR 0x85C0 /* Base address of software queue (?) */
144#define Q_WRITE_PTR 0x85C4 /* Current write pointer (?) */
145#define Q_READ_PTR 0x85C8 /* Current read pointer (?) */
146#define Q_STATUS 0x85CC /* queue status */
147
148
149#define MMIO_IN8(base, offset) \
150 *(volatile u8 *)(((u8*)(base)) + (offset))
151#define MMIO_IN16(base, offset) \
152 *(volatile u16 *)(void *)(((u8*)(base)) + (offset))
153#define MMIO_IN32(base, offset) \
154 *(volatile u32 *)(void *)(((u8*)(base)) + (offset))
155#define MMIO_OUT8(base, offset, val) \
156 *(volatile u8 *)(((u8*)(base)) + (offset)) = (val)
157#define MMIO_OUT16(base, offset, val) \
158 *(volatile u16 *)(void *)(((u8*)(base)) + (offset)) = (val)
159#define MMIO_OUT32(base, offset, val) \
160 *(volatile u32 *)(void *)(((u8*)(base)) + (offset)) = (val)
161
162
163
164/* ------------- XGI 300 series -------------- */
165
166/* Macros to do useful things with the XGI BitBLT engine */
167
168/* BR(16) (0x8420):
169
170 bit 31 2D engine: 1 is idle,
171 bit 30 3D engine: 1 is idle,
172 bit 29 Command queue: 1 is empty
173
174 bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0]
175
176 bits 15:0: Current command queue length
177
178*/
179
180/* TW: BR(16)+2 = 0x8242 */
181
182int xgiCmdQueLen;
183
184#define XGI300Idle \
185 { \
186 while( (MMIO_IN16(xgi_video_info.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
187 while( (MMIO_IN16(xgi_video_info.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
188 while( (MMIO_IN16(xgi_video_info.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
189 xgiCmdQueLen=MMIO_IN16(xgi_video_info.mmio_vbase, 0x8240); \
190 }
191/* TW: (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
192
193#define XGI300SetupSRCBase(base) \
194 if (xgiCmdQueLen <= 0) XGI300Idle;\
195 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(0), base);\
196 xgiCmdQueLen --;
197
198#define XGI300SetupSRCPitch(pitch) \
199 if (xgiCmdQueLen <= 0) XGI300Idle;\
200 MMIO_OUT16(xgi_video_info.mmio_vbase, BR(1), pitch);\
201 xgiCmdQueLen --;
202
203#define XGI300SetupSRCXY(x,y) \
204 if (xgiCmdQueLen <= 0) XGI300Idle;\
205 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(2), (x)<<16 | (y) );\
206 xgiCmdQueLen --;
207
208#define XGI300SetupDSTBase(base) \
209 if (xgiCmdQueLen <= 0) XGI300Idle;\
210 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(4), base);\
211 xgiCmdQueLen --;
212
213#define XGI300SetupDSTXY(x,y) \
214 if (xgiCmdQueLen <= 0) XGI300Idle;\
215 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(3), (x)<<16 | (y) );\
216 xgiCmdQueLen --;
217
218#define XGI300SetupDSTRect(x,y) \
219 if (xgiCmdQueLen <= 0) XGI300Idle;\
220 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(5), (y)<<16 | (x) );\
221 xgiCmdQueLen --;
222
223#define XGI300SetupDSTColorDepth(bpp) \
224 if (xgiCmdQueLen <= 0) XGI300Idle;\
225 MMIO_OUT16(xgi_video_info.mmio_vbase, BR(1)+2, bpp);\
226 xgiCmdQueLen --;
227
228#define XGI300SetupRect(w,h) \
229 if (xgiCmdQueLen <= 0) XGI300Idle;\
230 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(6), (h)<<16 | (w) );\
231 xgiCmdQueLen --;
232
233#define XGI300SetupPATFG(color) \
234 if (xgiCmdQueLen <= 0) XGI300Idle;\
235 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(7), color);\
236 xgiCmdQueLen --;
237
238#define XGI300SetupPATBG(color) \
239 if (xgiCmdQueLen <= 0) XGI300Idle;\
240 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(8), color);\
241 xgiCmdQueLen --;
242
243#define XGI300SetupSRCFG(color) \
244 if (xgiCmdQueLen <= 0) XGI300Idle;\
245 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(9), color);\
246 xgiCmdQueLen --;
247
248#define XGI300SetupSRCBG(color) \
249 if (xgiCmdQueLen <= 0) XGI300Idle;\
250 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(10), color);\
251 xgiCmdQueLen --;
252
253/* 0x8224 src colorkey high */
254/* 0x8228 src colorkey low */
255/* 0x821c dest colorkey high */
256/* 0x8220 dest colorkey low */
257#define XGI300SetupSRCTrans(color) \
258 if (xgiCmdQueLen <= 1) XGI300Idle;\
259 MMIO_OUT32(xgi_video_info.mmio_vbase, 0x8224, color);\
260 MMIO_OUT32(xgi_video_info.mmio_vbase, 0x8228, color);\
261 xgiCmdQueLen -= 2;
262
263#define XGI300SetupDSTTrans(color) \
264 if (xgiCmdQueLen <= 1) XGI300Idle;\
265 MMIO_OUT32(xgi_video_info.mmio_vbase, 0x821C, color); \
266 MMIO_OUT32(xgi_video_info.mmio_vbase, 0x8220, color); \
267 xgiCmdQueLen -= 2;
268
269#define XGI300SetupMONOPAT(p0,p1) \
270 if (xgiCmdQueLen <= 1) XGI300Idle;\
271 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(11), p0);\
272 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(12), p1);\
273 xgiCmdQueLen -= 2;
274
275#define XGI300SetupClipLT(left,top) \
276 if (xgiCmdQueLen <= 0) XGI300Idle;\
277 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
278 xgiCmdQueLen--;
279
280#define XGI300SetupClipRB(right,bottom) \
281 if (xgiCmdQueLen <= 0) XGI300Idle;\
282 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
283 xgiCmdQueLen--;
284
285/* General */
286#define XGI300SetupROP(rop) \
287 xgi_video_info.CommandReg = (rop) << 8;
288
289#define XGI300SetupCMDFlag(flags) \
290 xgi_video_info.CommandReg |= (flags);
291
292#define XGI300DoCMD \
293 if (xgiCmdQueLen <= 1) XGI300Idle;\
294 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(15), xgi_video_info.CommandReg); \
295 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(16), 0);\
296 xgiCmdQueLen -= 2;
297
298/* Line */
299#define XGI300SetupX0Y0(x,y) \
300 if (xgiCmdQueLen <= 0) XGI300Idle;\
301 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(2), (y)<<16 | (x) );\
302 xgiCmdQueLen--;
303
304#define XGI300SetupX1Y1(x,y) \
305 if (xgiCmdQueLen <= 0) XGI300Idle;\
306 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(3), (y)<<16 | (x) );\
307 xgiCmdQueLen--;
308
309#define XGI300SetupLineCount(c) \
310 if (xgiCmdQueLen <= 0) XGI300Idle;\
311 MMIO_OUT16(xgi_video_info.mmio_vbase, BR(6), c);\
312 xgiCmdQueLen--;
313
314#define XGI300SetupStylePeriod(p) \
315 if (xgiCmdQueLen <= 0) XGI300Idle;\
316 MMIO_OUT16(xgi_video_info.mmio_vbase, BR(6)+2, p);\
317 xgiCmdQueLen--;
318
319#define XGI300SetupStyleLow(ls) \
320 if (xgiCmdQueLen <= 0) XGI300Idle;\
321 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(11), ls);\
322 xgiCmdQueLen--;
323
324#define XGI300SetupStyleHigh(ls) \
325 if (xgiCmdQueLen <= 0) XGI300Idle;\
326 MMIO_OUT32(xgi_video_info.mmio_vbase, BR(12), ls);\
327 xgiCmdQueLen--;
328
329
330
331/* ----------- XGI 310/325 series --------------- */
332
333/* Q_STATUS:
334 bit 31 = 1: All engines idle and all queues empty
335 bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty
336 bit 29 = 1: 2D engine is idle
337 bit 28 = 1: 3D engine is idle
338 bit 27 = 1: HW command queue empty
339 bit 26 = 1: 2D queue empty
340 bit 25 = 1: 3D queue empty
341 bit 24 = 1: SW command queue empty
342 bits 23:16: 2D counter 3
343 bits 15:8: 2D counter 2
344 bits 7:0: 2D counter 1
345
346 Where is the command queue length (current amount of commands the queue
347 can accept) on the 310/325 series? (The current implementation is taken
348 from 300 series and certainly wrong...)
349*/
350
351/* TW: FIXME: xgiCmdQueLen is... where....? */
352#define XGI310Idle \
353 { \
354 while( (MMIO_IN16(xgi_video_info.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
355 while( (MMIO_IN16(xgi_video_info.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
356 xgiCmdQueLen=MMIO_IN16(xgi_video_info.mmio_vbase, Q_STATUS); \
357 }
358
359#define XGI310SetupSRCBase(base) \
360 if (xgiCmdQueLen <= 0) XGI310Idle;\
361 MMIO_OUT32(xgi_video_info.mmio_vbase, SRC_ADDR, base);\
362 xgiCmdQueLen--;
363
364#define XGI310SetupSRCPitch(pitch) \
365 if (xgiCmdQueLen <= 0) XGI310Idle;\
366 MMIO_OUT16(xgi_video_info.mmio_vbase, SRC_PITCH, pitch);\
367 xgiCmdQueLen--;
368
369#define XGI310SetupSRCXY(x,y) \
370 if (xgiCmdQueLen <= 0) XGI310Idle;\
371 MMIO_OUT32(xgi_video_info.mmio_vbase, SRC_Y, (x)<<16 | (y) );\
372 xgiCmdQueLen--;
373
374#define XGI310SetupDSTBase(base) \
375 if (xgiCmdQueLen <= 0) XGI310Idle;\
376 MMIO_OUT32(xgi_video_info.mmio_vbase, DST_ADDR, base);\
377 xgiCmdQueLen--;
378
379#define XGI310SetupDSTXY(x,y) \
380 if (xgiCmdQueLen <= 0) XGI310Idle;\
381 MMIO_OUT32(xgi_video_info.mmio_vbase, DST_Y, (x)<<16 | (y) );\
382 xgiCmdQueLen--;
383
384#define XGI310SetupDSTRect(x,y) \
385 if (xgiCmdQueLen <= 0) XGI310Idle;\
386 MMIO_OUT32(xgi_video_info.mmio_vbase, DST_PITCH, (y)<<16 | (x) );\
387 xgiCmdQueLen--;
388
389#define XGI310SetupDSTColorDepth(bpp) \
390 if (xgiCmdQueLen <= 0) XGI310Idle;\
391 MMIO_OUT16(xgi_video_info.mmio_vbase, AGP_BASE, bpp);\
392 xgiCmdQueLen--;
393
394#define XGI310SetupRect(w,h) \
395 if (xgiCmdQueLen <= 0) XGI310Idle;\
396 MMIO_OUT32(xgi_video_info.mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\
397 xgiCmdQueLen--;
398
399#define XGI310SetupPATFG(color) \
400 if (xgiCmdQueLen <= 0) XGI310Idle;\
401 MMIO_OUT32(xgi_video_info.mmio_vbase, PAT_FGCOLOR, color);\
402 xgiCmdQueLen--;
403
404#define XGI310SetupPATBG(color) \
405 if (xgiCmdQueLen <= 0) XGI310Idle;\
406 MMIO_OUT32(xgi_video_info.mmio_vbase, PAT_BGCOLOR, color);\
407 xgiCmdQueLen--;
408
409#define XGI310SetupSRCFG(color) \
410 if (xgiCmdQueLen <= 0) XGI310Idle;\
411 MMIO_OUT32(xgi_video_info.mmio_vbase, SRC_FGCOLOR, color);\
412 xgiCmdQueLen--;
413
414#define XGI310SetupSRCBG(color) \
415 if (xgiCmdQueLen <= 0) XGI310Idle;\
416 MMIO_OUT32(xgi_video_info.mmio_vbase, SRC_BGCOLOR, color);\
417 xgiCmdQueLen--;
418
419#define XGI310SetupSRCTrans(color) \
420 if (xgiCmdQueLen <= 1) XGI310Idle;\
421 MMIO_OUT32(xgi_video_info.mmio_vbase, TRANS_SRC_KEY_HIGH, color);\
422 MMIO_OUT32(xgi_video_info.mmio_vbase, TRANS_SRC_KEY_LOW, color);\
423 xgiCmdQueLen -= 2;
424
425#define XGI310SetupDSTTrans(color) \
426 if (xgiCmdQueLen <= 1) XGI310Idle;\
427 MMIO_OUT32(xgi_video_info.mmio_vbase, TRANS_DST_KEY_HIGH, color); \
428 MMIO_OUT32(xgi_video_info.mmio_vbase, TRANS_DST_KEY_LOW, color); \
429 xgiCmdQueLen -= 2;
430
431#define XGI310SetupMONOPAT(p0,p1) \
432 if (xgiCmdQueLen <= 1) XGI310Idle;\
433 MMIO_OUT32(xgi_video_info.mmio_vbase, MONO_MASK, p0);\
434 MMIO_OUT32(xgi_video_info.mmio_vbase, MONO_MASK+4, p1);\
435 xgiCmdQueLen -= 2;
436
437#define XGI310SetupClipLT(left,top) \
438 if (xgiCmdQueLen <= 0) XGI310Idle;\
439 MMIO_OUT32(xgi_video_info.mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
440 xgiCmdQueLen--;
441
442#define XGI310SetupClipRB(right,bottom) \
443 if (xgiCmdQueLen <= 0) XGI310Idle;\
444 MMIO_OUT32(xgi_video_info.mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
445 xgiCmdQueLen--;
446
447#define XGI310SetupROP(rop) \
448 xgi_video_info.CommandReg = (rop) << 8;
449
450#define XGI310SetupCMDFlag(flags) \
451 xgi_video_info.CommandReg |= (flags);
452
453#define XGI310DoCMD \
454 if (xgiCmdQueLen <= 1) XGI310Idle;\
455 MMIO_OUT32(xgi_video_info.mmio_vbase, COMMAND_READY, xgi_video_info.CommandReg); \
456 MMIO_OUT32(xgi_video_info.mmio_vbase, FIRE_TRIGGER, 0); \
457 xgiCmdQueLen -= 2;
458
459#define XGI310SetupX0Y0(x,y) \
460 if (xgiCmdQueLen <= 0) XGI310Idle;\
461 MMIO_OUT32(xgi_video_info.mmio_vbase, LINE_X0, (y)<<16 | (x) );\
462 xgiCmdQueLen--;
463
464#define XGI310SetupX1Y1(x,y) \
465 if (xgiCmdQueLen <= 0) XGI310Idle;\
466 MMIO_OUT32(xgi_video_info.mmio_vbase, LINE_X1, (y)<<16 | (x) );\
467 xgiCmdQueLen--;
468
469#define XGI310SetupLineCount(c) \
470 if (xgiCmdQueLen <= 0) XGI310Idle;\
471 MMIO_OUT16(xgi_video_info.mmio_vbase, LINE_COUNT, c);\
472 xgiCmdQueLen--;
473
474#define XGI310SetupStylePeriod(p) \
475 if (xgiCmdQueLen <= 0) XGI310Idle;\
476 MMIO_OUT16(xgi_video_info.mmio_vbase, LINE_STYLE_PERIOD, p);\
477 xgiCmdQueLen--;
478
479#define XGI310SetupStyleLow(ls) \
480 if (xgiCmdQueLen <= 0) XGI310Idle;\
481 MMIO_OUT32(xgi_video_info.mmio_vbase, LINE_STYLE_0, ls);\
482 xgiCmdQueLen--;
483
484#define XGI310SetupStyleHigh(ls) \
485 if (xgiCmdQueLen <= 0) XGI310Idle;\
486 MMIO_OUT32(xgi_video_info.mmio_vbase, LINE_STYLE_1, ls);\
487 xgiCmdQueLen--;
488
489int XGIfb_initaccel(void);
490void XGIfb_syncaccel(void);
491
492extern struct video_info xgi_video_info;
493
494#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
495void fbcon_XGI_bmove(struct display *p, int srcy, int srcx, int dsty,
496 int dstx, int height, int width);
497void fbcon_XGI_revc(struct display *p, int srcy, int srcx);
498void fbcon_XGI_clear8(struct vc_data *conp, struct display *p, int srcy,
499 int srcx, int height, int width);
500void fbcon_XGI_clear16(struct vc_data *conp, struct display *p, int srcy,
501 int srcx, int height, int width);
502void fbcon_XGI_clear32(struct vc_data *conp, struct display *p, int srcy,
503 int srcx, int height, int width);
504#endif
505#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
506extern int XGIfb_accel;
507void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
508void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area);
509#endif
510
511#endif
diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h
new file mode 100644
index 000000000000..4f4171e8a68a
--- /dev/null
+++ b/drivers/staging/xgifb/XGI_main.h
@@ -0,0 +1,1023 @@
1#ifndef _XGIFB_MAIN
2#define _XGIFB_MAIN
3
4
5/* ------------------- Constant Definitions ------------------------- */
6
7
8#include "XGIfb.h"
9#include "vb_struct.h"
10#include "vb_def.h"
11
12//#define LINUXBIOS /* turn this on when compiling for LINUXBIOS */
13#define AGPOFF /* default is turn off AGP */
14
15#define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
16
17#define VER_MAJOR 0
18#define VER_MINOR 8
19#define VER_LEVEL 1
20
21#define DRIVER_DESC "XGI Volari Frame Buffer Module Version 0.8.1"
22
23#ifndef PCI_VENDOR_ID_XG
24#define PCI_VENDOR_ID_XG 0x18CA
25#endif
26
27#ifndef PCI_DEVICE_ID_XG_40
28#define PCI_DEVICE_ID_XG_40 0x040
29#endif
30#ifndef PCI_DEVICE_ID_XG_41
31#define PCI_DEVICE_ID_XG_41 0x041
32#endif
33#ifndef PCI_DEVICE_ID_XG_42
34#define PCI_DEVICE_ID_XG_42 0x042
35#endif
36#ifndef PCI_DEVICE_ID_XG_20
37#define PCI_DEVICE_ID_XG_20 0x020
38#endif
39#ifndef PCI_DEVICE_ID_XG_27
40#define PCI_DEVICE_ID_XG_27 0x027
41#endif
42
43
44
45#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
46#define XGI_IOTYPE1 void __iomem
47#define XGI_IOTYPE2 __iomem
48#define XGIINITSTATIC static
49#else
50#define XGI_IOTYPE1 unsigned char
51#define XGI_IOTYPE2
52#define XGIINITSTATIC
53#endif
54
55#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
56static struct pci_device_id __devinitdata xgifb_pci_table[] = {
57
58 { PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
59 { PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_27, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
60 { PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_40, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
61 { PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
62 { 0 }
63};
64
65MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
66#endif
67/* To be included in fb.h */
68#ifndef FB_ACCEL_XGI_GLAMOUR_2
69#define FB_ACCEL_XGI_GLAMOUR_2 40 /* XGI 315, 650, 740 */
70#endif
71#ifndef FB_ACCEL_XGI_XABRE
72#define FB_ACCEL_XGI_XABRE 41 /* XGI 330 ("Xabre") */
73#endif
74
75#define MAX_ROM_SCAN 0x10000
76
77#define HW_CURSOR_CAP 0x80
78#define TURBO_QUEUE_CAP 0x40
79#define AGP_CMD_QUEUE_CAP 0x20
80#define VM_CMD_QUEUE_CAP 0x10
81#define MMIO_CMD_QUEUE_CAP 0x08
82
83
84
85/* For 315 series */
86
87#define COMMAND_QUEUE_AREA_SIZE 0x80000 /* 512K */
88#define COMMAND_QUEUE_THRESHOLD 0x1F
89
90
91/* TW */
92#define HW_CURSOR_AREA_SIZE_315 0x4000 /* 16K */
93#define HW_CURSOR_AREA_SIZE_300 0x1000 /* 4K */
94
95#define OH_ALLOC_SIZE 4000
96#define SENTINEL 0x7fffffff
97
98#define SEQ_ADR 0x14
99#define SEQ_DATA 0x15
100#define DAC_ADR 0x18
101#define DAC_DATA 0x19
102#define CRTC_ADR 0x24
103#define CRTC_DATA 0x25
104#define DAC2_ADR (0x16-0x30)
105#define DAC2_DATA (0x17-0x30)
106#define VB_PART1_ADR (0x04-0x30)
107#define VB_PART1_DATA (0x05-0x30)
108#define VB_PART2_ADR (0x10-0x30)
109#define VB_PART2_DATA (0x11-0x30)
110#define VB_PART3_ADR (0x12-0x30)
111#define VB_PART3_DATA (0x13-0x30)
112#define VB_PART4_ADR (0x14-0x30)
113#define VB_PART4_DATA (0x15-0x30)
114
115#define XGISR XGI_Pr.P3c4
116#define XGICR XGI_Pr.P3d4
117#define XGIDACA XGI_Pr.P3c8
118#define XGIDACD XGI_Pr.P3c9
119#define XGIPART1 XGI_Pr.Part1Port
120#define XGIPART2 XGI_Pr.Part2Port
121#define XGIPART3 XGI_Pr.Part3Port
122#define XGIPART4 XGI_Pr.Part4Port
123#define XGIPART5 XGI_Pr.Part5Port
124#define XGIDAC2A XGIPART5
125#define XGIDAC2D (XGIPART5 + 1)
126#define XGIMISCR (XGI_Pr.RelIO + 0x1c)
127#define XGIINPSTAT (XGI_Pr.RelIO + 0x2a)
128
129#define IND_XGI_PASSWORD 0x05 /* SRs */
130#define IND_XGI_COLOR_MODE 0x06
131#define IND_XGI_RAMDAC_CONTROL 0x07
132#define IND_XGI_DRAM_SIZE 0x14
133#define IND_XGI_SCRATCH_REG_16 0x16
134#define IND_XGI_SCRATCH_REG_17 0x17
135#define IND_XGI_SCRATCH_REG_1A 0x1A
136#define IND_XGI_MODULE_ENABLE 0x1E
137#define IND_XGI_PCI_ADDRESS_SET 0x20
138#define IND_XGI_TURBOQUEUE_ADR 0x26
139#define IND_XGI_TURBOQUEUE_SET 0x27
140#define IND_XGI_POWER_ON_TRAP 0x38
141#define IND_XGI_POWER_ON_TRAP2 0x39
142#define IND_XGI_CMDQUEUE_SET 0x26
143#define IND_XGI_CMDQUEUE_THRESHOLD 0x27
144
145#define IND_XGI_SCRATCH_REG_CR30 0x30 /* CRs */
146#define IND_XGI_SCRATCH_REG_CR31 0x31
147#define IND_XGI_SCRATCH_REG_CR32 0x32
148#define IND_XGI_SCRATCH_REG_CR33 0x33
149#define IND_XGI_LCD_PANEL 0x36
150#define IND_XGI_SCRATCH_REG_CR37 0x37
151#define IND_XGI_AGP_IO_PAD 0x48
152
153#define IND_BRI_DRAM_STATUS 0x63 /* PCI config memory size offset */
154
155#define MMIO_QUEUE_PHYBASE 0x85C0
156#define MMIO_QUEUE_WRITEPORT 0x85C4
157#define MMIO_QUEUE_READPORT 0x85C8
158
159#define IND_XGI_CRT2_WRITE_ENABLE_300 0x24
160#define IND_XGI_CRT2_WRITE_ENABLE_315 0x2F
161
162#define XGI_PASSWORD 0x86 /* SR05 */
163#define XGI_INTERLACED_MODE 0x20 /* SR06 */
164#define XGI_8BPP_COLOR_MODE 0x0
165#define XGI_15BPP_COLOR_MODE 0x1
166#define XGI_16BPP_COLOR_MODE 0x2
167#define XGI_32BPP_COLOR_MODE 0x4
168
169#define XGI_DRAM_SIZE_MASK 0xF0 /*SR14 */
170#define XGI_DRAM_SIZE_1MB 0x00
171#define XGI_DRAM_SIZE_2MB 0x01
172#define XGI_DRAM_SIZE_4MB 0x02
173#define XGI_DRAM_SIZE_8MB 0x03
174#define XGI_DRAM_SIZE_16MB 0x04
175#define XGI_DRAM_SIZE_32MB 0x05
176#define XGI_DRAM_SIZE_64MB 0x06
177#define XGI_DRAM_SIZE_128MB 0x07
178#define XGI_DRAM_SIZE_256MB 0x08
179#define XGI_DATA_BUS_MASK 0x02
180#define XGI_DATA_BUS_64 0x00
181#define XGI_DATA_BUS_128 0x01
182#define XGI_DUAL_CHANNEL_MASK 0x0C
183#define XGI_SINGLE_CHANNEL_1_RANK 0x0
184#define XGI_SINGLE_CHANNEL_2_RANK 0x1
185#define XGI_ASYM_DDR 0x02
186#define XGI_DUAL_CHANNEL_1_RANK 0x3
187
188#define XGI550_DRAM_SIZE_MASK 0x3F /* 550/650/740 SR14 */
189#define XGI550_DRAM_SIZE_4MB 0x00
190#define XGI550_DRAM_SIZE_8MB 0x01
191#define XGI550_DRAM_SIZE_16MB 0x03
192#define XGI550_DRAM_SIZE_24MB 0x05
193#define XGI550_DRAM_SIZE_32MB 0x07
194#define XGI550_DRAM_SIZE_64MB 0x0F
195#define XGI550_DRAM_SIZE_96MB 0x17
196#define XGI550_DRAM_SIZE_128MB 0x1F
197#define XGI550_DRAM_SIZE_256MB 0x3F
198
199#define XGI_SCRATCH_REG_1A_MASK 0x10
200
201#define XGI_ENABLE_2D 0x40 /* SR1E */
202
203#define XGI_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
204#define XGI_PCI_ADDR_ENABLE 0x80
205
206#define XGI_AGP_CMDQUEUE_ENABLE 0x80 /* 315/650/740 SR26 */
207#define XGI_VRAM_CMDQUEUE_ENABLE 0x40
208#define XGI_MMIO_CMD_ENABLE 0x20
209#define XGI_CMD_QUEUE_SIZE_512k 0x00
210#define XGI_CMD_QUEUE_SIZE_1M 0x04
211#define XGI_CMD_QUEUE_SIZE_2M 0x08
212#define XGI_CMD_QUEUE_SIZE_4M 0x0C
213#define XGI_CMD_QUEUE_RESET 0x01
214#define XGI_CMD_AUTO_CORR 0x02
215
216#define XGI_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
217#define XGI_MODE_SELECT_CRT2 0x02
218#define XGI_VB_OUTPUT_COMPOSITE 0x04
219#define XGI_VB_OUTPUT_SVIDEO 0x08
220#define XGI_VB_OUTPUT_SCART 0x10
221#define XGI_VB_OUTPUT_LCD 0x20
222#define XGI_VB_OUTPUT_CRT2 0x40
223#define XGI_VB_OUTPUT_HIVISION 0x80
224
225#define XGI_VB_OUTPUT_DISABLE 0x20 /* CR31 */
226#define XGI_DRIVER_MODE 0x40
227
228#define XGI_VB_COMPOSITE 0x01 /* CR32 */
229#define XGI_VB_SVIDEO 0x02
230#define XGI_VB_SCART 0x04
231#define XGI_VB_LCD 0x08
232#define XGI_VB_CRT2 0x10
233#define XGI_CRT1 0x20
234#define XGI_VB_HIVISION 0x40
235#define XGI_VB_YPBPR 0x80
236#define XGI_VB_TV (XGI_VB_COMPOSITE | XGI_VB_SVIDEO | \
237 XGI_VB_SCART | XGI_VB_HIVISION|XGI_VB_YPBPR)
238
239#define XGI_EXTERNAL_CHIP_MASK 0x0E /* CR37 */
240#define XGI_EXTERNAL_CHIP_XGI301 0x01 /* in CR37 << 1 ! */
241#define XGI_EXTERNAL_CHIP_LVDS 0x02 /* in CR37 << 1 ! */
242#define XGI_EXTERNAL_CHIP_TRUMPION 0x03 /* in CR37 << 1 ! */
243#define XGI_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04 /* in CR37 << 1 ! */
244#define XGI_EXTERNAL_CHIP_CHRONTEL 0x05 /* in CR37 << 1 ! */
245#define XGI310_EXTERNAL_CHIP_LVDS 0x02 /* in CR37 << 1 ! */
246#define XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03 /* in CR37 << 1 ! */
247
248#define XGI_AGP_2X 0x20 /* CR48 */
249
250#define BRI_DRAM_SIZE_MASK 0x70 /* PCI bridge config data */
251#define BRI_DRAM_SIZE_2MB 0x00
252#define BRI_DRAM_SIZE_4MB 0x01
253#define BRI_DRAM_SIZE_8MB 0x02
254#define BRI_DRAM_SIZE_16MB 0x03
255#define BRI_DRAM_SIZE_32MB 0x04
256#define BRI_DRAM_SIZE_64MB 0x05
257
258#define HW_DEVICE_EXTENSION XGI_HW_DEVICE_INFO
259#define PHW_DEVICE_EXTENSION PXGI_HW_DEVICE_INFO
260
261#define SR_BUFFER_SIZE 5
262#define CR_BUFFER_SIZE 5
263
264/* Useful macros */
265#define inXGIREG(base) inb(base)
266#define outXGIREG(base,val) outb(val,base)
267#define orXGIREG(base,val) do { \
268 unsigned char __Temp = inb(base); \
269 outXGIREG(base, __Temp | (val)); \
270 } while (0)
271#define andXGIREG(base,val) do { \
272 unsigned char __Temp = inb(base); \
273 outXGIREG(base, __Temp & (val)); \
274 } while (0)
275#define inXGIIDXREG(base,idx,var) do { \
276 outb(idx,base); var=inb((base)+1); \
277 } while (0)
278#define outXGIIDXREG(base,idx,val) do { \
279 outb(idx,base); outb((val),(base)+1); \
280 } while (0)
281#define orXGIIDXREG(base,idx,val) do { \
282 unsigned char __Temp; \
283 outb(idx,base); \
284 __Temp = inb((base)+1)|(val); \
285 outXGIIDXREG(base,idx,__Temp); \
286 } while (0)
287#define andXGIIDXREG(base,idx,and) do { \
288 unsigned char __Temp; \
289 outb(idx,base); \
290 __Temp = inb((base)+1)&(and); \
291 outXGIIDXREG(base,idx,__Temp); \
292 } while (0)
293#define setXGIIDXREG(base,idx,and,or) do { \
294 unsigned char __Temp; \
295 outb(idx,base); \
296 __Temp = (inb((base)+1)&(and))|(or); \
297 outXGIIDXREG(base,idx,__Temp); \
298 } while (0)
299
300/* ------------------- Global Variables ----------------------------- */
301
302/* Fbcon variables */
303#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
304static struct fb_info* fb_info;
305#else
306static struct fb_info XGI_fb_info;
307#endif
308
309
310static int video_type = FB_TYPE_PACKED_PIXELS;
311
312static struct fb_var_screeninfo default_var = {
313 .xres = 0,
314 .yres = 0,
315 .xres_virtual = 0,
316 .yres_virtual = 0,
317 .xoffset = 0,
318 .yoffset = 0,
319 .bits_per_pixel = 0,
320 .grayscale = 0,
321 .red = {0, 8, 0},
322 .green = {0, 8, 0},
323 .blue = {0, 8, 0},
324 .transp = {0, 0, 0},
325 .nonstd = 0,
326 .activate = FB_ACTIVATE_NOW,
327 .height = -1,
328 .width = -1,
329 .accel_flags = 0,
330 .pixclock = 0,
331 .left_margin = 0,
332 .right_margin = 0,
333 .upper_margin = 0,
334 .lower_margin = 0,
335 .hsync_len = 0,
336 .vsync_len = 0,
337 .sync = 0,
338 .vmode = FB_VMODE_NONINTERLACED,
339#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
340 .reserved = {0, 0, 0, 0, 0, 0}
341#endif
342};
343
344#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
345static struct fb_fix_screeninfo XGIfb_fix = {
346 .id = "XGI",
347 .type = FB_TYPE_PACKED_PIXELS,
348 .xpanstep = 1,
349 .ypanstep = 1,
350};
351static char myid[20];
352static u32 pseudo_palette[17];
353#endif
354
355#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
356static struct display XGI_disp;
357
358static struct display_switch XGIfb_sw;
359
360static struct {
361 u16 blue, green, red, pad;
362} XGI_palette[256];
363
364static union {
365#ifdef FBCON_HAS_CFB16
366 u16 cfb16[16];
367#endif
368#ifdef FBCON_HAS_CFB32
369 u32 cfb32[16];
370#endif
371} XGI_fbcon_cmap;
372
373static int XGIfb_inverse = 0;
374#endif
375
376/* display status */
377static int XGIfb_off = 0;
378static int XGIfb_crt1off = 0;
379static int XGIfb_forcecrt1 = -1;
380static int XGIvga_enabled = 0;
381static int XGIfb_userom = 0;
382//static int XGIfb_useoem = -1;
383#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
384static int currcon = 0;
385#endif
386
387/* global flags */
388static int XGIfb_registered;
389static int XGIfb_tvmode = 0;
390static int XGIfb_mem = 0;
391static int XGIfb_pdc = 0;
392static int enable_dstn = 0;
393static int XGIfb_ypan = -1;
394
395
396int XGIfb_accel = 0;
397
398
399static int XGIfb_hwcursor_size = 0;
400static int XGIfb_CRT2_write_enable = 0;
401
402int XGIfb_crt2type = -1; /* TW: CRT2 type (for overriding autodetection) */
403int XGIfb_tvplug = -1; /* PR: Tv plug type (for overriding autodetection) */
404
405int XGIfb_queuemode = -1; /* TW: Use MMIO queue mode by default (310/325 series only) */
406
407unsigned char XGIfb_detectedpdc = 0;
408
409unsigned char XGIfb_detectedlcda = 0xff;
410
411
412
413
414/* TW: For ioctl XGIFB_GET_INFO */
415/* XGIfb_info XGIfbinfo; */
416
417/* TW: Hardware extension; contains data on hardware */
418HW_DEVICE_EXTENSION XGIhw_ext;
419
420/* TW: XGI private structure */
421VB_DEVICE_INFO XGI_Pr;
422
423/* card parameters */
424static unsigned long XGIfb_mmio_size = 0;
425static u8 XGIfb_caps = 0;
426
427typedef enum _XGI_CMDTYPE {
428 MMIO_CMD = 0,
429 AGP_CMD_QUEUE,
430 VM_CMD_QUEUE,
431} XGI_CMDTYPE;
432
433#define MD_XGI300 1
434#define MD_XGI315 2
435
436/* mode table */
437/* NOT const - will be patched for 1280x960 mode number chaos reasons */
438struct _XGIbios_mode {
439 char name[15];
440 u8 mode_no;
441 u16 vesa_mode_no_1; /* "XGI defined" VESA mode number */
442 u16 vesa_mode_no_2; /* Real VESA mode numbers */
443 u16 xres;
444 u16 yres;
445 u16 bpp;
446 u16 rate_idx;
447 u16 cols;
448 u16 rows;
449 u8 chipset;
450} XGIbios_mode[] = {
451#define MODE_INDEX_NONE 0 /* TW: index for mode=none */
452 {"none", 0xFF, 0x0000, 0x0000, 0, 0, 0, 0, 0, 0, MD_XGI300|MD_XGI315}, /* TW: for mode "none" */
453 {"320x240x16", 0x56, 0x0000, 0x0000, 320, 240, 16, 1, 40, 15, MD_XGI315},
454 {"320x480x8", 0x5A, 0x0000, 0x0000, 320, 480, 8, 1, 40, 30, MD_XGI315}, /* TW: FSTN */
455 {"320x480x16", 0x5B, 0x0000, 0x0000, 320, 480, 16, 1, 40, 30, MD_XGI315}, /* TW: FSTN */
456 {"640x480x8", 0x2E, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, MD_XGI300|MD_XGI315},
457 {"640x480x16", 0x44, 0x0111, 0x0111, 640, 480, 16, 1, 80, 30, MD_XGI300|MD_XGI315},
458 {"640x480x24", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_XGI300|MD_XGI315}, /* TW: That's for people who mix up color- and fb depth */
459 {"640x480x32", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_XGI300|MD_XGI315},
460 {"720x480x8", 0x31, 0x0000, 0x0000, 720, 480, 8, 1, 90, 30, MD_XGI300|MD_XGI315},
461 {"720x480x16", 0x33, 0x0000, 0x0000, 720, 480, 16, 1, 90, 30, MD_XGI300|MD_XGI315},
462 {"720x480x24", 0x35, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_XGI300|MD_XGI315},
463 {"720x480x32", 0x35, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_XGI300|MD_XGI315},
464 {"720x576x8", 0x32, 0x0000, 0x0000, 720, 576, 8, 1, 90, 36, MD_XGI300|MD_XGI315},
465 {"720x576x16", 0x34, 0x0000, 0x0000, 720, 576, 16, 1, 90, 36, MD_XGI300|MD_XGI315},
466 {"720x576x24", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_XGI300|MD_XGI315},
467 {"720x576x32", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_XGI300|MD_XGI315},
468 {"800x480x8", 0x70, 0x0000, 0x0000, 800, 480, 8, 1, 100, 30, MD_XGI300|MD_XGI315},
469 {"800x480x16", 0x7a, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_XGI300|MD_XGI315},
470 {"800x480x24", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_XGI300|MD_XGI315},
471 {"800x480x32", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_XGI300|MD_XGI315},
472#define DEFAULT_MODE 21 /* TW: index for 800x600x8 */
473#define DEFAULT_LCDMODE 21 /* TW: index for 800x600x8 */
474#define DEFAULT_TVMODE 21 /* TW: index for 800x600x8 */
475 {"800x600x8", 0x30, 0x0103, 0x0103, 800, 600, 8, 1, 100, 37, MD_XGI300|MD_XGI315},
476 {"800x600x16", 0x47, 0x0114, 0x0114, 800, 600, 16, 1, 100, 37, MD_XGI300|MD_XGI315},
477 {"800x600x24", 0x63, 0x013b, 0x0115, 800, 600, 32, 1, 100, 37, MD_XGI300|MD_XGI315},
478 {"800x600x32", 0x63, 0x013b, 0x0115, 800, 600, 32, 1, 100, 37, MD_XGI300|MD_XGI315},
479 {"1024x576x8", 0x71, 0x0000, 0x0000, 1024, 576, 8, 1, 128, 36, MD_XGI300|MD_XGI315},
480 {"1024x576x16", 0x74, 0x0000, 0x0000, 1024, 576, 16, 1, 128, 36, MD_XGI300|MD_XGI315},
481 {"1024x576x24", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_XGI300|MD_XGI315},
482 {"1024x576x32", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_XGI300|MD_XGI315},
483 {"1024x600x8", 0x20, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, MD_XGI300 }, /* TW: 300 series only */
484 {"1024x600x16", 0x21, 0x0000, 0x0000, 1024, 600, 16, 1, 128, 37, MD_XGI300 },
485 {"1024x600x24", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_XGI300 },
486 {"1024x600x32", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_XGI300 },
487 {"1024x768x8", 0x38, 0x0105, 0x0105, 1024, 768, 8, 1, 128, 48, MD_XGI300|MD_XGI315},
488 {"1024x768x16", 0x4A, 0x0117, 0x0117, 1024, 768, 16, 1, 128, 48, MD_XGI300|MD_XGI315},
489 {"1024x768x24", 0x64, 0x013c, 0x0118, 1024, 768, 32, 1, 128, 48, MD_XGI300|MD_XGI315},
490 {"1024x768x32", 0x64, 0x013c, 0x0118, 1024, 768, 32, 1, 128, 48, MD_XGI300|MD_XGI315},
491 {"1152x768x8", 0x23, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, MD_XGI300 }, /* TW: 300 series only */
492 {"1152x768x16", 0x24, 0x0000, 0x0000, 1152, 768, 16, 1, 144, 48, MD_XGI300 },
493 {"1152x768x24", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_XGI300 },
494 {"1152x768x32", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_XGI300 },
495 {"1280x720x8", 0x79, 0x0000, 0x0000, 1280, 720, 8, 1, 160, 45, MD_XGI300|MD_XGI315},
496 {"1280x720x16", 0x75, 0x0000, 0x0000, 1280, 720, 16, 1, 160, 45, MD_XGI300|MD_XGI315},
497 {"1280x720x24", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_XGI300|MD_XGI315},
498 {"1280x720x32", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_XGI300|MD_XGI315},
499 {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, MD_XGI315}, /* TW: 310/325 series only */
500 {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, MD_XGI315},
501 {"1280x768x24", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_XGI315},
502 {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_XGI315},
503#define MODEINDEX_1280x960 48
504 {"1280x960x8", 0x7C, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_XGI300|MD_XGI315}, /* TW: Modenumbers being patched */
505 {"1280x960x16", 0x7D, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_XGI300|MD_XGI315},
506 {"1280x960x24", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_XGI300|MD_XGI315},
507 {"1280x960x32", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_XGI300|MD_XGI315},
508 {"1280x1024x8", 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 1, 160, 64, MD_XGI300|MD_XGI315},
509 {"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 1, 160, 64, MD_XGI300|MD_XGI315},
510 {"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64, MD_XGI300|MD_XGI315},
511 {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64, MD_XGI300|MD_XGI315},
512 {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_XGI315}, /* TW: 310/325 series only */
513 {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_XGI315},
514 {"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_XGI315},
515 {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_XGI315},
516 {"1600x1200x8", 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_XGI300|MD_XGI315},
517 {"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_XGI300|MD_XGI315},
518 {"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_XGI300|MD_XGI315},
519 {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_XGI300|MD_XGI315},
520 {"1920x1440x8", 0x68, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_XGI300|MD_XGI315},
521 {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_XGI300|MD_XGI315},
522 {"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_XGI300|MD_XGI315},
523 {"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_XGI300|MD_XGI315},
524 {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_XGI315}, /* TW: 310/325 series only */
525 {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_XGI315},
526 {"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_XGI315},
527 {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_XGI315},
528 {"\0", 0x00, 0, 0, 0, 0, 0, 0, 0}
529};
530
531/* mode-related variables */
532#ifdef MODULE
533#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
534static int xgifb_mode_idx = 1;
535#else
536static int XGIfb_mode_idx = MODE_INDEX_NONE; /* Don't use a mode by default if we are a module */
537#endif
538#else
539#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
540static int xgifb_mode_idx = -1; /* Use a default mode if we are inside the kernel */
541#else
542static int XGIfb_mode_idx = -1;
543#endif
544#endif
545u8 XGIfb_mode_no = 0;
546u8 XGIfb_rate_idx = 0;
547
548/* TW: CR36 evaluation */
549const USHORT XGI300paneltype[] =
550 { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
551 LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
552 LCD_1024x768, LCD_1024x768, LCD_1024x768,
553 LCD_1024x768, LCD_1024x768, LCD_1024x768, LCD_1024x768 };
554
555const USHORT XGI310paneltype[] =
556 { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
557 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
558 LCD_1152x768, LCD_1400x1050,LCD_1280x768, LCD_1600x1200,
559 LCD_1024x768, LCD_1024x768, LCD_1024x768 };
560
561static const struct _XGI_crt2type {
562 char name[10];
563 int type_no;
564 int tvplug_no;
565} XGI_crt2type[] = {
566 {"NONE", 0, -1},
567 {"LCD", DISPTYPE_LCD, -1},
568 {"TV", DISPTYPE_TV, -1},
569 {"VGA", DISPTYPE_CRT2, -1},
570 {"SVIDEO", DISPTYPE_TV, TVPLUG_SVIDEO},
571 {"COMPOSITE", DISPTYPE_TV, TVPLUG_COMPOSITE},
572 {"SCART", DISPTYPE_TV, TVPLUG_SCART},
573 {"none", 0, -1},
574 {"lcd", DISPTYPE_LCD, -1},
575 {"tv", DISPTYPE_TV, -1},
576 {"vga", DISPTYPE_CRT2, -1},
577 {"svideo", DISPTYPE_TV, TVPLUG_SVIDEO},
578 {"composite", DISPTYPE_TV, TVPLUG_COMPOSITE},
579 {"scart", DISPTYPE_TV, TVPLUG_SCART},
580 {"\0", -1, -1}
581};
582
583/* Queue mode selection for 310 series */
584static const struct _XGI_queuemode {
585 char name[6];
586 int type_no;
587} XGI_queuemode[] = {
588 {"AGP", AGP_CMD_QUEUE},
589 {"VRAM", VM_CMD_QUEUE},
590 {"MMIO", MMIO_CMD},
591 {"agp", AGP_CMD_QUEUE},
592 {"vram", VM_CMD_QUEUE},
593 {"mmio", MMIO_CMD},
594 {"\0", -1}
595};
596
597/* TV standard */
598static const struct _XGI_tvtype {
599 char name[6];
600 int type_no;
601} XGI_tvtype[] = {
602 {"PAL", 1},
603 {"NTSC", 2},
604 {"pal", 1},
605 {"ntsc", 2},
606 {"\0", -1}
607};
608
609static const struct _XGI_vrate {
610 u16 idx;
611 u16 xres;
612 u16 yres;
613 u16 refresh;
614} XGIfb_vrate[] = {
615 {1, 640, 480, 60}, {2, 640, 480, 72}, {3, 640, 480, 75}, {4, 640, 480, 85},
616 {5, 640, 480,100}, {6, 640, 480, 120}, {7, 640, 480, 160}, {8, 640, 480, 200},
617 {1, 720, 480, 60},
618 {1, 720, 576, 58},
619 {1, 800, 480, 60}, {2, 800, 480, 75}, {3, 800, 480, 85},
620 {1, 800, 600, 60}, {2, 800, 600, 72}, {3, 800, 600, 75},
621 {4, 800, 600, 85}, {5, 800, 600, 100}, {6, 800, 600, 120}, {7, 800, 600, 160},
622 {1, 1024, 768, 60}, {2, 1024, 768, 70}, {3, 1024, 768, 75},
623 {4, 1024, 768, 85}, {5, 1024, 768, 100}, {6, 1024, 768, 120},
624 {1, 1024, 576, 60}, {2, 1024, 576, 75}, {3, 1024, 576, 85},
625 {1, 1024, 600, 60},
626 {1, 1152, 768, 60},
627 {1, 1280, 720, 60}, {2, 1280, 720, 75}, {3, 1280, 720, 85},
628 {1, 1280, 768, 60},
629 {1, 1280, 1024, 60}, {2, 1280, 1024, 75}, {3, 1280, 1024, 85},
630 {1, 1280, 960, 70},
631 {1, 1400, 1050, 60},
632 {1, 1600, 1200, 60}, {2, 1600, 1200, 65}, {3, 1600, 1200, 70}, {4, 1600, 1200, 75},
633 {5, 1600, 1200, 85}, {6, 1600, 1200, 100}, {7, 1600, 1200, 120},
634 {1, 1920, 1440, 60}, {2, 1920, 1440, 65}, {3, 1920, 1440, 70}, {4, 1920, 1440, 75},
635 {5, 1920, 1440, 85}, {6, 1920, 1440, 100},
636 {1, 2048, 1536, 60}, {2, 2048, 1536, 65}, {3, 2048, 1536, 70}, {4, 2048, 1536, 75},
637 {5, 2048, 1536, 85},
638 {0, 0, 0, 0}
639};
640
641static const struct _chswtable {
642 int subsysVendor;
643 int subsysCard;
644 char *vendorName;
645 char *cardName;
646} mychswtable[] = {
647 { 0x1631, 0x1002, "Mitachi", "0x1002" },
648 { 0, 0, "" , "" }
649};
650
651#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
652/* Offscreen layout */
653typedef struct _XGI_GLYINFO {
654 unsigned char ch;
655 int fontwidth;
656 int fontheight;
657 u8 gmask[72];
658 int ngmask;
659} XGI_GLYINFO;
660#endif
661
662typedef struct _XGI_OH {
663 struct _XGI_OH *poh_next;
664 struct _XGI_OH *poh_prev;
665 unsigned long offset;
666 unsigned long size;
667} XGI_OH;
668
669typedef struct _XGI_OHALLOC {
670 struct _XGI_OHALLOC *poha_next;
671 XGI_OH aoh[1];
672} XGI_OHALLOC;
673
674typedef struct _XGI_HEAP {
675 XGI_OH oh_free;
676 XGI_OH oh_used;
677 XGI_OH *poh_freelist;
678 XGI_OHALLOC *poha_chain;
679 unsigned long max_freesize;
680} XGI_HEAP;
681
682static unsigned long XGIfb_hwcursor_vbase;
683
684static unsigned long XGIfb_heap_start;
685static unsigned long XGIfb_heap_end;
686static unsigned long XGIfb_heap_size;
687static XGI_HEAP XGIfb_heap;
688
689// Eden Chen
690static const struct _XGI_TV_filter {
691 u8 filter[9][4];
692} XGI_TV_filter[] = {
693 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_0 */
694 {0x00,0xE0,0x10,0x60},
695 {0x00,0xEE,0x10,0x44},
696 {0x00,0xF4,0x10,0x38},
697 {0xF8,0xF4,0x18,0x38},
698 {0xFC,0xFB,0x14,0x2A},
699 {0x00,0x00,0x10,0x20},
700 {0x00,0x04,0x10,0x18},
701 {0xFF,0xFF,0xFF,0xFF} }},
702 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_1 */
703 {0x00,0xE0,0x10,0x60},
704 {0x00,0xEE,0x10,0x44},
705 {0x00,0xF4,0x10,0x38},
706 {0xF8,0xF4,0x18,0x38},
707 {0xFC,0xFB,0x14,0x2A},
708 {0x00,0x00,0x10,0x20},
709 {0x00,0x04,0x10,0x18},
710 {0xFF,0xFF,0xFF,0xFF} }},
711 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_2 */
712 {0xF5,0xEE,0x1B,0x44},
713 {0xF8,0xF4,0x18,0x38},
714 {0xEB,0x04,0x25,0x18},
715 {0xF1,0x05,0x1F,0x16},
716 {0xF6,0x06,0x1A,0x14},
717 {0xFA,0x06,0x16,0x14},
718 {0x00,0x04,0x10,0x18},
719 {0xFF,0xFF,0xFF,0xFF} }},
720 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_3 */
721 {0xF1,0x04,0x1F,0x18},
722 {0xEE,0x0D,0x22,0x06},
723 {0xF7,0x06,0x19,0x14},
724 {0xF4,0x0B,0x1C,0x0A},
725 {0xFA,0x07,0x16,0x12},
726 {0xF9,0x0A,0x17,0x0C},
727 {0x00,0x07,0x10,0x12},
728 {0xFF,0xFF,0xFF,0xFF} }},
729 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_4 */
730 {0x00,0xE0,0x10,0x60},
731 {0x00,0xEE,0x10,0x44},
732 {0x00,0xF4,0x10,0x38},
733 {0xF8,0xF4,0x18,0x38},
734 {0xFC,0xFB,0x14,0x2A},
735 {0x00,0x00,0x10,0x20},
736 {0x00,0x04,0x10,0x18},
737 {0xFF,0xFF,0xFF,0xFF} }},
738 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_5 */
739 {0xF5,0xEE,0x1B,0x44},
740 {0xF8,0xF4,0x18,0x38},
741 {0xEB,0x04,0x25,0x18},
742 {0xF1,0x05,0x1F,0x16},
743 {0xF6,0x06,0x1A,0x14},
744 {0xFA,0x06,0x16,0x14},
745 {0x00,0x04,0x10,0x18},
746 {0xFF,0xFF,0xFF,0xFF} }},
747 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_6 */
748 {0xEB,0x04,0x25,0x18},
749 {0xE7,0x0E,0x29,0x04},
750 {0xEE,0x0C,0x22,0x08},
751 {0xF6,0x0B,0x1A,0x0A},
752 {0xF9,0x0A,0x17,0x0C},
753 {0xFC,0x0A,0x14,0x0C},
754 {0x00,0x08,0x10,0x10},
755 {0xFF,0xFF,0xFF,0xFF} }},
756 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_7 */
757 {0xEC,0x02,0x24,0x1C},
758 {0xF2,0x04,0x1E,0x18},
759 {0xEB,0x15,0x25,0xF6},
760 {0xF4,0x10,0x1C,0x00},
761 {0xF8,0x0F,0x18,0x02},
762 {0x00,0x04,0x10,0x18},
763 {0x01,0x06,0x0F,0x14},
764 {0xFF,0xFF,0xFF,0xFF} }},
765 { {{0x00,0x00,0x00,0x40}, /* PALFilter_0 */
766 {0x00,0xE0,0x10,0x60},
767 {0x00,0xEE,0x10,0x44},
768 {0x00,0xF4,0x10,0x38},
769 {0xF8,0xF4,0x18,0x38},
770 {0xFC,0xFB,0x14,0x2A},
771 {0x00,0x00,0x10,0x20},
772 {0x00,0x04,0x10,0x18},
773 {0xFF,0xFF,0xFF,0xFF} }},
774 { {{0x00,0x00,0x00,0x40}, /* PALFilter_1 */
775 {0x00,0xE0,0x10,0x60},
776 {0x00,0xEE,0x10,0x44},
777 {0x00,0xF4,0x10,0x38},
778 {0xF8,0xF4,0x18,0x38},
779 {0xFC,0xFB,0x14,0x2A},
780 {0x00,0x00,0x10,0x20},
781 {0x00,0x04,0x10,0x18},
782 {0xFF,0xFF,0xFF,0xFF} }},
783 { {{0x00,0x00,0x00,0x40}, /* PALFilter_2 */
784 {0xF5,0xEE,0x1B,0x44},
785 {0xF8,0xF4,0x18,0x38},
786 {0xF1,0xF7,0x01,0x32},
787 {0xF5,0xFB,0x1B,0x2A},
788 {0xF9,0xFF,0x17,0x22},
789 {0xFB,0x01,0x15,0x1E},
790 {0x00,0x04,0x10,0x18},
791 {0xFF,0xFF,0xFF,0xFF} }},
792 { {{0x00,0x00,0x00,0x40}, /* PALFilter_3 */
793 {0xF5,0xFB,0x1B,0x2A},
794 {0xEE,0xFE,0x22,0x24},
795 {0xF3,0x00,0x1D,0x20},
796 {0xF9,0x03,0x17,0x1A},
797 {0xFB,0x02,0x14,0x1E},
798 {0xFB,0x04,0x15,0x18},
799 {0x00,0x06,0x10,0x14},
800 {0xFF,0xFF,0xFF,0xFF} }},
801 { {{0x00,0x00,0x00,0x40}, /* PALFilter_4 */
802 {0x00,0xE0,0x10,0x60},
803 {0x00,0xEE,0x10,0x44},
804 {0x00,0xF4,0x10,0x38},
805 {0xF8,0xF4,0x18,0x38},
806 {0xFC,0xFB,0x14,0x2A},
807 {0x00,0x00,0x10,0x20},
808 {0x00,0x04,0x10,0x18},
809 {0xFF,0xFF,0xFF,0xFF} }},
810 { {{0x00,0x00,0x00,0x40}, /* PALFilter_5 */
811 {0xF5,0xEE,0x1B,0x44},
812 {0xF8,0xF4,0x18,0x38},
813 {0xF1,0xF7,0x1F,0x32},
814 {0xF5,0xFB,0x1B,0x2A},
815 {0xF9,0xFF,0x17,0x22},
816 {0xFB,0x01,0x15,0x1E},
817 {0x00,0x04,0x10,0x18},
818 {0xFF,0xFF,0xFF,0xFF} }},
819 { {{0x00,0x00,0x00,0x40}, /* PALFilter_6 */
820 {0xF5,0xEE,0x1B,0x2A},
821 {0xEE,0xFE,0x22,0x24},
822 {0xF3,0x00,0x1D,0x20},
823 {0xF9,0x03,0x17,0x1A},
824 {0xFB,0x02,0x14,0x1E},
825 {0xFB,0x04,0x15,0x18},
826 {0x00,0x06,0x10,0x14},
827 {0xFF,0xFF,0xFF,0xFF} }},
828 { {{0x00,0x00,0x00,0x40}, /* PALFilter_7 */
829 {0xF5,0xEE,0x1B,0x44},
830 {0xF8,0xF4,0x18,0x38},
831 {0xFC,0xFB,0x14,0x2A},
832 {0xEB,0x05,0x25,0x16},
833 {0xF1,0x05,0x1F,0x16},
834 {0xFA,0x07,0x16,0x12},
835 {0x00,0x07,0x10,0x12},
836 {0xFF,0xFF,0xFF,0xFF} }}
837};
838
839static int filter = -1;
840static unsigned char filter_tb;
841
842
843/* ---------------------- Routine prototypes ------------------------- */
844
845/* Interface used by the world */
846#ifndef MODULE
847XGIINITSTATIC int __init XGIfb_setup(char *options);
848#endif
849
850/* Interface to the low level console driver */
851
852
853
854/* fbdev routines */
855#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
856 int XGIfb_init(void);
857static int XGIfb_get_fix(struct fb_fix_screeninfo *fix,
858 int con,
859 struct fb_info *info);
860static int XGIfb_get_var(struct fb_var_screeninfo *var,
861 int con,
862 struct fb_info *info);
863static int XGIfb_set_var(struct fb_var_screeninfo *var,
864 int con,
865 struct fb_info *info);
866static void XGIfb_crtc_to_var(struct fb_var_screeninfo *var);
867static int XGIfb_get_cmap(struct fb_cmap *cmap,
868 int kspc,
869 int con,
870 struct fb_info *info);
871static int XGIfb_set_cmap(struct fb_cmap *cmap,
872 int kspc,
873 int con,
874 struct fb_info *info);
875static int XGIfb_update_var(int con,
876 struct fb_info *info);
877static int XGIfb_switch(int con,
878 struct fb_info *info);
879static void XGIfb_blank(int blank,
880 struct fb_info *info);
881static void XGIfb_set_disp(int con,
882 struct fb_var_screeninfo *var,
883 struct fb_info *info);
884static int XGI_getcolreg(unsigned regno, unsigned *red, unsigned *green,
885 unsigned *blue, unsigned *transp,
886 struct fb_info *fb_info);
887static void XGIfb_do_install_cmap(int con,
888 struct fb_info *info);
889static void XGI_get_glyph(struct fb_info *info,
890 XGI_GLYINFO *gly);
891static int XGIfb_mmap(struct fb_info *info, struct file *file,
892 struct vm_area_struct *vma);
893static int XGIfb_ioctl(struct inode *inode, struct file *file,
894 unsigned int cmd, unsigned long arg, int con,
895 struct fb_info *info);
896#endif
897
898#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
899XGIINITSTATIC int __init xgifb_init(void);
900static int XGIfb_set_par(struct fb_info *info);
901static int XGIfb_blank(int blank,
902 struct fb_info *info);
903/*static int XGIfb_mmap(struct fb_info *info, struct file *file,
904 struct vm_area_struct *vma);
905*/
906extern void fbcon_XGI_fillrect(struct fb_info *info,
907 const struct fb_fillrect *rect);
908extern void fbcon_XGI_copyarea(struct fb_info *info,
909 const struct fb_copyarea *area);
910#if 0
911extern void cfb_imageblit(struct fb_info *info,
912 const struct fb_image *image);
913#endif
914extern int fbcon_XGI_sync(struct fb_info *info);
915
916#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
917static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
918 unsigned long arg);
919#else
920static int XGIfb_ioctl(struct inode *inode,
921 struct file *file,
922 unsigned int cmd,
923 unsigned long arg,
924 struct fb_info *info);
925#endif
926
927/*
928extern int XGIfb_mode_rate_to_dclock(VB_DEVICE_INFO *XGI_Pr,
929 PXGI_HW_DEVICE_INFO HwDeviceExtension,
930 unsigned char modeno, unsigned char rateindex);
931extern int XGIfb_mode_rate_to_ddata(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwDeviceExtension,
932 unsigned char modeno, unsigned char rateindex,
933 unsigned int *left_margin, unsigned int *right_margin,
934 unsigned int *upper_margin, unsigned int *lower_margin,
935 unsigned int *hsync_len, unsigned int *vsync_len,
936 unsigned int *sync, unsigned int *vmode);
937*/
938#endif
939 extern BOOLEAN XGI_SearchModeID( USHORT ModeNo,USHORT *ModeIdIndex, PVB_DEVICE_INFO );
940static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
941 struct fb_info *info);
942
943/* Internal 2D accelerator functions */
944extern int XGIfb_initaccel(void);
945extern void XGIfb_syncaccel(void);
946
947/* Internal general routines */
948static void XGIfb_search_mode(const char *name);
949static int XGIfb_validate_mode(int modeindex);
950static u8 XGIfb_search_refresh_rate(unsigned int rate);
951static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
952 unsigned blue, unsigned transp,
953 struct fb_info *fb_info);
954static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
955 struct fb_info *info);
956static void XGIfb_pre_setmode(void);
957static void XGIfb_post_setmode(void);
958
959static BOOLEAN XGIfb_CheckVBRetrace(void);
960static BOOLEAN XGIfbcheckvretracecrt2(void);
961static BOOLEAN XGIfbcheckvretracecrt1(void);
962static BOOLEAN XGIfb_bridgeisslave(void);
963
964struct XGI_memreq {
965 unsigned long offset;
966 unsigned long size;
967};
968
969/* XGI-specific Export functions */
970void XGI_dispinfo(struct ap_data *rec);
971void XGI_malloc(struct XGI_memreq *req);
972void XGI_free(unsigned long base);
973
974/* Internal hardware access routines */
975void XGIfb_set_reg4(u16 port, unsigned long data);
976u32 XGIfb_get_reg3(u16 port);
977
978/* Chipset-dependent internal routines */
979
980
981static int XGIfb_get_dram_size(void);
982static void XGIfb_detect_VB(void);
983static void XGIfb_get_VB_type(void);
984static int XGIfb_has_VB(void);
985
986
987/* Internal heap routines */
988static int XGIfb_heap_init(void);
989static XGI_OH *XGIfb_poh_new_node(void);
990static XGI_OH *XGIfb_poh_allocate(unsigned long size);
991static void XGIfb_delete_node(XGI_OH *poh);
992static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh);
993static XGI_OH *XGIfb_poh_free(unsigned long base);
994static void XGIfb_free_node(XGI_OH *poh);
995
996/* Internal routines to access PCI configuration space */
997BOOLEAN XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
998 unsigned long offset, unsigned long set, unsigned long *value);
999//BOOLEAN XGIfb_query_north_bridge_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
1000// unsigned long offset, unsigned long set, unsigned long *value);
1001
1002
1003/* Routines from init.c/init301.c */
1004extern void InitTo330Pointer(UCHAR,PVB_DEVICE_INFO pVBInfo);
1005extern BOOLEAN XGIInitNew(PXGI_HW_DEVICE_INFO HwDeviceExtension);
1006extern BOOLEAN XGISetModeNew(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
1007//extern void XGI_SetEnableDstn(VB_DEVICE_INFO *XGI_Pr);
1008extern void XGI_LongWait(VB_DEVICE_INFO *XGI_Pr);
1009extern USHORT XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo );
1010/* TW: Chrontel TV functions */
1011extern USHORT XGI_GetCH700x(VB_DEVICE_INFO *XGI_Pr, USHORT tempbx);
1012extern void XGI_SetCH700x(VB_DEVICE_INFO *XGI_Pr, USHORT tempbx);
1013extern USHORT XGI_GetCH701x(VB_DEVICE_INFO *XGI_Pr, USHORT tempbx);
1014extern void XGI_SetCH701x(VB_DEVICE_INFO *XGI_Pr, USHORT tempbx);
1015extern void XGI_SetCH70xxANDOR(VB_DEVICE_INFO *XGI_Pr, USHORT tempax,USHORT tempbh);
1016extern void XGI_DDC2Delay(VB_DEVICE_INFO *XGI_Pr, USHORT delaytime);
1017
1018/* TW: Sensing routines */
1019void XGI_Sense30x(void);
1020int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch);
1021
1022extern XGI21_LVDSCapStruct XGI21_LCDCapList[13];
1023#endif
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
new file mode 100644
index 000000000000..867012b48a01
--- /dev/null
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -0,0 +1,3773 @@
1/*
2 * XG20, XG21, XG40, XG42 frame buffer device
3 * for Linux kernels 2.5.x, 2.6.x
4 * Base on TW's sis fbdev code.
5 */
6
7//#include <linux/config.h>
8#include <linux/version.h>
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/kernel.h>
12#include <linux/spinlock.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15#include <linux/mm.h>
16#include <linux/tty.h>
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include <linux/fb.h>
20#include <linux/console.h>
21#include <linux/selection.h>
22#include <linux/ioport.h>
23#include <linux/init.h>
24#include <linux/pci.h>
25#include <linux/vmalloc.h>
26#include <linux/vt_kern.h>
27#include <linux/capability.h>
28#include <linux/fs.h>
29#include <linux/types.h>
30#include <linux/proc_fs.h>
31#include <linux/kernel.h>
32
33#include "osdef.h"
34
35
36#ifndef XGIFB_PAN
37#define XGIFB_PAN
38#endif
39
40#include <asm/io.h>
41#ifdef CONFIG_MTRR
42#include <asm/mtrr.h>
43#endif
44
45#include "XGIfb.h"
46#include "vgatypes.h"
47#include "XGI_main.h"
48#include "vb_util.h"
49
50
51#define Index_CR_GPIO_Reg1 0x48
52#define Index_CR_GPIO_Reg2 0x49
53#define Index_CR_GPIO_Reg3 0x4a
54
55#define GPIOG_EN (1<<6)
56#define GPIOG_WRITE (1<<6)
57#define GPIOG_READ (1<<1)
58int XGIfb_GetXG21DefaultLVDSModeIdx(void);
59
60/* -------------------- Macro definitions ---------------------------- */
61
62#undef XGIFBDEBUG
63
64#ifdef XGIFBDEBUG
65#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
66#else
67#define DPRINTK(fmt, args...)
68#endif
69
70#ifdef XGIFBDEBUG
71static void dumpVGAReg(void)
72{
73 u8 i,reg;
74
75outXGIIDXREG(XGISR, 0x05, 0x86);
76/*
77outXGIIDXREG(XGISR, 0x08, 0x4f);
78outXGIIDXREG(XGISR, 0x0f, 0x20);
79outXGIIDXREG(XGISR, 0x11, 0x4f);
80outXGIIDXREG(XGISR, 0x13, 0x45);
81outXGIIDXREG(XGISR, 0x14, 0x51);
82outXGIIDXREG(XGISR, 0x1e, 0x41);
83outXGIIDXREG(XGISR, 0x1f, 0x0);
84outXGIIDXREG(XGISR, 0x20, 0xa1);
85outXGIIDXREG(XGISR, 0x22, 0xfb);
86outXGIIDXREG(XGISR, 0x26, 0x22);
87outXGIIDXREG(XGISR, 0x3e, 0x07);
88*/
89
90//outXGIIDXREG(XGICR, 0x19, 0x00);
91//outXGIIDXREG(XGICR, 0x1a, 0x3C);
92//outXGIIDXREG(XGICR, 0x22, 0xff);
93//outXGIIDXREG(XGICR, 0x3D, 0x10);
94
95//outXGIIDXREG(XGICR, 0x4a, 0xf3);
96
97//outXGIIDXREG(XGICR, 0x57, 0x0);
98//outXGIIDXREG(XGICR, 0x7a, 0x2c);
99
100//outXGIIDXREG(XGICR, 0x82, 0xcc);
101//outXGIIDXREG(XGICR, 0x8c, 0x0);
102/*
103outXGIIDXREG(XGICR, 0x99, 0x1);
104outXGIIDXREG(XGICR, 0x41, 0x40);
105*/
106
107 for(i=0; i < 0x4f; i++)
108 {
109 inXGIIDXREG(XGISR, i, reg);
110 printk("\no 3c4 %x",i);
111 printk("\ni 3c5 => %x",reg);
112 }
113
114 for(i=0; i < 0xF0; i++)
115 {
116 inXGIIDXREG(XGICR, i, reg);
117 printk("\no 3d4 %x",i);
118 printk("\ni 3d5 => %x",reg);
119 }
120/*
121
122 outXGIIDXREG(XGIPART1,0x2F,1);
123 for(i=1; i < 0x50; i++)
124 {
125 inXGIIDXREG(XGIPART1, i, reg);
126 printk("\no d004 %x",i);
127 printk("\ni d005 => %x",reg);
128 }
129
130 for(i=0; i < 0x50; i++)
131 {
132 inXGIIDXREG(XGIPART2, i, reg);
133 printk("\no d010 %x",i);
134 printk("\ni d011 => %x",reg);
135 }
136 for(i=0; i < 0x50; i++)
137 {
138 inXGIIDXREG(XGIPART3, i, reg);
139 printk("\no d012 %x",i);
140 printk("\ni d013 => %x",reg);
141 }
142 for(i=0; i < 0x50; i++)
143 {
144 inXGIIDXREG(XGIPART4, i, reg);
145 printk("\no d014 %x",i);
146 printk("\ni d015 => %x",reg);
147 }
148*/
149}
150#else
151static inline void dumpVGAReg(void) {}
152#endif
153
154/* data for XGI components */
155struct video_info xgi_video_info;
156
157
158#if 1
159#define DEBUGPRN(x)
160#else
161#define DEBUGPRN(x) printk(KERN_INFO x "\n");
162#endif
163
164
165/* --------------- Hardware Access Routines -------------------------- */
166
167#ifdef LINUX_KERNEL
168int
169XGIfb_mode_rate_to_dclock(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwDeviceExtension,
170 unsigned char modeno, unsigned char rateindex)
171{
172 USHORT ModeNo = modeno;
173 USHORT ModeIdIndex = 0, ClockIndex = 0;
174 USHORT RefreshRateTableIndex = 0;
175
176 /*ULONG temp = 0;*/
177 int Clock;
178 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
179 InitTo330Pointer( HwDeviceExtension->jChipType, XGI_Pr ) ;
180
181 RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, XGI_Pr ) ;
182
183/*
184 temp = XGI_SearchModeID( ModeNo , &ModeIdIndex, XGI_Pr ) ;
185 if(!temp) {
186 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
187 return 65000;
188 }
189
190 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
191 RefreshRateTableIndex += (rateindex - 1);
192
193*/
194 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
195 if(HwDeviceExtension->jChipType < XGI_315H) {
196 ClockIndex &= 0x3F;
197 }
198 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000 ;
199
200 return(Clock);
201}
202
203int
204XGIfb_mode_rate_to_ddata(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwDeviceExtension,
205 unsigned char modeno, unsigned char rateindex,
206 u32 *left_margin, u32 *right_margin,
207 u32 *upper_margin, u32 *lower_margin,
208 u32 *hsync_len, u32 *vsync_len,
209 u32 *sync, u32 *vmode)
210{
211 USHORT ModeNo = modeno;
212 USHORT ModeIdIndex = 0, index = 0;
213 USHORT RefreshRateTableIndex = 0;
214
215 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
216 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
217 unsigned char sr_data, cr_data, cr_data2;
218 unsigned long cr_data3;
219 int A, B, C, D, E, F, temp, j;
220 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
221 InitTo330Pointer( HwDeviceExtension->jChipType, XGI_Pr ) ;
222 RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, XGI_Pr ) ;
223/*
224 temp = XGI_SearchModeID( ModeNo, &ModeIdIndex, XGI_Pr);
225 if(!temp) return 0;
226
227 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
228 RefreshRateTableIndex += (rateindex - 1);
229*/
230 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
231
232 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
233
234 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
235
236 /* Horizontal total */
237 HT = (cr_data & 0xff) |
238 ((unsigned short) (sr_data & 0x03) << 8);
239 A = HT + 5;
240
241 /*cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
242
243 Horizontal display enable end
244 HDE = (cr_data & 0xff) |
245 ((unsigned short) (sr_data & 0x0C) << 6);*/
246 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) -1;
247 E = HDE + 1;
248
249 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
250
251 /* Horizontal retrace (=sync) start */
252 HRS = (cr_data & 0xff) |
253 ((unsigned short) (sr_data & 0xC0) << 2);
254 F = HRS - E - 3;
255
256 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
257
258 /* Horizontal blank start */
259 HBS = (cr_data & 0xff) |
260 ((unsigned short) (sr_data & 0x30) << 4);
261
262 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
263
264 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
265
266 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
267
268 /* Horizontal blank end */
269 HBE = (cr_data & 0x1f) |
270 ((unsigned short) (cr_data2 & 0x80) >> 2) |
271 ((unsigned short) (sr_data & 0x03) << 6);
272
273 /* Horizontal retrace (=sync) end */
274 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
275
276 temp = HBE - ((E - 1) & 255);
277 B = (temp > 0) ? temp : (temp + 256);
278
279 temp = HRE - ((E + F + 3) & 63);
280 C = (temp > 0) ? temp : (temp + 64);
281
282 D = B - F - C;
283
284 *left_margin = D * 8;
285 *right_margin = F * 8;
286 *hsync_len = C * 8;
287
288 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
289
290 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
291
292 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
293
294 /* Vertical total */
295 VT = (cr_data & 0xFF) |
296 ((unsigned short) (cr_data2 & 0x01) << 8) |
297 ((unsigned short)(cr_data2 & 0x20) << 4) |
298 ((unsigned short) (sr_data & 0x01) << 10);
299 A = VT + 2;
300
301 //cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
302
303 /* Vertical display enable end */
304/* VDE = (cr_data & 0xff) |
305 ((unsigned short) (cr_data2 & 0x02) << 7) |
306 ((unsigned short) (cr_data2 & 0x40) << 3) |
307 ((unsigned short) (sr_data & 0x02) << 9); */
308 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes -1;
309 E = VDE + 1;
310
311 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
312
313 /* Vertical retrace (=sync) start */
314 VRS = (cr_data & 0xff) |
315 ((unsigned short) (cr_data2 & 0x04) << 6) |
316 ((unsigned short) (cr_data2 & 0x80) << 2) |
317 ((unsigned short) (sr_data & 0x08) << 7);
318 F = VRS + 1 - E;
319
320 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
321
322 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
323
324 /* Vertical blank start */
325 VBS = (cr_data & 0xff) |
326 ((unsigned short) (cr_data2 & 0x08) << 5) |
327 ((unsigned short) (cr_data3 & 0x20) << 4) |
328 ((unsigned short) (sr_data & 0x04) << 8);
329
330 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
331
332 /* Vertical blank end */
333 VBE = (cr_data & 0xff) |
334 ((unsigned short) (sr_data & 0x10) << 4);
335 temp = VBE - ((E - 1) & 511);
336 B = (temp > 0) ? temp : (temp + 512);
337
338 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
339
340 /* Vertical retrace (=sync) end */
341 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
342 temp = VRE - ((E + F - 1) & 31);
343 C = (temp > 0) ? temp : (temp + 32);
344
345 D = B - F - C;
346
347 *upper_margin = D;
348 *lower_margin = F;
349 *vsync_len = C;
350
351 if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
352 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
353 else
354 *sync |= FB_SYNC_VERT_HIGH_ACT;
355
356 if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
357 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
358 else
359 *sync |= FB_SYNC_HOR_HIGH_ACT;
360
361 *vmode = FB_VMODE_NONINTERLACED;
362 if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
363 *vmode = FB_VMODE_INTERLACED;
364 else {
365 j = 0;
366 while(XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
367 if(XGI_Pr->EModeIDTable[j].Ext_ModeID ==
368 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
369 if(XGI_Pr->EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
370 *vmode = FB_VMODE_DOUBLE;
371 }
372 break;
373 }
374 j++;
375 }
376 }
377
378#if 0 /* That's bullshit, only the resolution needs to be shifted */
379 if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
380 *upper_margin <<= 1;
381 *lower_margin <<= 1;
382 *vsync_len <<= 1;
383 } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
384 *upper_margin >>= 1;
385 *lower_margin >>= 1;
386 *vsync_len >>= 1;
387 }
388#endif
389
390 return 1;
391}
392
393#endif
394
395
396
397void XGIRegInit(VB_DEVICE_INFO *XGI_Pr, ULONG BaseAddr)
398{
399 XGI_Pr->RelIO = BaseAddr;
400 XGI_Pr->P3c4 = BaseAddr + 0x14;
401 XGI_Pr->P3d4 = BaseAddr + 0x24;
402 XGI_Pr->P3c0 = BaseAddr + 0x10;
403 XGI_Pr->P3ce = BaseAddr + 0x1e;
404 XGI_Pr->P3c2 = BaseAddr + 0x12;
405 XGI_Pr->P3ca = BaseAddr + 0x1a;
406 XGI_Pr->P3c6 = BaseAddr + 0x16;
407 XGI_Pr->P3c7 = BaseAddr + 0x17;
408 XGI_Pr->P3c8 = BaseAddr + 0x18;
409 XGI_Pr->P3c9 = BaseAddr + 0x19;
410 XGI_Pr->P3da = BaseAddr + 0x2A;
411 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
412 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
413 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
414 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
415 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14+2; /* 301 palette address port registers */
416
417}
418
419
420void XGIfb_set_reg4(u16 port, unsigned long data)
421{
422 outl((u32) (data & 0xffffffff), port);
423}
424
425u32 XGIfb_get_reg3(u16 port)
426{
427 u32 data;
428
429 data = inl(port);
430 return (data);
431}
432
433/* ------------ Interface for init & mode switching code ------------- */
434
435BOOLEAN
436XGIfb_query_VGA_config_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
437 unsigned long offset, unsigned long set, unsigned long *value)
438{
439 static struct pci_dev *pdev = NULL;
440 static unsigned char init = 0, valid_pdev = 0;
441
442 if (!set)
443 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
444 else
445 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
446
447 if (!init) {
448 init = TRUE;
449 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id, pdev);
450 if (pdev) {
451 valid_pdev = TRUE;
452 pci_dev_put(pdev);
453 }
454 }
455
456 if (!valid_pdev) {
457 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
458 xgi_video_info.chip_id);
459 return FALSE;
460 }
461
462 if (set == 0)
463 pci_read_config_dword(pdev, offset, (u32 *)value);
464 else
465 pci_write_config_dword(pdev, offset, (u32)(*value));
466
467 return TRUE;
468}
469
470/*BOOLEAN XGIfb_query_north_bridge_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
471 unsigned long offset, unsigned long set, unsigned long *value)
472{
473 static struct pci_dev *pdev = NULL;
474 static unsigned char init = 0, valid_pdev = 0;
475 u16 nbridge_id = 0;
476
477 if (!init) {
478 init = TRUE;
479 switch (xgi_video_info.chip) {
480 case XGI_540:
481 nbridge_id = PCI_DEVICE_ID_XG_540;
482 break;
483 case XGI_630:
484 nbridge_id = PCI_DEVICE_ID_XG_630;
485 break;
486 case XGI_730:
487 nbridge_id = PCI_DEVICE_ID_XG_730;
488 break;
489 case XGI_550:
490 nbridge_id = PCI_DEVICE_ID_XG_550;
491 break;
492 case XGI_650:
493 nbridge_id = PCI_DEVICE_ID_XG_650;
494 break;
495 case XGI_740:
496 nbridge_id = PCI_DEVICE_ID_XG_740;
497 break;
498 default:
499 nbridge_id = 0;
500 break;
501 }
502
503 pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
504 if (pdev)
505 valid_pdev = TRUE;
506 }
507
508 if (!valid_pdev) {
509 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
510 nbridge_id);
511 return FALSE;
512 }
513
514 if (set == 0)
515 pci_read_config_dword(pdev, offset, (u32 *)value);
516 else
517 pci_write_config_dword(pdev, offset, (u32)(*value));
518
519 return TRUE;
520}
521*/
522/* ------------------ Internal helper routines ----------------- */
523
524static void XGIfb_search_mode(const char *name)
525{
526 int i = 0, j = 0, l;
527
528 if(name == NULL) {
529 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
530 xgifb_mode_idx = DEFAULT_MODE;
531 if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
532 {
533 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
534 }
535 return;
536 }
537
538
539 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
540 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
541 xgifb_mode_idx = DEFAULT_MODE;
542 if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
543 {
544 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
545 }
546 return;
547 }
548
549 while(XGIbios_mode[i].mode_no != 0) {
550 l = min(strlen(name), strlen(XGIbios_mode[i].name));
551 if (!strncmp(name, XGIbios_mode[i].name, l)) {
552 xgifb_mode_idx = i;
553 j = 1;
554 break;
555 }
556 i++;
557 }
558 if(!j) printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
559}
560
561static void XGIfb_search_vesamode(unsigned int vesamode)
562{
563 int i = 0, j = 0;
564
565 if(vesamode == 0) {
566
567 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
568 xgifb_mode_idx = DEFAULT_MODE;
569 if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
570 {
571 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
572 }
573 return;
574 }
575
576 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
577
578 while(XGIbios_mode[i].mode_no != 0) {
579 if( (XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
580 (XGIbios_mode[i].vesa_mode_no_2 == vesamode) ) {
581 xgifb_mode_idx = i;
582 j = 1;
583 break;
584 }
585 i++;
586 }
587 if(!j) printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
588}
589
590int XGIfb_GetXG21LVDSData(void)
591{
592 u8 tmp;
593 unsigned char *pData;
594 int i,j,k;
595
596 inXGIIDXREG(XGISR,0x1e,tmp);
597 outXGIIDXREG(XGISR, 0x1e, tmp|4);
598
599 pData = xgi_video_info.mmio_vbase+0x20000;
600 if ((pData[0x0]==0x55) && (pData[0x1]==0xAA) && (pData[0x65] & 0x1))
601 {
602 i = pData[ 0x316 ] | ( pData[ 0x317 ] << 8 );
603 j = pData[ i-1 ] ;
604 if ( j == 0xff )
605 {
606 j = 1;
607 }
608 k = 0;
609 do
610 {
611 XGI21_LCDCapList[k].LVDS_Capability = pData[ i ] | ( pData[ i + 1 ] << 8 );
612 XGI21_LCDCapList[k].LVDSHT = pData[ i + 2 ] | ( pData[ i + 3 ] << 8 ) ;
613 XGI21_LCDCapList[k].LVDSVT = pData[ i + 4 ] | ( pData[ i + 5 ] << 8 );
614 XGI21_LCDCapList[k].LVDSHDE = pData[ i + 6 ] | ( pData[ i + 7 ] << 8 );
615 XGI21_LCDCapList[k].LVDSVDE = pData[ i + 8 ] | ( pData[ i + 9 ] << 8 );
616 XGI21_LCDCapList[k].LVDSHFP = pData[ i + 10 ] | ( pData[ i + 11 ] << 8 );
617 XGI21_LCDCapList[k].LVDSVFP = pData[ i + 12 ] | ( pData[ i + 13 ] << 8 );
618 XGI21_LCDCapList[k].LVDSHSYNC = pData[ i + 14 ] | ( pData[ i + 15 ] << 8 );
619 XGI21_LCDCapList[k].LVDSVSYNC = pData[ i + 16 ] | ( pData[ i + 17 ] << 8 );
620 XGI21_LCDCapList[k].VCLKData1 = pData[ i + 18 ] ;
621 XGI21_LCDCapList[k].VCLKData2 = pData[ i + 19 ] ;
622 XGI21_LCDCapList[k].PSC_S1 = pData[ i + 20 ] ;
623 XGI21_LCDCapList[k].PSC_S2 = pData[ i + 21 ] ;
624 XGI21_LCDCapList[k].PSC_S3 = pData[ i + 22 ] ;
625 XGI21_LCDCapList[k].PSC_S4 = pData[ i + 23 ] ;
626 XGI21_LCDCapList[k].PSC_S5 = pData[ i + 24 ] ;
627 i += 25;
628 j--;
629 k++;
630 } while ( (j>0) && ( k < (sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct)) ) );
631 return 1;
632 }
633 return 0;
634}
635
636int XGIfb_GetXG21DefaultLVDSModeIdx(void)
637{
638
639 int found_mode = 0;
640 int XGIfb_mode_idx = 0;
641
642 found_mode = 0;
643 while( (XGIbios_mode[XGIfb_mode_idx].mode_no != 0) &&
644 (XGIbios_mode[XGIfb_mode_idx].xres <= XGI21_LCDCapList[0].LVDSHDE) )
645 {
646 if( (XGIbios_mode[XGIfb_mode_idx].xres == XGI21_LCDCapList[0].LVDSHDE) &&
647 (XGIbios_mode[XGIfb_mode_idx].yres == XGI21_LCDCapList[0].LVDSVDE) &&
648 (XGIbios_mode[XGIfb_mode_idx].bpp == 8))
649 {
650 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
651 found_mode = 1;
652 break;
653 }
654 XGIfb_mode_idx++;
655 }
656 if (!found_mode)
657 XGIfb_mode_idx = 0;
658
659 return (XGIfb_mode_idx);
660}
661
662
663static int XGIfb_validate_mode(int myindex)
664{
665 u16 xres, yres;
666
667 if (xgi_video_info.chip == XG21)
668 {
669 if ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD)
670 {
671 xres = XGI21_LCDCapList[0].LVDSHDE;
672 yres = XGI21_LCDCapList[0].LVDSVDE;
673 if(XGIbios_mode[myindex].xres > xres)
674 return(-1);
675 if(XGIbios_mode[myindex].yres > yres)
676 return(-1);
677 if ((XGIbios_mode[myindex].xres < xres) && (XGIbios_mode[myindex].yres < yres) )
678 {
679 if (XGIbios_mode[myindex].bpp > 8)
680 return(-1);
681 }
682
683 }
684 return(myindex);
685
686 }
687
688 /* FIXME: for now, all is valid on XG27 */
689 if (xgi_video_info.chip == XG27)
690 return(myindex);
691
692 if(!(XGIbios_mode[myindex].chipset & MD_XGI315))
693 return(-1);
694
695 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
696 case DISPTYPE_LCD:
697 switch (XGIhw_ext.ulCRT2LCDType) {
698 case LCD_640x480:
699 xres = 640; yres = 480; break;
700 case LCD_800x600:
701 xres = 800; yres = 600; break;
702 case LCD_1024x600:
703 xres = 1024; yres = 600; break;
704 case LCD_1024x768:
705 xres = 1024; yres = 768; break;
706 case LCD_1152x768:
707 xres = 1152; yres = 768; break;
708 case LCD_1280x960:
709 xres = 1280; yres = 960; break;
710 case LCD_1280x768:
711 xres = 1280; yres = 768; break;
712 case LCD_1280x1024:
713 xres = 1280; yres = 1024; break;
714 case LCD_1400x1050:
715 xres = 1400; yres = 1050; break;
716 case LCD_1600x1200:
717 xres = 1600; yres = 1200; break;
718// case LCD_320x480: // TW: FSTN
719// xres = 320; yres = 480; break;
720 default:
721 xres = 0; yres = 0; break;
722 }
723 if(XGIbios_mode[myindex].xres > xres) {
724 return(-1);
725 }
726 if(XGIbios_mode[myindex].yres > yres) {
727 return(-1);
728 }
729 if((XGIhw_ext.ulExternalChip == 0x01) || // LVDS
730 (XGIhw_ext.ulExternalChip == 0x05)) // LVDS+Chrontel
731 {
732 switch (XGIbios_mode[myindex].xres) {
733 case 512:
734 if(XGIbios_mode[myindex].yres != 512) return -1;
735 if(XGIhw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
736 break;
737 case 640:
738 if((XGIbios_mode[myindex].yres != 400) &&
739 (XGIbios_mode[myindex].yres != 480))
740 return -1;
741 break;
742 case 800:
743 if(XGIbios_mode[myindex].yres != 600) return -1;
744 break;
745 case 1024:
746 if((XGIbios_mode[myindex].yres != 600) &&
747 (XGIbios_mode[myindex].yres != 768))
748 return -1;
749 if((XGIbios_mode[myindex].yres == 600) &&
750 (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
751 return -1;
752 break;
753 case 1152:
754 if((XGIbios_mode[myindex].yres) != 768) return -1;
755 if(XGIhw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
756 break;
757 case 1280:
758 if((XGIbios_mode[myindex].yres != 768) &&
759 (XGIbios_mode[myindex].yres != 1024))
760 return -1;
761 if((XGIbios_mode[myindex].yres == 768) &&
762 (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
763 return -1;
764 break;
765 case 1400:
766 if(XGIbios_mode[myindex].yres != 1050) return -1;
767 break;
768 case 1600:
769 if(XGIbios_mode[myindex].yres != 1200) return -1;
770 break;
771 default:
772 return -1;
773 }
774 } else {
775 switch (XGIbios_mode[myindex].xres) {
776 case 512:
777 if(XGIbios_mode[myindex].yres != 512) return -1;
778 break;
779 case 640:
780 if((XGIbios_mode[myindex].yres != 400) &&
781 (XGIbios_mode[myindex].yres != 480))
782 return -1;
783 break;
784 case 800:
785 if(XGIbios_mode[myindex].yres != 600) return -1;
786 break;
787 case 1024:
788 if(XGIbios_mode[myindex].yres != 768) return -1;
789 break;
790 case 1280:
791 if((XGIbios_mode[myindex].yres != 960) &&
792 (XGIbios_mode[myindex].yres != 1024))
793 return -1;
794 if(XGIbios_mode[myindex].yres == 960) {
795 if(XGIhw_ext.ulCRT2LCDType == LCD_1400x1050)
796 return -1;
797 }
798 break;
799 case 1400:
800 if(XGIbios_mode[myindex].yres != 1050) return -1;
801 break;
802 case 1600:
803 if(XGIbios_mode[myindex].yres != 1200) return -1;
804 break;
805 default:
806 return -1;
807 }
808 }
809 break;
810 case DISPTYPE_TV:
811 switch (XGIbios_mode[myindex].xres) {
812 case 512:
813 case 640:
814 case 800:
815 break;
816 case 720:
817 if (xgi_video_info.TV_type == TVMODE_NTSC) {
818 if (XGIbios_mode[myindex].yres != 480) {
819 return(-1);
820 }
821 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
822 if (XGIbios_mode[myindex].yres != 576) {
823 return(-1);
824 }
825 }
826 // TW: LVDS/CHRONTEL does not support 720
827 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
828 xgi_video_info.hasVB == HASVB_CHRONTEL) {
829 return(-1);
830 }
831 break;
832 case 1024:
833 if (xgi_video_info.TV_type == TVMODE_NTSC) {
834 if(XGIbios_mode[myindex].bpp == 32) {
835 return(-1);
836 }
837 }
838 // TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)
839 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
840 xgi_video_info.hasVB == HASVB_CHRONTEL) {
841 if(xgi_video_info.chip < XGI_315H) {
842 return(-1);
843 }
844 }
845 break;
846 default:
847 return(-1);
848 }
849 break;
850 case DISPTYPE_CRT2:
851 if(XGIbios_mode[myindex].xres > 1280) return -1;
852 break;
853 }
854 return(myindex);
855
856}
857
858static void XGIfb_search_crt2type(const char *name)
859{
860 int i = 0;
861
862 if(name == NULL)
863 return;
864
865 while(XGI_crt2type[i].type_no != -1) {
866 if (!strcmp(name, XGI_crt2type[i].name)) {
867 XGIfb_crt2type = XGI_crt2type[i].type_no;
868 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
869 break;
870 }
871 i++;
872 }
873 if(XGIfb_crt2type < 0)
874 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
875}
876
877static void XGIfb_search_queuemode(const char *name)
878{
879 int i = 0;
880
881 if(name == NULL)
882 return;
883
884 while (XGI_queuemode[i].type_no != -1) {
885 if (!strcmp(name, XGI_queuemode[i].name)) {
886 XGIfb_queuemode = XGI_queuemode[i].type_no;
887 break;
888 }
889 i++;
890 }
891 if (XGIfb_queuemode < 0)
892 printk(KERN_INFO "XGIfb: Invalid queuemode type: %s\n", name);
893}
894
895static u8 XGIfb_search_refresh_rate(unsigned int rate)
896{
897 u16 xres, yres;
898 int i = 0;
899
900 xres = XGIbios_mode[xgifb_mode_idx].xres;
901 yres = XGIbios_mode[xgifb_mode_idx].yres;
902
903 XGIfb_rate_idx = 0;
904 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
905 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres == yres)) {
906 if (XGIfb_vrate[i].refresh == rate) {
907 XGIfb_rate_idx = XGIfb_vrate[i].idx;
908 break;
909 } else if (XGIfb_vrate[i].refresh > rate) {
910 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
911 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
912 rate, XGIfb_vrate[i].refresh);
913 XGIfb_rate_idx = XGIfb_vrate[i].idx;
914 xgi_video_info.refresh_rate = XGIfb_vrate[i].refresh;
915 } else if (((rate - XGIfb_vrate[i-1].refresh) <= 2)
916 && (XGIfb_vrate[i].idx != 1)) {
917 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
918 rate, XGIfb_vrate[i-1].refresh);
919 XGIfb_rate_idx = XGIfb_vrate[i-1].idx;
920 xgi_video_info.refresh_rate = XGIfb_vrate[i-1].refresh;
921 }
922 break;
923 } else if((rate - XGIfb_vrate[i].refresh) <= 2) {
924 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
925 rate, XGIfb_vrate[i].refresh);
926 XGIfb_rate_idx = XGIfb_vrate[i].idx;
927 break;
928 }
929 }
930 i++;
931 }
932 if (XGIfb_rate_idx > 0) {
933 return XGIfb_rate_idx;
934 } else {
935 printk(KERN_INFO
936 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
937 return 0;
938 }
939}
940
941static void XGIfb_search_tvstd(const char *name)
942{
943 int i = 0;
944
945 if(name == NULL)
946 return;
947
948 while (XGI_tvtype[i].type_no != -1) {
949 if (!strcmp(name, XGI_tvtype[i].name)) {
950 XGIfb_tvmode = XGI_tvtype[i].type_no;
951 break;
952 }
953 i++;
954 }
955}
956
957static BOOLEAN XGIfb_bridgeisslave(void)
958{
959 unsigned char usScratchP1_00;
960
961 if(xgi_video_info.hasVB == HASVB_NONE) return FALSE;
962
963 inXGIIDXREG(XGIPART1,0x00,usScratchP1_00);
964 if( (usScratchP1_00 & 0x50) == 0x10) {
965 return TRUE;
966 } else {
967 return FALSE;
968 }
969}
970
971static BOOLEAN XGIfbcheckvretracecrt1(void)
972{
973 unsigned char temp;
974
975 inXGIIDXREG(XGICR,0x17,temp);
976 if(!(temp & 0x80)) return FALSE;
977
978
979 inXGIIDXREG(XGISR,0x1f,temp);
980 if(temp & 0xc0) return FALSE;
981
982
983 if(inXGIREG(XGIINPSTAT) & 0x08) return TRUE;
984 else return FALSE;
985}
986
987static BOOLEAN XGIfbcheckvretracecrt2(void)
988{
989 unsigned char temp;
990 if(xgi_video_info.hasVB == HASVB_NONE) return FALSE;
991 inXGIIDXREG(XGIPART1, 0x30, temp);
992 if(temp & 0x02) return FALSE;
993 else return TRUE;
994}
995
996static BOOLEAN XGIfb_CheckVBRetrace(void)
997{
998 if(xgi_video_info.disp_state & DISPTYPE_DISP2) {
999 if(XGIfb_bridgeisslave()) {
1000 return(XGIfbcheckvretracecrt1());
1001 } else {
1002 return(XGIfbcheckvretracecrt2());
1003 }
1004 }
1005 return(XGIfbcheckvretracecrt1());
1006}
1007
1008/* ----------- FBDev related routines for all series ----------- */
1009
1010
1011static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
1012{
1013 switch(var->bits_per_pixel) {
1014 case 8:
1015 var->red.offset = var->green.offset = var->blue.offset = 0;
1016 var->red.length = var->green.length = var->blue.length = 6;
1017 xgi_video_info.video_cmap_len = 256;
1018 break;
1019 case 16:
1020 var->red.offset = 11;
1021 var->red.length = 5;
1022 var->green.offset = 5;
1023 var->green.length = 6;
1024 var->blue.offset = 0;
1025 var->blue.length = 5;
1026 var->transp.offset = 0;
1027 var->transp.length = 0;
1028 xgi_video_info.video_cmap_len = 16;
1029 break;
1030 case 32:
1031 var->red.offset = 16;
1032 var->red.length = 8;
1033 var->green.offset = 8;
1034 var->green.length = 8;
1035 var->blue.offset = 0;
1036 var->blue.length = 8;
1037 var->transp.offset = 24;
1038 var->transp.length = 8;
1039 xgi_video_info.video_cmap_len = 16;
1040 break;
1041 }
1042}
1043
1044
1045
1046static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1047 struct fb_info *info)
1048{
1049
1050 unsigned int htotal = var->left_margin + var->xres +
1051 var->right_margin + var->hsync_len;
1052 unsigned int vtotal = var->upper_margin + var->yres +
1053 var->lower_margin + var->vsync_len;
1054#if defined(__powerpc__)
1055 u8 sr_data, cr_data;
1056#endif
1057 unsigned int drate = 0, hrate = 0;
1058 int found_mode = 0;
1059 int old_mode;
1060// unsigned char reg,reg1;
1061
1062 DEBUGPRN("Inside do_set_var");
1063// printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres,var->upper_margin,var->lower_margin,var->vsync_len);
1064
1065 info->var.xres_virtual = var->xres_virtual;
1066 info->var.yres_virtual = var->yres_virtual;
1067 info->var.bits_per_pixel = var->bits_per_pixel;
1068
1069 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1070 vtotal <<= 1;
1071 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1072 vtotal <<= 2;
1073 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
1074 {
1075// vtotal <<= 1;
1076// var->yres <<= 1;
1077 }
1078
1079 if(!htotal || !vtotal) {
1080 DPRINTK("XGIfb: Invalid 'var' information\n");
1081 return -EINVAL;
1082 }
1083 printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1084 var->pixclock,htotal,vtotal);
1085
1086
1087
1088 if(var->pixclock && htotal && vtotal) {
1089 drate = 1000000000 / var->pixclock;
1090 hrate = (drate * 1000) / htotal;
1091 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1092 } else {
1093 xgi_video_info.refresh_rate = 60;
1094 }
1095
1096 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1097 var->xres,var->yres,var->bits_per_pixel,xgi_video_info.refresh_rate);
1098
1099 old_mode = xgifb_mode_idx;
1100 xgifb_mode_idx = 0;
1101
1102 while( (XGIbios_mode[xgifb_mode_idx].mode_no != 0) &&
1103 (XGIbios_mode[xgifb_mode_idx].xres <= var->xres) ) {
1104 if( (XGIbios_mode[xgifb_mode_idx].xres == var->xres) &&
1105 (XGIbios_mode[xgifb_mode_idx].yres == var->yres) &&
1106 (XGIbios_mode[xgifb_mode_idx].bpp == var->bits_per_pixel)) {
1107 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1108 found_mode = 1;
1109 break;
1110 }
1111 xgifb_mode_idx++;
1112 }
1113
1114 if(found_mode)
1115 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1116 else
1117 xgifb_mode_idx = -1;
1118
1119 if(xgifb_mode_idx < 0) {
1120 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
1121 var->yres, var->bits_per_pixel);
1122 xgifb_mode_idx = old_mode;
1123 return -EINVAL;
1124 }
1125
1126 if(XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1127 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1128 xgi_video_info.refresh_rate = 60;
1129 }
1130
1131 if(isactive) {
1132
1133
1134 XGIfb_pre_setmode();
1135 if(XGISetModeNew( &XGIhw_ext, XGIfb_mode_no) == 0) {
1136 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1137 return -EINVAL;
1138 }
1139 info->fix.line_length = ((info->var.xres_virtual * info->var.bits_per_pixel)>>6);
1140
1141 outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
1142
1143 outXGIIDXREG(XGICR,0x13,(info->fix.line_length & 0x00ff));
1144 outXGIIDXREG(XGISR,0x0E,(info->fix.line_length & 0xff00)>>8);
1145
1146 XGIfb_post_setmode();
1147
1148 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d \n",
1149 XGIbios_mode[xgifb_mode_idx].xres,
1150 XGIbios_mode[xgifb_mode_idx].yres,
1151 XGIbios_mode[xgifb_mode_idx].bpp,
1152 xgi_video_info.refresh_rate);
1153
1154 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1155 xgi_video_info.video_vwidth = info->var.xres_virtual;
1156 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1157 xgi_video_info.video_vheight = info->var.yres_virtual;
1158 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1159 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1160 xgi_video_info.video_linelength = info->var.xres_virtual * (xgi_video_info.video_bpp >> 3);
1161 xgi_video_info.accel = 0;
1162 if(XGIfb_accel) {
1163 xgi_video_info.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
1164 }
1165 switch(xgi_video_info.video_bpp)
1166 {
1167 case 8:
1168 xgi_video_info.DstColor = 0x0000;
1169 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1170 xgi_video_info.video_cmap_len = 256;
1171#if defined(__powerpc__)
1172 inXGIIDXREG (XGICR, 0x4D, cr_data);
1173 outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
1174#endif
1175 break;
1176 case 16:
1177 xgi_video_info.DstColor = 0x8000;
1178 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1179#if defined(__powerpc__)
1180 inXGIIDXREG (XGICR, 0x4D, cr_data);
1181 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1182#endif
1183 xgi_video_info.video_cmap_len = 16;
1184 break;
1185 case 32:
1186 xgi_video_info.DstColor = 0xC000;
1187 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1188 xgi_video_info.video_cmap_len = 16;
1189#if defined(__powerpc__)
1190 inXGIIDXREG (XGICR, 0x4D, cr_data);
1191 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1192#endif
1193 break;
1194 default:
1195 xgi_video_info.video_cmap_len = 16;
1196 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1197 xgi_video_info.accel = 0;
1198 break;
1199 }
1200 }
1201 XGIfb_bpp_to_var(var); /*update ARGB info*/
1202 DEBUGPRN("End of do_set_var");
1203
1204 dumpVGAReg();
1205 return 0;
1206}
1207
1208#ifdef XGIFB_PAN
1209static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1210{
1211 unsigned int base;
1212
1213// printk("Inside pan_var");
1214
1215 if (var->xoffset > (var->xres_virtual - var->xres)) {
1216// printk( "Pan: xo: %d xv %d xr %d\n",
1217// var->xoffset, var->xres_virtual, var->xres);
1218 return -EINVAL;
1219 }
1220 if(var->yoffset > (var->yres_virtual - var->yres)) {
1221// printk( "Pan: yo: %d yv %d yr %d\n",
1222// var->yoffset, var->yres_virtual, var->yres);
1223 return -EINVAL;
1224 }
1225 base = var->yoffset * var->xres_virtual + var->xoffset;
1226
1227 /* calculate base bpp dep. */
1228 switch(var->bits_per_pixel) {
1229 case 16:
1230 base >>= 1;
1231 break;
1232 case 32:
1233 break;
1234 case 8:
1235 default:
1236 base >>= 2;
1237 break;
1238 }
1239
1240 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1241
1242 outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
1243 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1244 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
1245 outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
1246 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1247
1248 if(xgi_video_info.disp_state & DISPTYPE_DISP2) {
1249 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1250 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1251 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1252 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1253 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1254 }
1255// printk("End of pan_var");
1256 return 0;
1257}
1258#endif
1259
1260
1261void XGI_dispinfo(struct ap_data *rec)
1262{
1263 rec->minfo.bpp = xgi_video_info.video_bpp;
1264 rec->minfo.xres = xgi_video_info.video_width;
1265 rec->minfo.yres = xgi_video_info.video_height;
1266 rec->minfo.v_xres = xgi_video_info.video_vwidth;
1267 rec->minfo.v_yres = xgi_video_info.video_vheight;
1268 rec->minfo.org_x = xgi_video_info.org_x;
1269 rec->minfo.org_y = xgi_video_info.org_y;
1270 rec->minfo.vrate = xgi_video_info.refresh_rate;
1271 rec->iobase = xgi_video_info.vga_base - 0x30;
1272 rec->mem_size = xgi_video_info.video_size;
1273 rec->disp_state = xgi_video_info.disp_state;
1274 rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
1275 rec->hasVB = xgi_video_info.hasVB;
1276 rec->TV_type = xgi_video_info.TV_type;
1277 rec->TV_plug = xgi_video_info.TV_plug;
1278 rec->chip = xgi_video_info.chip;
1279}
1280
1281
1282
1283
1284static int XGIfb_open(struct fb_info *info, int user)
1285{
1286 return 0;
1287}
1288
1289static int XGIfb_release(struct fb_info *info, int user)
1290{
1291 return 0;
1292}
1293
1294static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1295{
1296 int rc = 16;
1297
1298 switch(var->bits_per_pixel) {
1299 case 8:
1300 rc = 256;
1301 break;
1302 case 16:
1303 rc = 16;
1304 break;
1305 case 32:
1306 rc = 16;
1307 break;
1308 }
1309 return rc;
1310}
1311
1312static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
1313 unsigned transp, struct fb_info *info)
1314{
1315 if (regno >= XGIfb_get_cmap_len(&info->var))
1316 return 1;
1317
1318 switch (info->var.bits_per_pixel) {
1319 case 8:
1320 outXGIREG(XGIDACA, regno);
1321 outXGIREG(XGIDACD, (red >> 10));
1322 outXGIREG(XGIDACD, (green >> 10));
1323 outXGIREG(XGIDACD, (blue >> 10));
1324 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1325 outXGIREG(XGIDAC2A, regno);
1326 outXGIREG(XGIDAC2D, (red >> 8));
1327 outXGIREG(XGIDAC2D, (green >> 8));
1328 outXGIREG(XGIDAC2D, (blue >> 8));
1329 }
1330 break;
1331 case 16:
1332 ((u32 *)(info->pseudo_palette))[regno] =
1333 ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
1334 break;
1335 case 32:
1336 red >>= 8;
1337 green >>= 8;
1338 blue >>= 8;
1339 ((u32 *) (info->pseudo_palette))[regno] =
1340 (red << 16) | (green << 8) | (blue);
1341 break;
1342 }
1343 return 0;
1344}
1345
1346static int XGIfb_set_par(struct fb_info *info)
1347{
1348 int err;
1349
1350// printk("XGIfb: inside set_par\n");
1351 if((err = XGIfb_do_set_var(&info->var, 1, info)))
1352 return err;
1353#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
1354 XGIfb_get_fix(&info->fix, info->currcon, info);
1355#else
1356 XGIfb_get_fix(&info->fix, -1, info);
1357#endif
1358// printk("XGIfb:end of set_par\n");
1359 return 0;
1360}
1361
1362static int XGIfb_check_var(struct fb_var_screeninfo *var,
1363 struct fb_info *info)
1364{
1365 unsigned int htotal =
1366 var->left_margin + var->xres + var->right_margin +
1367 var->hsync_len;
1368 unsigned int vtotal = 0;
1369 unsigned int drate = 0, hrate = 0;
1370 int found_mode = 0;
1371 int refresh_rate, search_idx;
1372
1373 DEBUGPRN("Inside check_var");
1374
1375 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1376 vtotal = var->upper_margin + var->yres + var->lower_margin +
1377 var->vsync_len;
1378 vtotal <<= 1;
1379 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1380 vtotal = var->upper_margin + var->yres + var->lower_margin +
1381 var->vsync_len;
1382 vtotal <<= 2;
1383 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1384 vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
1385 var->vsync_len;
1386 } else vtotal = var->upper_margin + var->yres + var->lower_margin +
1387 var->vsync_len;
1388
1389 if(!(htotal) || !(vtotal)) {
1390 XGIFAIL("XGIfb: no valid timing data");
1391 }
1392
1393
1394 if(var->pixclock && htotal && vtotal) {
1395 drate = 1000000000 / var->pixclock;
1396 hrate = (drate * 1000) / htotal;
1397 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1398 printk(KERN_DEBUG \
1399 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n" \
1400 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1401 __func__,var->pixclock, htotal, vtotal,
1402 __func__, drate, hrate, xgi_video_info.refresh_rate);
1403 } else {
1404 xgi_video_info.refresh_rate = 60;
1405 }
1406
1407/*
1408 if((var->pixclock) && (htotal)) {
1409 drate = 1E12 / var->pixclock;
1410 hrate = drate / htotal;
1411 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1412 } else refresh_rate = 60;
1413*/
1414 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1415 if((var->xres == 1024) && (var->yres == 600)) refresh_rate = 60;
1416
1417 search_idx = 0;
1418 while((XGIbios_mode[search_idx].mode_no != 0) &&
1419 (XGIbios_mode[search_idx].xres <= var->xres) ) {
1420 if((XGIbios_mode[search_idx].xres == var->xres) &&
1421 (XGIbios_mode[search_idx].yres == var->yres) &&
1422 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1423 if(XGIfb_validate_mode(search_idx) > 0) {
1424 found_mode = 1;
1425 break;
1426 }
1427 }
1428 search_idx++;
1429 }
1430
1431 if(!found_mode) {
1432
1433 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1434 var->xres, var->yres, var->bits_per_pixel);
1435
1436 search_idx = 0;
1437 while(XGIbios_mode[search_idx].mode_no != 0) {
1438
1439 if( (var->xres <= XGIbios_mode[search_idx].xres) &&
1440 (var->yres <= XGIbios_mode[search_idx].yres) &&
1441 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp) ) {
1442 if(XGIfb_validate_mode(search_idx) > 0) {
1443 found_mode = 1;
1444 break;
1445 }
1446 }
1447 search_idx++;
1448 }
1449 if(found_mode) {
1450 var->xres = XGIbios_mode[search_idx].xres;
1451 var->yres = XGIbios_mode[search_idx].yres;
1452 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1453 var->xres, var->yres, var->bits_per_pixel);
1454
1455 } else {
1456 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1457 var->xres, var->yres, var->bits_per_pixel);
1458 return -EINVAL;
1459 }
1460 }
1461
1462 /* TW: TODO: Check the refresh rate */
1463
1464 /* Adapt RGB settings */
1465 XGIfb_bpp_to_var(var);
1466
1467 /* Sanity check for offsets */
1468 if (var->xoffset < 0)
1469 var->xoffset = 0;
1470 if (var->yoffset < 0)
1471 var->yoffset = 0;
1472
1473
1474 if(!XGIfb_ypan) {
1475 if(var->xres != var->xres_virtual)
1476 var->xres_virtual = var->xres;
1477 if(var->yres != var->yres_virtual)
1478 var->yres_virtual = var->yres;
1479 }/* else {
1480 // TW: Now patch yres_virtual if we use panning
1481 // May I do this?
1482 var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3));
1483 if(var->yres_virtual <= var->yres) {
1484 // TW: Paranoia check
1485 var->yres_virtual = var->yres;
1486 }
1487 }*/
1488
1489 /* Truncate offsets to maximum if too high */
1490 if (var->xoffset > var->xres_virtual - var->xres)
1491 var->xoffset = var->xres_virtual - var->xres - 1;
1492
1493 if (var->yoffset > var->yres_virtual - var->yres)
1494 var->yoffset = var->yres_virtual - var->yres - 1;
1495
1496 /* Set everything else to 0 */
1497 var->red.msb_right =
1498 var->green.msb_right =
1499 var->blue.msb_right =
1500 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1501
1502 DEBUGPRN("end of check_var");
1503 return 0;
1504}
1505
1506#ifdef XGIFB_PAN
1507static int XGIfb_pan_display( struct fb_var_screeninfo *var,
1508 struct fb_info* info)
1509{
1510 int err;
1511
1512// printk("\nInside pan_display:");
1513
1514 if (var->xoffset > (var->xres_virtual - var->xres))
1515 return -EINVAL;
1516 if (var->yoffset > (var->yres_virtual - var->yres))
1517 return -EINVAL;
1518
1519 if (var->vmode & FB_VMODE_YWRAP) {
1520 if (var->yoffset < 0
1521 || var->yoffset >= info->var.yres_virtual
1522 || var->xoffset) return -EINVAL;
1523 } else {
1524 if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1525 var->yoffset + info->var.yres > info->var.yres_virtual)
1526 return -EINVAL;
1527 }
1528
1529 if((err = XGIfb_pan_var(var)) < 0) return err;
1530
1531 info->var.xoffset = var->xoffset;
1532 info->var.yoffset = var->yoffset;
1533 if (var->vmode & FB_VMODE_YWRAP)
1534 info->var.vmode |= FB_VMODE_YWRAP;
1535 else
1536 info->var.vmode &= ~FB_VMODE_YWRAP;
1537
1538// printk(" End of pan_display");
1539 return 0;
1540}
1541#endif
1542
1543#if 0
1544static int XGIfb_mmap(struct fb_info *info, struct file *file,
1545 struct vm_area_struct *vma)
1546{
1547 unsigned long start;
1548 unsigned long off;
1549 u32 len, mmio_off;
1550
1551 DEBUGPRN("inside mmap");
1552 if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL;
1553
1554 off = vma->vm_pgoff << PAGE_SHIFT;
1555
1556 start = (unsigned long) xgi_video_info.video_base;
1557 len = PAGE_ALIGN((start & ~PAGE_MASK) + xgi_video_info.video_size);
1558 start &= PAGE_MASK;
1559#if 0
1560 if (off >= len) {
1561 off -= len;
1562#endif
1563 /* By Jake Page: Treat mmap request with offset beyond heapstart
1564 * as request for mapping the mmio area
1565 */
1566 #if 1
1567 mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + xgi_video_info.heapstart);
1568 if(off >= mmio_off) {
1569 off -= mmio_off;
1570 if(info->var.accel_flags) return -EINVAL;
1571
1572 start = (unsigned long) xgi_video_info.mmio_base;
1573 len = PAGE_ALIGN((start & ~PAGE_MASK) + XGIfb_mmio_size);
1574 }
1575 start &= PAGE_MASK;
1576 #endif
1577 if((vma->vm_end - vma->vm_start + off) > len) return -EINVAL;
1578
1579 off += start;
1580 vma->vm_pgoff = off >> PAGE_SHIFT;
1581 vma->vm_flags |= VM_IO; /* by Jake Page; is that really needed? */
1582
1583#if defined(__i386__) || defined(__x86_64__)
1584 if (boot_cpu_data.x86 > 3)
1585 pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
1586#endif
1587 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start,
1588 vma->vm_page_prot))
1589 return -EAGAIN;
1590
1591 DEBUGPRN("end of mmap");
1592 return 0;
1593}
1594#endif
1595static int XGIfb_blank(int blank, struct fb_info *info)
1596{
1597 u8 reg;
1598
1599 inXGIIDXREG(XGICR, 0x17, reg);
1600
1601 if(blank > 0)
1602 reg &= 0x7f;
1603 else
1604 reg |= 0x80;
1605
1606 outXGIIDXREG(XGICR, 0x17, reg);
1607 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1608 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1609 return(0);
1610}
1611
1612
1613#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
1614static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
1615 unsigned long arg)
1616#else
1617static int XGIfb_ioctl(struct inode *inode, struct file *file,
1618 unsigned int cmd, unsigned long arg,
1619 struct fb_info *info)
1620#endif
1621
1622{
1623 DEBUGPRN("inside ioctl");
1624 switch (cmd) {
1625 case FBIO_ALLOC:
1626 if (!capable(CAP_SYS_RAWIO))
1627 return -EPERM;
1628 XGI_malloc((struct XGI_memreq *) arg);
1629 break;
1630 case FBIO_FREE:
1631 if (!capable(CAP_SYS_RAWIO))
1632 return -EPERM;
1633 XGI_free(*(unsigned long *) arg);
1634 break;
1635 case FBIOGET_HWCINFO:
1636 {
1637 unsigned long *hwc_offset = (unsigned long *) arg;
1638
1639 if (XGIfb_caps & HW_CURSOR_CAP)
1640 *hwc_offset = XGIfb_hwcursor_vbase -
1641 (unsigned long) xgi_video_info.video_vbase;
1642 else
1643 *hwc_offset = 0;
1644
1645 break;
1646 }
1647 case FBIOPUT_MODEINFO:
1648 {
1649 struct mode_info *x = (struct mode_info *)arg;
1650
1651 xgi_video_info.video_bpp = x->bpp;
1652 xgi_video_info.video_width = x->xres;
1653 xgi_video_info.video_height = x->yres;
1654 xgi_video_info.video_vwidth = x->v_xres;
1655 xgi_video_info.video_vheight = x->v_yres;
1656 xgi_video_info.org_x = x->org_x;
1657 xgi_video_info.org_y = x->org_y;
1658 xgi_video_info.refresh_rate = x->vrate;
1659 xgi_video_info.video_linelength = xgi_video_info.video_vwidth * (xgi_video_info.video_bpp >> 3);
1660 switch(xgi_video_info.video_bpp) {
1661 case 8:
1662 xgi_video_info.DstColor = 0x0000;
1663 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1664 xgi_video_info.video_cmap_len = 256;
1665 break;
1666 case 16:
1667 xgi_video_info.DstColor = 0x8000;
1668 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1669 xgi_video_info.video_cmap_len = 16;
1670 break;
1671 case 32:
1672 xgi_video_info.DstColor = 0xC000;
1673 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1674 xgi_video_info.video_cmap_len = 16;
1675 break;
1676 default:
1677 xgi_video_info.video_cmap_len = 16;
1678 printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
1679 xgi_video_info.accel = 0;
1680 break;
1681 }
1682
1683 break;
1684 }
1685 case FBIOGET_DISPINFO:
1686 XGI_dispinfo((struct ap_data *)arg);
1687 break;
1688 case XGIFB_GET_INFO: /* TW: New for communication with X driver */
1689 {
1690 XGIfb_info *x = (XGIfb_info *)arg;
1691
1692 //x->XGIfb_id = XGIFB_ID;
1693 x->XGIfb_version = VER_MAJOR;
1694 x->XGIfb_revision = VER_MINOR;
1695 x->XGIfb_patchlevel = VER_LEVEL;
1696 x->chip_id = xgi_video_info.chip_id;
1697 x->memory = xgi_video_info.video_size / 1024;
1698 x->heapstart = xgi_video_info.heapstart / 1024;
1699 x->fbvidmode = XGIfb_mode_no;
1700 x->XGIfb_caps = XGIfb_caps;
1701 x->XGIfb_tqlen = 512; /* yet unused */
1702 x->XGIfb_pcibus = xgi_video_info.pcibus;
1703 x->XGIfb_pcislot = xgi_video_info.pcislot;
1704 x->XGIfb_pcifunc = xgi_video_info.pcifunc;
1705 x->XGIfb_lcdpdc = XGIfb_detectedpdc;
1706 x->XGIfb_lcda = XGIfb_detectedlcda;
1707 break;
1708 }
1709 case XGIFB_GET_VBRSTATUS:
1710 {
1711 unsigned long *vbrstatus = (unsigned long *) arg;
1712 if(XGIfb_CheckVBRetrace()) *vbrstatus = 1;
1713 else *vbrstatus = 0;
1714 }
1715 default:
1716 return -EINVAL;
1717 }
1718 DEBUGPRN("end of ioctl");
1719 return 0;
1720
1721}
1722
1723
1724
1725/* ----------- FBDev related routines for all series ---------- */
1726
1727static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1728 struct fb_info *info)
1729{
1730 DEBUGPRN("inside get_fix");
1731 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1732
1733 strcpy(fix->id, myid);
1734
1735 fix->smem_start = xgi_video_info.video_base;
1736
1737 fix->smem_len = xgi_video_info.video_size;
1738
1739
1740/* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
1741 if (xgi_video_info.video_size > 0x1000000) {
1742 fix->smem_len = 0xD00000;
1743 } else if (xgi_video_info.video_size > 0x800000)
1744 fix->smem_len = 0x800000;
1745 else
1746 fix->smem_len = 0x400000;
1747 } else
1748 fix->smem_len = XGIfb_mem * 1024;
1749*/
1750 fix->type = video_type;
1751 fix->type_aux = 0;
1752 if(xgi_video_info.video_bpp == 8)
1753 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1754 else
1755 fix->visual = FB_VISUAL_DIRECTCOLOR;
1756 fix->xpanstep = 0;
1757#ifdef XGIFB_PAN
1758 if(XGIfb_ypan) fix->ypanstep = 1;
1759#endif
1760 fix->ywrapstep = 0;
1761 fix->line_length = xgi_video_info.video_linelength;
1762 fix->mmio_start = xgi_video_info.mmio_base;
1763 fix->mmio_len = XGIfb_mmio_size;
1764 if(xgi_video_info.chip >= XG40)
1765 fix->accel = FB_ACCEL_XGI_XABRE;
1766 else
1767 fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
1768
1769
1770 DEBUGPRN("end of get_fix");
1771 return 0;
1772}
1773
1774
1775static struct fb_ops XGIfb_ops = {
1776 .owner = THIS_MODULE,
1777 .fb_open = XGIfb_open,
1778 .fb_release = XGIfb_release,
1779 .fb_check_var = XGIfb_check_var,
1780 .fb_set_par = XGIfb_set_par,
1781 .fb_setcolreg = XGIfb_setcolreg,
1782#ifdef XGIFB_PAN
1783 .fb_pan_display = XGIfb_pan_display,
1784#endif
1785 .fb_blank = XGIfb_blank,
1786 .fb_fillrect = fbcon_XGI_fillrect,
1787 .fb_copyarea = fbcon_XGI_copyarea,
1788 .fb_imageblit = cfb_imageblit,
1789#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1790 .fb_cursor = soft_cursor,
1791#endif
1792 .fb_sync = fbcon_XGI_sync,
1793 .fb_ioctl = XGIfb_ioctl,
1794// .fb_mmap = XGIfb_mmap,
1795};
1796
1797/* ---------------- Chip generation dependent routines ---------------- */
1798
1799
1800/* for XGI 315/550/650/740/330 */
1801
1802static int XGIfb_get_dram_size(void)
1803{
1804
1805 u8 ChannelNum,tmp;
1806 u8 reg = 0;
1807
1808 /* xorg driver sets 32MB * 1 channel */
1809 if (xgi_video_info.chip == XG27)
1810 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1811
1812 inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1813 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1814 case XGI_DRAM_SIZE_1MB:
1815 xgi_video_info.video_size = 0x100000;
1816 break;
1817 case XGI_DRAM_SIZE_2MB:
1818 xgi_video_info.video_size = 0x200000;
1819 break;
1820 case XGI_DRAM_SIZE_4MB:
1821 xgi_video_info.video_size = 0x400000;
1822 break;
1823 case XGI_DRAM_SIZE_8MB:
1824 xgi_video_info.video_size = 0x800000;
1825 break;
1826 case XGI_DRAM_SIZE_16MB:
1827 xgi_video_info.video_size = 0x1000000;
1828 break;
1829 case XGI_DRAM_SIZE_32MB:
1830 xgi_video_info.video_size = 0x2000000;
1831 break;
1832 case XGI_DRAM_SIZE_64MB:
1833 xgi_video_info.video_size = 0x4000000;
1834 break;
1835 case XGI_DRAM_SIZE_128MB:
1836 xgi_video_info.video_size = 0x8000000;
1837 break;
1838 case XGI_DRAM_SIZE_256MB:
1839 xgi_video_info.video_size = 0x10000000;
1840 break;
1841 default:
1842 return -1;
1843 }
1844
1845 tmp = (reg & 0x0c) >> 2;
1846 switch(xgi_video_info.chip)
1847 {
1848 case XG20:
1849 case XG21:
1850 case XG27:
1851 ChannelNum = 1;
1852 break;
1853
1854 case XG42:
1855 if(reg & 0x04)
1856 ChannelNum = 2;
1857 else
1858 ChannelNum = 1;
1859 break;
1860
1861 case XG45:
1862 if(tmp == 1)
1863 ChannelNum = 2;
1864 else
1865 if(tmp == 2)
1866 ChannelNum = 3;
1867 else
1868 if(tmp == 3)
1869 ChannelNum = 4;
1870 else
1871 ChannelNum = 1;
1872 break;
1873
1874 case XG40:
1875 default:
1876 if(tmp == 2)
1877 ChannelNum = 2;
1878 else
1879 if(tmp == 3)
1880 ChannelNum = 3;
1881 else
1882 ChannelNum = 1;
1883 break;
1884 }
1885
1886
1887 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1888 //PLiad fixed for benchmarking and fb set
1889 //xgi_video_info.video_size = 0x200000;//1024x768x16
1890 //xgi_video_info.video_size = 0x1000000;//benchmark
1891
1892 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",reg,xgi_video_info.video_size ,ChannelNum );
1893 return 0;
1894
1895}
1896
1897static void XGIfb_detect_VB(void)
1898{
1899 u8 cr32, temp=0;
1900
1901 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1902
1903 switch(xgi_video_info.hasVB) {
1904 case HASVB_LVDS_CHRONTEL:
1905 case HASVB_CHRONTEL:
1906 break;
1907 case HASVB_301:
1908 case HASVB_302:
1909// XGI_Sense30x(); //Yi-Lin TV Sense?
1910 break;
1911 }
1912
1913 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1914
1915 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1916 XGIfb_crt1off = 0;
1917 else {
1918 if (cr32 & 0x5F)
1919 XGIfb_crt1off = 1;
1920 else
1921 XGIfb_crt1off = 0;
1922 }
1923
1924 if (XGIfb_crt2type != -1)
1925 /* TW: Override with option */
1926 xgi_video_info.disp_state = XGIfb_crt2type;
1927 else if (cr32 & XGI_VB_TV)
1928 xgi_video_info.disp_state = DISPTYPE_TV;
1929 else if (cr32 & XGI_VB_LCD)
1930 xgi_video_info.disp_state = DISPTYPE_LCD;
1931 else if (cr32 & XGI_VB_CRT2)
1932 xgi_video_info.disp_state = DISPTYPE_CRT2;
1933 else
1934 xgi_video_info.disp_state = 0;
1935
1936 if(XGIfb_tvplug != -1)
1937 /* PR/TW: Override with option */
1938 xgi_video_info.TV_plug = XGIfb_tvplug;
1939 else if (cr32 & XGI_VB_HIVISION) {
1940 xgi_video_info.TV_type = TVMODE_HIVISION;
1941 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1942 }
1943 else if (cr32 & XGI_VB_SVIDEO)
1944 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1945 else if (cr32 & XGI_VB_COMPOSITE)
1946 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1947 else if (cr32 & XGI_VB_SCART)
1948 xgi_video_info.TV_plug = TVPLUG_SCART;
1949
1950 if(xgi_video_info.TV_type == 0) {
1951 /* TW: PAL/NTSC changed for 650 */
1952 if((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip >= XGI_330)) {
1953
1954 inXGIIDXREG(XGICR, 0x38, temp);
1955 if(temp & 0x10)
1956 xgi_video_info.TV_type = TVMODE_PAL;
1957 else
1958 xgi_video_info.TV_type = TVMODE_NTSC;
1959
1960 } else {
1961
1962 inXGIIDXREG(XGICR, 0x79, temp);
1963 if(temp & 0x20)
1964 xgi_video_info.TV_type = TVMODE_PAL;
1965 else
1966 xgi_video_info.TV_type = TVMODE_NTSC;
1967 }
1968 }
1969
1970 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1971 if (XGIfb_forcecrt1 != -1) {
1972 if (XGIfb_forcecrt1) XGIfb_crt1off = 0;
1973 else XGIfb_crt1off = 1;
1974 }
1975}
1976
1977static void XGIfb_get_VB_type(void)
1978{
1979 u8 reg;
1980
1981 if (!XGIfb_has_VB()) {
1982 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
1983 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1984 case XGI310_EXTERNAL_CHIP_LVDS:
1985 xgi_video_info.hasVB = HASVB_LVDS;
1986 break;
1987 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1988 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1989 break;
1990 default:
1991 break;
1992 }
1993 }
1994}
1995
1996
1997static int XGIfb_has_VB(void)
1998{
1999 u8 vb_chipid;
2000
2001 inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
2002 switch (vb_chipid) {
2003 case 0x01:
2004 xgi_video_info.hasVB = HASVB_301;
2005 break;
2006 case 0x02:
2007 xgi_video_info.hasVB = HASVB_302;
2008 break;
2009 default:
2010 xgi_video_info.hasVB = HASVB_NONE;
2011 return FALSE;
2012 }
2013 return TRUE;
2014}
2015
2016
2017
2018/* ------------------ Sensing routines ------------------ */
2019
2020/* TW: Determine and detect attached devices on XGI30x */
2021int
2022XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
2023{
2024 int temp,i;
2025
2026 outXGIIDXREG(XGIPART4,0x11,tempbl);
2027 temp = tempbh | tempcl;
2028 setXGIIDXREG(XGIPART4,0x10,0xe0,temp);
2029 for(i=0; i<10; i++) XGI_LongWait(&XGI_Pr);
2030 tempch &= 0x7f;
2031 inXGIIDXREG(XGIPART4,0x03,temp);
2032 temp ^= 0x0e;
2033 temp &= tempch;
2034 return(temp);
2035}
2036
2037void
2038XGI_Sense30x(void)
2039{
2040 u8 backupP4_0d;
2041 u8 testsvhs_tempbl, testsvhs_tempbh;
2042 u8 testsvhs_tempcl, testsvhs_tempch;
2043 u8 testcvbs_tempbl, testcvbs_tempbh;
2044 u8 testcvbs_tempcl, testcvbs_tempch;
2045 u8 testvga2_tempbl, testvga2_tempbh;
2046 u8 testvga2_tempcl, testvga2_tempch;
2047 int myflag, result;
2048
2049 inXGIIDXREG(XGIPART4,0x0d,backupP4_0d);
2050 outXGIIDXREG(XGIPART4,0x0d,(backupP4_0d | 0x04));
2051
2052
2053
2054 testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
2055 testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
2056 testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
2057 if((XGIhw_ext.ujVBChipID != VB_CHIP_301) &&
2058 (XGIhw_ext.ujVBChipID != VB_CHIP_302)) {
2059 testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
2060 testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
2061 testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
2062 if(XGIhw_ext.ujVBChipID == VB_CHIP_301LV ||
2063 XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
2064 testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
2065 testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
2066 testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
2067 }
2068 }
2069 if(XGIhw_ext.ujVBChipID != VB_CHIP_301LV &&
2070 XGIhw_ext.ujVBChipID != VB_CHIP_302LV) {
2071 inXGIIDXREG(XGIPART4,0x01,myflag);
2072 if(myflag & 0x04) {
2073 testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
2074 testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
2075 testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
2076 }
2077 }
2078 if((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2079 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV) ) {
2080 testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
2081 testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
2082 testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
2083 testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
2084 } else {
2085 testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
2086 testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
2087 testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
2088 }
2089
2090
2091 if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
2092 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
2093 testvga2_tempcl, testvga2_tempch);
2094 if(result) {
2095 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
2096 orXGIIDXREG(XGICR, 0x32, 0x10);
2097 }
2098 }
2099
2100 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh,
2101 testsvhs_tempcl, testsvhs_tempch);
2102 if(result) {
2103 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
2104 /* TW: So we can be sure that there IS a SVHS output */
2105 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
2106 orXGIIDXREG(XGICR, 0x32, 0x02);
2107 }
2108
2109 if(!result) {
2110 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
2111 testcvbs_tempcl, testcvbs_tempch);
2112 if(result) {
2113 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
2114 /* TW: So we can be sure that there IS a CVBS output */
2115 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
2116 orXGIIDXREG(XGICR, 0x32, 0x01);
2117 }
2118 }
2119 XGIDoSense(0, 0, 0, 0);
2120
2121 outXGIIDXREG(XGIPART4,0x0d,backupP4_0d);
2122}
2123
2124
2125
2126/* ------------------------ Heap routines -------------------------- */
2127
2128static int XGIfb_heap_init(void)
2129{
2130 XGI_OH *poh;
2131 u8 temp=0;
2132
2133 int agp_enabled = 1;
2134 u32 agp_size;
2135 unsigned long *cmdq_baseport = 0;
2136 unsigned long *read_port = 0;
2137 unsigned long *write_port = 0;
2138 XGI_CMDTYPE cmd_type;
2139#ifndef AGPOFF
2140 struct agp_kern_info *agp_info;
2141 struct agp_memory *agp;
2142 u32 agp_phys;
2143#endif
2144
2145/* TW: The heap start is either set manually using the "mem" parameter, or
2146 * defaults as follows:
2147 * -) If more than 16MB videoRAM available, let our heap start at 12MB.
2148 * -) If more than 8MB videoRAM available, let our heap start at 8MB.
2149 * -) If 4MB or less is available, let it start at 4MB.
2150 * This is for avoiding a clash with X driver which uses the beginning
2151 * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
2152 * in XF86Config-4.
2153 * The heap start can also be specified by parameter "mem" when starting the XGIfb
2154 * driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
2155 */
2156 if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
2157 if (xgi_video_info.video_size > 0x1000000) {
2158 xgi_video_info.heapstart = 0xD00000;
2159 } else if (xgi_video_info.video_size > 0x800000) {
2160 xgi_video_info.heapstart = 0x800000;
2161 } else {
2162 xgi_video_info.heapstart = 0x400000;
2163 }
2164 } else {
2165 xgi_video_info.heapstart = XGIfb_mem * 1024;
2166 }
2167 XGIfb_heap_start =
2168 (unsigned long) (xgi_video_info.video_vbase + xgi_video_info.heapstart);
2169 printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
2170 (int)(xgi_video_info.heapstart / 1024));
2171
2172 XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase + xgi_video_info.video_size;
2173 XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
2174
2175
2176
2177 /* TW: Now initialize the 310 series' command queue mode.
2178 * On 310/325, there are three queue modes available which
2179 * are chosen by setting bits 7:5 in SR26:
2180 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
2181 * track of the queue, the FIFO, command parsing and so
2182 * on. This is the one comparable to the 300 series.
2183 * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
2184 * have to do queue management himself. Register 0x85c4 will
2185 * hold the location of the next free queue slot, 0x85c8
2186 * is the "queue read pointer" whose way of working is
2187 * unknown to me. Anyway, this mode would require a
2188 * translation of the MMIO commands to some kind of
2189 * accelerator assembly and writing these commands
2190 * to the memory location pointed to by 0x85c4.
2191 * We will not use this, as nobody knows how this
2192 * "assembly" works, and as it would require a complete
2193 * re-write of the accelerator code.
2194 * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
2195 * queue in AGP memory space.
2196 *
2197 * SR26 bit 4 is called "Bypass H/W queue".
2198 * SR26 bit 1 is called "Enable Command Queue Auto Correction"
2199 * SR26 bit 0 resets the queue
2200 * Size of queue memory is encoded in bits 3:2 like this:
2201 * 00 (0x00) 512K
2202 * 01 (0x04) 1M
2203 * 10 (0x08) 2M
2204 * 11 (0x0C) 4M
2205 * The queue location is to be written to 0x85C0.
2206 *
2207 */
2208 cmdq_baseport = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_PHYBASE);
2209 write_port = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_WRITEPORT);
2210 read_port = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_READPORT);
2211
2212 DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
2213
2214 agp_size = COMMAND_QUEUE_AREA_SIZE;
2215
2216#ifndef AGPOFF
2217 if (XGIfb_queuemode == AGP_CMD_QUEUE) {
2218 agp_info = vmalloc(sizeof(*agp_info));
2219 memset((void*)agp_info, 0x00, sizeof(*agp_info));
2220 agp_copy_info(agp_info);
2221
2222 agp_backend_acquire();
2223
2224 agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE/PAGE_SIZE,
2225 AGP_NORMAL_MEMORY);
2226 if (agp == NULL) {
2227 DPRINTK("XGIfb: Allocating AGP buffer failed.\n");
2228 agp_enabled = 0;
2229 } else {
2230 if (agp_bind_memory(agp, agp->pg_start) != 0) {
2231 DPRINTK("XGIfb: AGP: Failed to bind memory\n");
2232 /* TODO: Free AGP memory here */
2233 agp_enabled = 0;
2234 } else {
2235 agp_enable(0);
2236 }
2237 }
2238 }
2239#else
2240 agp_enabled = 0;
2241#endif
2242
2243 /* TW: Now select the queue mode */
2244
2245 if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) {
2246 cmd_type = AGP_CMD_QUEUE;
2247 printk(KERN_INFO "XGIfb: Using AGP queue mode\n");
2248/* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
2249 } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
2250 cmd_type = VM_CMD_QUEUE;
2251 printk(KERN_INFO "XGIfb: Using VRAM queue mode\n");
2252 } else {
2253 printk(KERN_INFO "XGIfb: Using MMIO queue mode\n");
2254 cmd_type = MMIO_CMD;
2255 }
2256
2257 switch (agp_size) {
2258 case 0x80000:
2259 temp = XGI_CMD_QUEUE_SIZE_512k;
2260 break;
2261 case 0x100000:
2262 temp = XGI_CMD_QUEUE_SIZE_1M;
2263 break;
2264 case 0x200000:
2265 temp = XGI_CMD_QUEUE_SIZE_2M;
2266 break;
2267 case 0x400000:
2268 temp = XGI_CMD_QUEUE_SIZE_4M;
2269 break;
2270 }
2271
2272 switch (cmd_type) {
2273 case AGP_CMD_QUEUE:
2274#ifndef AGPOFF
2275 DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
2276 agp_info->aper_base, agp->physical, agp_size/1024);
2277
2278 agp_phys = agp_info->aper_base + agp->physical;
2279
2280 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
2281 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
2282
2283 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2284
2285 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2286
2287 *write_port = *read_port;
2288
2289 temp |= XGI_AGP_CMDQUEUE_ENABLE;
2290 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2291
2292 *cmdq_baseport = agp_phys;
2293
2294 XGIfb_caps |= AGP_CMD_QUEUE_CAP;
2295#endif
2296 break;
2297
2298 case VM_CMD_QUEUE:
2299 XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2300 XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2301
2302 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2303
2304 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2305
2306 *write_port = *read_port;
2307
2308 temp |= XGI_VRAM_CMDQUEUE_ENABLE;
2309 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2310
2311 *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2312
2313 XGIfb_caps |= VM_CMD_QUEUE_CAP;
2314
2315 DPRINTK("XGIfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
2316 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2317 break;
2318
2319 default: /* MMIO */
2320
2321// printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__);
2322 /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
2323 * to IND_XGI_CMDQUEUE_SET. I doubt that this is
2324 * enough. Reserve memory in any way.
2325 */
2326// FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2327// FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2328// FIXME
2329// FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2330// FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2331// FIXME
2332// FIXME *write_port = *read_port;
2333// FIXME
2334// FIXME /* TW: Set Auto_Correction bit */
2335// FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR);
2336// FIXME // FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2337// FIXME
2338// FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2339// FIXME
2340// FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP;
2341// FIXME
2342// FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n",
2343// FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2344 break;
2345 }
2346
2347
2348
2349
2350 /* TW: Now reserve memory for the HWCursor. It is always located at the very
2351 top of the videoRAM, right below the TB memory area (if used). */
2352 if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
2353 XGIfb_heap_end -= XGIfb_hwcursor_size;
2354 XGIfb_heap_size -= XGIfb_hwcursor_size;
2355 XGIfb_hwcursor_vbase = XGIfb_heap_end;
2356
2357 XGIfb_caps |= HW_CURSOR_CAP;
2358
2359 DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n",
2360 XGIfb_heap_end, XGIfb_hwcursor_size/1024);
2361 }
2362
2363 XGIfb_heap.poha_chain = NULL;
2364 XGIfb_heap.poh_freelist = NULL;
2365
2366 poh = XGIfb_poh_new_node();
2367
2368 if(poh == NULL) return 1;
2369
2370 poh->poh_next = &XGIfb_heap.oh_free;
2371 poh->poh_prev = &XGIfb_heap.oh_free;
2372 poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
2373 poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
2374
2375 DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
2376 (char *) XGIfb_heap_start, (char *) XGIfb_heap_end,
2377 (unsigned int) poh->size / 1024);
2378
2379 DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
2380 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
2381
2382 XGIfb_heap.oh_free.poh_next = poh;
2383 XGIfb_heap.oh_free.poh_prev = poh;
2384 XGIfb_heap.oh_free.size = 0;
2385 XGIfb_heap.max_freesize = poh->size;
2386
2387 XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
2388 XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
2389 XGIfb_heap.oh_used.size = SENTINEL;
2390
2391 return 0;
2392}
2393
2394static XGI_OH *XGIfb_poh_new_node(void)
2395{
2396 int i;
2397 unsigned long cOhs;
2398 XGI_OHALLOC *poha;
2399 XGI_OH *poh;
2400
2401 if (XGIfb_heap.poh_freelist == NULL) {
2402 poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
2403 if(!poha) return NULL;
2404
2405 poha->poha_next = XGIfb_heap.poha_chain;
2406 XGIfb_heap.poha_chain = poha;
2407
2408 cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH) + 1;
2409
2410 poh = &poha->aoh[0];
2411 for (i = cOhs - 1; i != 0; i--) {
2412 poh->poh_next = poh + 1;
2413 poh = poh + 1;
2414 }
2415
2416 poh->poh_next = NULL;
2417 XGIfb_heap.poh_freelist = &poha->aoh[0];
2418 }
2419
2420 poh = XGIfb_heap.poh_freelist;
2421 XGIfb_heap.poh_freelist = poh->poh_next;
2422
2423 return (poh);
2424}
2425
2426static XGI_OH *XGIfb_poh_allocate(unsigned long size)
2427{
2428 XGI_OH *pohThis;
2429 XGI_OH *pohRoot;
2430 int bAllocated = 0;
2431
2432 if (size > XGIfb_heap.max_freesize) {
2433 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2434 (unsigned int) size / 1024);
2435 return (NULL);
2436 }
2437
2438 pohThis = XGIfb_heap.oh_free.poh_next;
2439
2440 while (pohThis != &XGIfb_heap.oh_free) {
2441 if (size <= pohThis->size) {
2442 bAllocated = 1;
2443 break;
2444 }
2445 pohThis = pohThis->poh_next;
2446 }
2447
2448 if (!bAllocated) {
2449 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2450 (unsigned int) size / 1024);
2451 return (NULL);
2452 }
2453
2454 if (size == pohThis->size) {
2455 pohRoot = pohThis;
2456 XGIfb_delete_node(pohThis);
2457 } else {
2458 pohRoot = XGIfb_poh_new_node();
2459
2460 if (pohRoot == NULL) {
2461 return (NULL);
2462 }
2463
2464 pohRoot->offset = pohThis->offset;
2465 pohRoot->size = size;
2466
2467 pohThis->offset += size;
2468 pohThis->size -= size;
2469 }
2470
2471 XGIfb_heap.max_freesize -= size;
2472
2473 pohThis = &XGIfb_heap.oh_used;
2474 XGIfb_insert_node(pohThis, pohRoot);
2475
2476 return (pohRoot);
2477}
2478
2479static void XGIfb_delete_node(XGI_OH *poh)
2480{
2481 XGI_OH *poh_prev;
2482 XGI_OH *poh_next;
2483
2484 poh_prev = poh->poh_prev;
2485 poh_next = poh->poh_next;
2486
2487 poh_prev->poh_next = poh_next;
2488 poh_next->poh_prev = poh_prev;
2489
2490}
2491
2492static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh)
2493{
2494 XGI_OH *pohTemp;
2495
2496 pohTemp = pohList->poh_next;
2497
2498 pohList->poh_next = poh;
2499 pohTemp->poh_prev = poh;
2500
2501 poh->poh_prev = pohList;
2502 poh->poh_next = pohTemp;
2503}
2504
2505static XGI_OH *XGIfb_poh_free(unsigned long base)
2506{
2507 XGI_OH *pohThis;
2508 XGI_OH *poh_freed;
2509 XGI_OH *poh_prev;
2510 XGI_OH *poh_next;
2511 unsigned long ulUpper;
2512 unsigned long ulLower;
2513 int foundNode = 0;
2514
2515 poh_freed = XGIfb_heap.oh_used.poh_next;
2516
2517 while(poh_freed != &XGIfb_heap.oh_used) {
2518 if(poh_freed->offset == base) {
2519 foundNode = 1;
2520 break;
2521 }
2522
2523 poh_freed = poh_freed->poh_next;
2524 }
2525
2526 if (!foundNode) return (NULL);
2527
2528 XGIfb_heap.max_freesize += poh_freed->size;
2529
2530 poh_prev = poh_next = NULL;
2531 ulUpper = poh_freed->offset + poh_freed->size;
2532 ulLower = poh_freed->offset;
2533
2534 pohThis = XGIfb_heap.oh_free.poh_next;
2535
2536 while (pohThis != &XGIfb_heap.oh_free) {
2537 if (pohThis->offset == ulUpper) {
2538 poh_next = pohThis;
2539 }
2540 else if ((pohThis->offset + pohThis->size) ==
2541 ulLower) {
2542 poh_prev = pohThis;
2543 }
2544 pohThis = pohThis->poh_next;
2545 }
2546
2547 XGIfb_delete_node(poh_freed);
2548
2549 if (poh_prev && poh_next) {
2550 poh_prev->size += (poh_freed->size + poh_next->size);
2551 XGIfb_delete_node(poh_next);
2552 XGIfb_free_node(poh_freed);
2553 XGIfb_free_node(poh_next);
2554 return (poh_prev);
2555 }
2556
2557 if (poh_prev) {
2558 poh_prev->size += poh_freed->size;
2559 XGIfb_free_node(poh_freed);
2560 return (poh_prev);
2561 }
2562
2563 if (poh_next) {
2564 poh_next->size += poh_freed->size;
2565 poh_next->offset = poh_freed->offset;
2566 XGIfb_free_node(poh_freed);
2567 return (poh_next);
2568 }
2569
2570 XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed);
2571
2572 return (poh_freed);
2573}
2574
2575static void XGIfb_free_node(XGI_OH *poh)
2576{
2577 if(poh == NULL) return;
2578
2579 poh->poh_next = XGIfb_heap.poh_freelist;
2580 XGIfb_heap.poh_freelist = poh;
2581
2582}
2583
2584void XGI_malloc(struct XGI_memreq *req)
2585{
2586 XGI_OH *poh;
2587
2588 poh = XGIfb_poh_allocate(req->size);
2589
2590 if(poh == NULL) {
2591 req->offset = 0;
2592 req->size = 0;
2593 DPRINTK("XGIfb: Video RAM allocation failed\n");
2594 } else {
2595 DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n",
2596 (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
2597
2598 req->offset = poh->offset;
2599 req->size = poh->size;
2600 }
2601
2602}
2603
2604void XGI_free(unsigned long base)
2605{
2606 XGI_OH *poh;
2607
2608 poh = XGIfb_poh_free(base);
2609
2610 if(poh == NULL) {
2611 DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n",
2612 (unsigned int) base);
2613 }
2614}
2615
2616/* --------------------- SetMode routines ------------------------- */
2617
2618static void XGIfb_pre_setmode(void)
2619{
2620 u8 cr30 = 0, cr31 = 0;
2621
2622 inXGIIDXREG(XGICR, 0x31, cr31);
2623 cr31 &= ~0x60;
2624
2625 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2626 case DISPTYPE_CRT2:
2627 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2628 cr31 |= XGI_DRIVER_MODE;
2629 break;
2630 case DISPTYPE_LCD:
2631 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
2632 cr31 |= XGI_DRIVER_MODE;
2633 break;
2634 case DISPTYPE_TV:
2635 if (xgi_video_info.TV_type == TVMODE_HIVISION)
2636 cr30 = (XGI_VB_OUTPUT_HIVISION | XGI_SIMULTANEOUS_VIEW_ENABLE);
2637 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
2638 cr30 = (XGI_VB_OUTPUT_SVIDEO | XGI_SIMULTANEOUS_VIEW_ENABLE);
2639 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
2640 cr30 = (XGI_VB_OUTPUT_COMPOSITE | XGI_SIMULTANEOUS_VIEW_ENABLE);
2641 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
2642 cr30 = (XGI_VB_OUTPUT_SCART | XGI_SIMULTANEOUS_VIEW_ENABLE);
2643 cr31 |= XGI_DRIVER_MODE;
2644
2645 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
2646 cr31 |= 0x01;
2647 else
2648 cr31 &= ~0x01;
2649 break;
2650 default: /* disable CRT2 */
2651 cr30 = 0x00;
2652 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
2653 }
2654
2655 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
2656 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
2657 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
2658
2659 if(xgi_video_info.accel) XGIfb_syncaccel();
2660
2661
2662}
2663
2664static void XGIfb_post_setmode(void)
2665{
2666 u8 reg;
2667 BOOLEAN doit = TRUE;
2668#if 0 /* TW: Wrong: Is not in MMIO space, but in RAM */
2669 /* Backup mode number to MMIO space */
2670 if(xgi_video_info.mmio_vbase) {
2671 *(volatile u8 *)(((u8*)xgi_video_info.mmio_vbase) + 0x449) = (unsigned char)XGIfb_mode_no;
2672 }
2673#endif
2674/* outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
2675 outXGIIDXREG(XGICR,0x13,0x00);
2676 setXGIIDXREG(XGISR,0x0E,0xF0,0x01);
2677*test**/
2678 if (xgi_video_info.video_bpp == 8) {
2679 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
2680 if ((xgi_video_info.hasVB == HASVB_LVDS) || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
2681 doit = FALSE;
2682 }
2683 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
2684 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2685 doit = FALSE;
2686 }
2687 }
2688
2689 /* TW: We can't switch off CRT1 if bridge is in slave mode */
2690 if(xgi_video_info.hasVB != HASVB_NONE) {
2691 inXGIIDXREG(XGIPART1, 0x00, reg);
2692
2693
2694 if((reg & 0x50) == 0x10) {
2695 doit = FALSE;
2696 }
2697
2698 } else XGIfb_crt1off = 0;
2699
2700 inXGIIDXREG(XGICR, 0x17, reg);
2701 if((XGIfb_crt1off) && (doit))
2702 reg &= ~0x80;
2703 else
2704 reg |= 0x80;
2705 outXGIIDXREG(XGICR, 0x17, reg);
2706
2707 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
2708
2709 if((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB == HASVB_301)) {
2710
2711 inXGIIDXREG(XGIPART4, 0x01, reg);
2712
2713 if(reg < 0xB0) { /* Set filter for XGI301 */
2714
2715 switch (xgi_video_info.video_width) {
2716 case 320:
2717 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
2718 break;
2719 case 640:
2720 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
2721 break;
2722 case 720:
2723 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
2724 break;
2725 case 800:
2726 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
2727 break;
2728 default:
2729 filter = -1;
2730 break;
2731 }
2732
2733 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
2734
2735 if(xgi_video_info.TV_type == TVMODE_NTSC) {
2736
2737 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
2738
2739 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2740
2741 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
2742
2743 } else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE) {
2744
2745 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2746
2747 switch (xgi_video_info.video_width) {
2748 case 640:
2749 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2750 outXGIIDXREG(XGIPART2, 0x36, 0x04);
2751 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2752 outXGIIDXREG(XGIPART2, 0x38, 0x18);
2753 break;
2754 case 720:
2755 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
2756 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
2757 outXGIIDXREG(XGIPART2, 0x37, 0x22);
2758 outXGIIDXREG(XGIPART2, 0x38, 0x08);
2759 break;
2760 case 800:
2761 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2762 outXGIIDXREG(XGIPART2, 0x36, 0x15);
2763 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2764 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
2765 break;
2766 }
2767 }
2768
2769 } else if(xgi_video_info.TV_type == TVMODE_PAL) {
2770
2771 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2772
2773 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2774
2775 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2776
2777 } else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE) {
2778
2779 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2780
2781 switch (xgi_video_info.video_width) {
2782 case 640:
2783 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2784 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2785 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2786 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2787 break;
2788 case 720:
2789 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2790 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2791 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2792 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2793 break;
2794 case 800:
2795 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2796 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2797 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2798 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2799 break;
2800 }
2801 }
2802 }
2803
2804 if ((filter >= 0) && (filter <=7)) {
2805 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2806 XGI_TV_filter[filter_tb].filter[filter][0],
2807 XGI_TV_filter[filter_tb].filter[filter][1],
2808 XGI_TV_filter[filter_tb].filter[filter][2],
2809 XGI_TV_filter[filter_tb].filter[filter][3]
2810 );
2811 outXGIIDXREG(XGIPART2, 0x35, (XGI_TV_filter[filter_tb].filter[filter][0]));
2812 outXGIIDXREG(XGIPART2, 0x36, (XGI_TV_filter[filter_tb].filter[filter][1]));
2813 outXGIIDXREG(XGIPART2, 0x37, (XGI_TV_filter[filter_tb].filter[filter][2]));
2814 outXGIIDXREG(XGIPART2, 0x38, (XGI_TV_filter[filter_tb].filter[filter][3]));
2815 }
2816
2817 }
2818
2819 }
2820
2821}
2822
2823#ifndef MODULE
2824XGIINITSTATIC int __init XGIfb_setup(char *options)
2825{
2826 char *this_opt;
2827
2828
2829
2830 xgi_video_info.refresh_rate = 0;
2831
2832 printk(KERN_INFO "XGIfb: Options %s\n", options);
2833
2834 if (!options || !*options)
2835 return 0;
2836
2837 while((this_opt = strsep(&options, ",")) != NULL) {
2838
2839 if (!*this_opt) continue;
2840
2841 if (!strncmp(this_opt, "mode:", 5)) {
2842 XGIfb_search_mode(this_opt + 5);
2843 } else if (!strncmp(this_opt, "vesa:", 5)) {
2844 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2845 } else if (!strncmp(this_opt, "mode:", 5)) {
2846 XGIfb_search_mode(this_opt + 5);
2847 } else if (!strncmp(this_opt, "vesa:", 5)) {
2848 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2849 } else if (!strncmp(this_opt, "vrate:", 6)) {
2850 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2851 } else if (!strncmp(this_opt, "rate:", 5)) {
2852 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2853 } else if (!strncmp(this_opt, "off", 3)) {
2854 XGIfb_off = 1;
2855 } else if (!strncmp(this_opt, "crt1off", 7)) {
2856 XGIfb_crt1off = 1;
2857 } else if (!strncmp(this_opt, "filter:", 7)) {
2858 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2859 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2860 XGIfb_search_crt2type(this_opt + 14);
2861 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2862 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
2863 } else if (!strncmp(this_opt, "tvmode:",7)) {
2864 XGIfb_search_tvstd(this_opt + 7);
2865 } else if (!strncmp(this_opt, "tvstandard:",11)) {
2866 XGIfb_search_tvstd(this_opt + 7);
2867 } else if (!strncmp(this_opt, "mem:",4)) {
2868 XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
2869 } else if (!strncmp(this_opt, "dstn", 4)) {
2870 enable_dstn = 1;
2871 /* TW: DSTN overrules forcecrt2type */
2872 XGIfb_crt2type = DISPTYPE_LCD;
2873 } else if (!strncmp(this_opt, "queuemode:", 10)) {
2874 XGIfb_search_queuemode(this_opt + 10);
2875 } else if (!strncmp(this_opt, "pdc:", 4)) {
2876 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2877 if(XGIfb_pdc & ~0x3c) {
2878 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2879 XGIfb_pdc = 0;
2880 }
2881 } else if (!strncmp(this_opt, "noaccel", 7)) {
2882 XGIfb_accel = 0;
2883 } else if (!strncmp(this_opt, "noypan", 6)) {
2884 XGIfb_ypan = 0;
2885 } else if (!strncmp(this_opt, "userom:", 7)) {
2886 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
2887// } else if (!strncmp(this_opt, "useoem:", 7)) {
2888// XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
2889 } else {
2890 XGIfb_search_mode(this_opt);
2891// printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt);
2892 }
2893
2894 /* TW: Acceleration only with MMIO mode */
2895 if((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
2896 XGIfb_ypan = 0;
2897 XGIfb_accel = 0;
2898 }
2899 /* TW: Panning only with acceleration */
2900 if(XGIfb_accel == 0) XGIfb_ypan = 0;
2901
2902 }
2903 printk("\nxgifb: outa xgifb_setup 3450");
2904 return 0;
2905}
2906#endif
2907
2908static unsigned char VBIOS_BUF[65535];
2909
2910unsigned char* attempt_map_rom(struct pci_dev *dev,void *copy_address)
2911{
2912 u32 rom_size = 0;
2913 u32 rom_address = 0;
2914 int j;
2915
2916 /* Get the size of the expansion rom */
2917 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
2918 pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
2919 if ((rom_size & 0x01) == 0)
2920 {
2921 printk("No ROM\n");
2922 return NULL;
2923 }
2924
2925 rom_size &= 0xFFFFF800;
2926 rom_size = (~rom_size)+1;
2927
2928 rom_address = pci_resource_start(dev, 0);
2929 if (rom_address == 0 || rom_address == 0xFFFFFFF0)
2930 {
2931 printk("No suitable rom address found\n"); return NULL;
2932 }
2933
2934 printk("ROM Size is %dK, Address is %x\n", rom_size/1024, rom_address);
2935
2936 /* Map ROM */
2937 pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address | PCI_ROM_ADDRESS_ENABLE);
2938
2939 /* memcpy(copy_address, rom_address, rom_size); */
2940 {
2941 unsigned char *virt_addr = ioremap(rom_address, 0x8000000);
2942
2943 unsigned char *from = (unsigned char *)virt_addr;
2944 unsigned char *to = (unsigned char *)copy_address;
2945 for (j=0; j<65536 /*rom_size*/; j++) *to++ = *from++;
2946 }
2947
2948 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
2949
2950 printk("Copy is done\n");
2951
2952 return copy_address;
2953}
2954
2955int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2956{
2957 u16 reg16;
2958 u8 reg, reg1;
2959 u8 CR48,CR38;
2960 if (XGIfb_off)
2961 return -ENXIO;
2962
2963 XGIfb_registered = 0;
2964
2965 memset(&XGIhw_ext, 0, sizeof(HW_DEVICE_EXTENSION));
2966#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
2967 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2968 if(!fb_info) return -ENOMEM;
2969#else
2970 XGI_fb_info = kmalloc( sizeof(struct fb_info), GFP_KERNEL);
2971 if(!XGI_fb_info) return -ENOMEM;
2972 memset(XGI_fb_info, 0, sizeof(struct fb_info));
2973#endif
2974
2975 xgi_video_info.chip_id = pdev->device;
2976 pci_read_config_byte(pdev, PCI_REVISION_ID,&xgi_video_info.revision_id);
2977 pci_read_config_word(pdev, PCI_COMMAND, &reg16);
2978 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2979 XGIvga_enabled = reg16 & 0x01;
2980
2981 xgi_video_info.pcibus = pdev->bus->number;
2982 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2983 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2984 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2985 xgi_video_info.subsysdevice = pdev->subsystem_device;
2986
2987 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2988 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2989 XGIfb_mmio_size = pci_resource_len(pdev, 1);
2990 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2991 XGIhw_ext.pjIOAddress = (PUCHAR)xgi_video_info.vga_base;
2992 //XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30;
2993 printk("XGIfb: Relocate IO address: %lx [%08lx] \n", (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2994
2995 if (pci_enable_device(pdev))
2996 return -EIO;
2997
2998 XGIRegInit(&XGI_Pr, (ULONG)XGIhw_ext.pjIOAddress);
2999
3000 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3001 inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
3002
3003 if(reg1 != 0xa1) /*I/O error */
3004 {
3005 printk("\nXGIfb: I/O error!!!");
3006 return -EIO;
3007 }
3008
3009 switch (xgi_video_info.chip_id) {
3010 case PCI_DEVICE_ID_XG_20:
3011 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
3012 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
3013 if (CR48&GPIOG_READ)
3014 xgi_video_info.chip = XG21;
3015 else
3016 xgi_video_info.chip = XG20;
3017 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3018 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3019 break;
3020 case PCI_DEVICE_ID_XG_40:
3021 xgi_video_info.chip = XG40;
3022 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3023 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3024 break;
3025 case PCI_DEVICE_ID_XG_41:
3026 xgi_video_info.chip = XG41;
3027 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3028 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3029 break;
3030 case PCI_DEVICE_ID_XG_42:
3031 xgi_video_info.chip = XG42;
3032 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3033 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3034 break;
3035 case PCI_DEVICE_ID_XG_27:
3036 xgi_video_info.chip = XG27;
3037 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3038 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3039 break;
3040 default:
3041 return -ENODEV;
3042 }
3043
3044 printk("XGIfb:chipid = %x\n",xgi_video_info.chip);
3045 XGIhw_ext.jChipType = xgi_video_info.chip;
3046
3047 switch (xgi_video_info.chip) {
3048 case XG40:
3049 case XG41:
3050 case XG42:
3051 case XG45:
3052 case XG20:
3053 case XG21:
3054 case XG27:
3055 XGIhw_ext.bIntegratedMMEnabled = TRUE;
3056 break;
3057
3058 default:
3059 break;
3060 }
3061
3062
3063 XGIhw_ext.pDevice = NULL;
3064 if ((xgi_video_info.chip == XG21) || (XGIfb_userom))
3065 {
3066 XGIhw_ext.pjVirtualRomBase = attempt_map_rom(pdev, VBIOS_BUF);
3067
3068 if(XGIhw_ext.pjVirtualRomBase)
3069 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",XGIhw_ext.pjVirtualRomBase);
3070 else
3071 printk(KERN_INFO "XGIfb: Video ROM not found\n");
3072 } else {
3073 XGIhw_ext.pjVirtualRomBase = NULL;
3074 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
3075 }
3076 XGIhw_ext.pjCustomizedROMImage = NULL;
3077 XGIhw_ext.bSkipDramSizing = 0;
3078 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
3079// XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space;
3080 strcpy(XGIhw_ext.szVBIOSVer, "0.84");
3081
3082
3083 XGIhw_ext.pSR = vmalloc(sizeof(XGI_DSReg) * SR_BUFFER_SIZE);
3084 if (XGIhw_ext.pSR == NULL)
3085 {
3086 printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
3087 return -ENODEV;
3088 }
3089 XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
3090
3091 XGIhw_ext.pCR = vmalloc(sizeof(XGI_DSReg) * CR_BUFFER_SIZE);
3092 if (XGIhw_ext.pCR == NULL)
3093 {
3094 vfree(XGIhw_ext.pSR);
3095 printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n");
3096 return -ENODEV;
3097 }
3098 XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF;
3099
3100
3101
3102
3103 if (!XGIvga_enabled)
3104 {
3105 /* Mapping Max FB Size for 315 Init */
3106 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3107 if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
3108 {
3109#ifdef LINUXBIOS
3110 printk("XGIfb: XGIInit() ...");
3111 /* XGIInitNewt for LINUXBIOS only */
3112 if(XGIInitNew(&XGIhw_ext))
3113 {
3114 printk("OK\n");
3115 }
3116 else
3117 {
3118 printk("Fail\n");
3119 }
3120#endif
3121
3122 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3123
3124
3125 }
3126 }
3127#ifdef LINUXBIOS
3128 else
3129 {
3130 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3131 if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
3132 {
3133
3134 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3135
3136 // yilin Because no VBIOS DRAM Sizing, Dram size will error.
3137 // Set SR13 ,14 temporarily for UDtech
3138 outXGIIDXREG(XGISR, 0x13, 0x45);
3139 outXGIIDXREG(XGISR, 0x14, 0x51);
3140
3141
3142 }
3143 }
3144#endif
3145 if (XGIfb_get_dram_size())
3146 {
3147 vfree(XGIhw_ext.pSR);
3148 vfree(XGIhw_ext.pCR);
3149 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
3150 return -ENODEV;
3151 }
3152
3153
3154
3155 if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
3156 {
3157 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
3158 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
3159 /* Enable 2D accelerator engine */
3160 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
3161 }
3162
3163 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
3164
3165 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB"))
3166 { printk("unable request memory size %x",xgi_video_info.video_size);
3167 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
3168 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
3169 vfree(XGIhw_ext.pSR);
3170 vfree(XGIhw_ext.pCR);
3171 return -ENODEV;
3172 }
3173
3174 if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO"))
3175 {
3176 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
3177 release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size);
3178 vfree(XGIhw_ext.pSR);
3179 vfree(XGIhw_ext.pCR);
3180 return -ENODEV;
3181 }
3182
3183 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
3184 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
3185 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size);
3186
3187 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
3188 xgi_video_info.video_base, xgi_video_info.video_vbase,xgi_video_info.video_size / 1024);
3189
3190 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
3191 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,XGIfb_mmio_size / 1024);
3192 printk("XGIfb: XGIInitNew() ...");
3193 if(XGIInitNew(&XGIhw_ext))
3194 {
3195 printk("OK\n");
3196 }
3197 else
3198 {
3199 printk("Fail\n");
3200 }
3201
3202 if(XGIfb_heap_init())
3203 {
3204 printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
3205 }
3206
3207
3208 xgi_video_info.mtrr = (unsigned int) 0;
3209
3210 if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
3211 {
3212 xgi_video_info.hasVB = HASVB_NONE;
3213 if((xgi_video_info.chip == XG20)||(xgi_video_info.chip == XG27))
3214 xgi_video_info.hasVB = HASVB_NONE;
3215 else if(xgi_video_info.chip == XG21) {
3216 inXGIIDXREG(XGICR,0x38,CR38);
3217 if ((CR38&0xE0) == 0xC0) {
3218 xgi_video_info.disp_state = DISPTYPE_LCD;
3219 if (!XGIfb_GetXG21LVDSData()) {
3220 int m;
3221 for (m=0; m < sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct); m++) {
3222 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
3223 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
3224 XGINew_SetReg1( XGI_Pr.P3d4 , 0x36, m) ;
3225 }
3226 }
3227 }
3228 }
3229 else if ((CR38&0xE0) == 0x60)
3230 xgi_video_info.hasVB = HASVB_CHRONTEL ;
3231 else
3232 xgi_video_info.hasVB = HASVB_NONE;
3233 }
3234 else
3235 XGIfb_get_VB_type();
3236
3237 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
3238
3239 XGIhw_ext.ulExternalChip = 0;
3240
3241 switch (xgi_video_info.hasVB) {
3242 case HASVB_301:
3243 inXGIIDXREG(XGIPART4, 0x01, reg);
3244 if (reg >= 0xE0) {
3245 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3246 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
3247 } else if (reg >= 0xD0) {
3248 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3249 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n",reg);
3250 }
3251 /* else if (reg >= 0xB0) {
3252 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
3253 inXGIIDXREG(XGIPART4,0x23,reg1);
3254 printk("XGIfb: XGI301B bridge detected\n");
3255 }*/
3256 else {
3257 XGIhw_ext.ujVBChipID = VB_CHIP_301;
3258 printk("XGIfb: XGI301 bridge detected\n");
3259 }
3260 break;
3261 case HASVB_302:
3262 inXGIIDXREG(XGIPART4, 0x01, reg);
3263 if (reg >= 0xE0) {
3264 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3265 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
3266 } else if (reg >= 0xD0) {
3267 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3268 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
3269 } else if (reg >= 0xB0) {
3270 inXGIIDXREG(XGIPART4,0x23,reg1);
3271
3272 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
3273
3274 } else {
3275 XGIhw_ext.ujVBChipID = VB_CHIP_302;
3276 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
3277 }
3278 break;
3279 case HASVB_LVDS:
3280 XGIhw_ext.ulExternalChip = 0x1;
3281 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
3282 break;
3283 case HASVB_TRUMPION:
3284 XGIhw_ext.ulExternalChip = 0x2;
3285 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
3286 break;
3287 case HASVB_CHRONTEL:
3288 XGIhw_ext.ulExternalChip = 0x4;
3289 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
3290 break;
3291 case HASVB_LVDS_CHRONTEL:
3292 XGIhw_ext.ulExternalChip = 0x5;
3293 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
3294 break;
3295 default:
3296 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
3297 break;
3298 }
3299
3300 if (xgi_video_info.hasVB != HASVB_NONE) {
3301 XGIfb_detect_VB();
3302 }
3303
3304 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3305 if (XGIfb_crt1off)
3306 xgi_video_info.disp_state |= DISPMODE_SINGLE;
3307 else
3308 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
3309 } else {
3310 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
3311 }
3312
3313 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
3314 if (!enable_dstn) {
3315 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
3316 reg &= 0x0f;
3317 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
3318
3319 } else {
3320 // TW: FSTN/DSTN
3321 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
3322 }
3323 }
3324
3325 XGIfb_detectedpdc = 0;
3326
3327 XGIfb_detectedlcda = 0xff;
3328#ifndef LINUXBIOS
3329
3330 /* TW: Try to find about LCDA */
3331
3332 if((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
3333 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
3334 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV))
3335 {
3336 int tmp;
3337 inXGIIDXREG(XGICR,0x34,tmp);
3338 if(tmp <= 0x13)
3339 {
3340 // Currently on LCDA? (Some BIOSes leave CR38)
3341 inXGIIDXREG(XGICR,0x38,tmp);
3342 if((tmp & 0x03) == 0x03)
3343 {
3344// XGI_Pr.XGI_UseLCDA = TRUE;
3345 }else
3346 {
3347 // Currently on LCDA? (Some newer BIOSes set D0 in CR35)
3348 inXGIIDXREG(XGICR,0x35,tmp);
3349 if(tmp & 0x01)
3350 {
3351// XGI_Pr.XGI_UseLCDA = TRUE;
3352 }else
3353 {
3354 inXGIIDXREG(XGICR,0x30,tmp);
3355 if(tmp & 0x20)
3356 {
3357 inXGIIDXREG(XGIPART1,0x13,tmp);
3358 if(tmp & 0x04)
3359 {
3360// XGI_Pr.XGI_UseLCDA = TRUE;
3361 }
3362 }
3363 }
3364 }
3365 }
3366
3367 }
3368
3369
3370#endif
3371
3372 if (xgifb_mode_idx >= 0)
3373 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
3374
3375 if (xgifb_mode_idx < 0) {
3376 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3377 case DISPTYPE_LCD:
3378 xgifb_mode_idx = DEFAULT_LCDMODE;
3379 if (xgi_video_info.chip == XG21)
3380 {
3381 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
3382 }
3383 break;
3384 case DISPTYPE_TV:
3385 xgifb_mode_idx = DEFAULT_TVMODE;
3386 break;
3387 default:
3388 xgifb_mode_idx = DEFAULT_MODE;
3389 break;
3390 }
3391 }
3392
3393 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
3394
3395
3396 if( xgi_video_info.refresh_rate == 0)
3397 xgi_video_info.refresh_rate = 60; /*yilin set default refresh rate */
3398 if(XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0)
3399 {
3400 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
3401 xgi_video_info.refresh_rate = 60;
3402 }
3403
3404 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
3405 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
3406 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
3407 xgi_video_info.org_x = xgi_video_info.org_y = 0;
3408 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
3409 switch(xgi_video_info.video_bpp) {
3410 case 8:
3411 xgi_video_info.DstColor = 0x0000;
3412 xgi_video_info.XGI310_AccelDepth = 0x00000000;
3413 xgi_video_info.video_cmap_len = 256;
3414 break;
3415 case 16:
3416 xgi_video_info.DstColor = 0x8000;
3417 xgi_video_info.XGI310_AccelDepth = 0x00010000;
3418 xgi_video_info.video_cmap_len = 16;
3419 break;
3420 case 32:
3421 xgi_video_info.DstColor = 0xC000;
3422 xgi_video_info.XGI310_AccelDepth = 0x00020000;
3423 xgi_video_info.video_cmap_len = 16;
3424 break;
3425 default:
3426 xgi_video_info.video_cmap_len = 16;
3427 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
3428 break;
3429 }
3430
3431
3432
3433 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
3434 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
3435 xgi_video_info.refresh_rate);
3436
3437 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
3438 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
3439 default_var.bits_per_pixel = xgi_video_info.video_bpp;
3440
3441 XGIfb_bpp_to_var(&default_var);
3442
3443 default_var.pixclock = (u32) (1000000000 /
3444 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
3445 XGIfb_mode_no, XGIfb_rate_idx));
3446
3447 if(XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
3448 XGIfb_mode_no, XGIfb_rate_idx,
3449 &default_var.left_margin, &default_var.right_margin,
3450 &default_var.upper_margin, &default_var.lower_margin,
3451 &default_var.hsync_len, &default_var.vsync_len,
3452 &default_var.sync, &default_var.vmode)) {
3453
3454 if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
3455 default_var.yres <<= 1;
3456 default_var.yres_virtual <<= 1;
3457 } else if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
3458 default_var.pixclock >>= 1;
3459 default_var.yres >>= 1;
3460 default_var.yres_virtual >>= 1;
3461 }
3462
3463 }
3464
3465
3466#if 0
3467#ifdef XGIFB_PAN
3468 if(XGIfb_ypan) {
3469 default_var.yres_virtual =
3470 xgi_video_info.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
3471 if(default_var.yres_virtual <= default_var.yres) {
3472 default_var.yres_virtual = default_var.yres;
3473 }
3474 }
3475#endif
3476#endif
3477
3478
3479 xgi_video_info.accel = 0;
3480 if(XGIfb_accel) {
3481 xgi_video_info.accel = -1;
3482 default_var.accel_flags |= FB_ACCELF_TEXT;
3483 XGIfb_initaccel();
3484 }
3485
3486 fb_info->flags = FBINFO_FLAG_DEFAULT;
3487 fb_info->var = default_var;
3488 fb_info->fix = XGIfb_fix;
3489 fb_info->par = &xgi_video_info;
3490 fb_info->screen_base = xgi_video_info.video_vbase;
3491 fb_info->fbops = &XGIfb_ops;
3492 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
3493 fb_info->pseudo_palette = pseudo_palette;
3494
3495 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
3496
3497
3498#ifdef CONFIG_MTRR
3499 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
3500 (unsigned int) xgi_video_info.video_size,
3501 MTRR_TYPE_WRCOMB, 1);
3502 if(xgi_video_info.mtrr) {
3503 printk(KERN_INFO "XGIfb: Added MTRRs\n");
3504 }
3505#endif
3506
3507 if(register_framebuffer(fb_info) < 0)
3508 {
3509 return -EINVAL;
3510 }
3511
3512 XGIfb_registered = 1;
3513
3514 printk(KERN_INFO "XGIfb: Installed XGIFB_GET_INFO ioctl (%x)\n", XGIFB_GET_INFO);
3515
3516/* printk(KERN_INFO "XGIfb: 2D acceleration is %s, scrolling mode %s\n",
3517 XGIfb_accel ? "enabled" : "disabled",
3518 XGIfb_ypan ? "ypan" : "redraw");
3519*/
3520 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
3521 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
3522
3523
3524 }
3525
3526 dumpVGAReg();
3527
3528 return 0;
3529}
3530
3531
3532/*****************************************************/
3533/* PCI DEVICE HANDLING */
3534/*****************************************************/
3535
3536static void __devexit xgifb_remove(struct pci_dev *pdev)
3537{
3538 /* Unregister the framebuffer */
3539// if(xgi_video_info.registered) {
3540 unregister_framebuffer(fb_info);
3541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
3542 framebuffer_release(fb_info);
3543#else
3544 kfree(fb_info);
3545#endif
3546// }
3547
3548 pci_set_drvdata(pdev, NULL);
3549
3550};
3551
3552static struct pci_driver xgifb_driver = {
3553 .name = "xgifb",
3554 .id_table = xgifb_pci_table,
3555 .probe = xgifb_probe,
3556 .remove = __devexit_p(xgifb_remove)
3557};
3558
3559XGIINITSTATIC int __init xgifb_init(void)
3560{
3561#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
3562#ifndef MODULE
3563 char *option = NULL;
3564
3565 if (fb_get_options("xgifb", &option))
3566 return -ENODEV;
3567 XGIfb_setup(option);
3568#endif
3569#endif
3570 return(pci_register_driver(&xgifb_driver));
3571}
3572
3573#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
3574#ifndef MODULE
3575module_init(xgifb_init);
3576#endif
3577#endif
3578
3579/*****************************************************/
3580/* MODULE */
3581/*****************************************************/
3582
3583#ifdef MODULE
3584
3585static char *mode = NULL;
3586static int vesa = 0;
3587static unsigned int rate = 0;
3588static unsigned int crt1off = 1;
3589static unsigned int mem = 0;
3590static char *forcecrt2type = NULL;
3591static int forcecrt1 = -1;
3592static int pdc = -1;
3593static int pdc1 = -1;
3594static int noaccel = -1;
3595static int noypan = -1;
3596static int nomax = -1;
3597static int userom = -1;
3598static int useoem = -1;
3599static char *tvstandard = NULL;
3600static int nocrt2rate = 0;
3601static int scalelcd = -1;
3602static char *specialtiming = NULL;
3603static int lvdshl = -1;
3604static int tvxposoffset = 0, tvyposoffset = 0;
3605#if !defined(__i386__) && !defined(__x86_64__)
3606static int resetcard = 0;
3607static int videoram = 0;
3608#endif
3609
3610MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
3611MODULE_LICENSE("GPL");
3612MODULE_AUTHOR("XGITECH , Others");
3613
3614
3615
3616module_param(mem, int, 0);
3617module_param(noaccel, int, 0);
3618module_param(noypan, int, 0);
3619module_param(nomax, int, 0);
3620module_param(userom, int, 0);
3621module_param(useoem, int, 0);
3622module_param(mode, charp, 0);
3623module_param(vesa, int, 0);
3624module_param(rate, int, 0);
3625module_param(forcecrt1, int, 0);
3626module_param(forcecrt2type, charp, 0);
3627module_param(scalelcd, int, 0);
3628module_param(pdc, int, 0);
3629module_param(pdc1, int, 0);
3630module_param(specialtiming, charp, 0);
3631module_param(lvdshl, int, 0);
3632module_param(tvstandard, charp, 0);
3633module_param(tvxposoffset, int, 0);
3634module_param(tvyposoffset, int, 0);
3635module_param(filter, int, 0);
3636module_param(nocrt2rate, int, 0);
3637#if !defined(__i386__) && !defined(__x86_64__)
3638module_param(resetcard, int, 0);
3639module_param(videoram, int, 0);
3640#endif
3641
3642
3643MODULE_PARM_DESC(mem,
3644 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
3645 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
3646 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
3647 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
3648 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
3649 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
3650 "for XFree86 4.x/X.org 6.7 and later.\n");
3651
3652MODULE_PARM_DESC(noaccel,
3653 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
3654 "(default: 0)\n");
3655
3656MODULE_PARM_DESC(noypan,
3657 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
3658 "will be performed by redrawing the screen. (default: 0)\n");
3659
3660MODULE_PARM_DESC(nomax,
3661 "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
3662 "memory for the virtual screen in order to optimize scrolling performance. If\n"
3663 "this is set to anything other than 0, xgifb will not do this and thereby \n"
3664 "enable the user to positively specify a virtual Y size of the screen using\n"
3665 "fbset. (default: 0)\n");
3666
3667
3668
3669MODULE_PARM_DESC(mode,
3670 "\nSelects the desired default display mode in the format XxYxDepth,\n"
3671 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
3672 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
3673 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
3674
3675MODULE_PARM_DESC(vesa,
3676 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
3677 "0x117 (default: 0x0103)\n");
3678
3679
3680MODULE_PARM_DESC(rate,
3681 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
3682 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
3683 "will be ignored (default: 60)\n");
3684
3685MODULE_PARM_DESC(forcecrt1,
3686 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
3687 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
3688 "0=CRT1 OFF) (default: [autodetected])\n");
3689
3690MODULE_PARM_DESC(forcecrt2type,
3691 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
3692 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
3693 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
3694 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
3695 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
3696 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
3697 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
3698 "depends on the very hardware in use. (default: [autodetected])\n");
3699
3700MODULE_PARM_DESC(scalelcd,
3701 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
3702 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
3703 "show black bars around the image, TMDS panels will probably do the scaling\n"
3704 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
3705
3706MODULE_PARM_DESC(pdc,
3707 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
3708 "should detect this correctly in most cases; however, sometimes this is not\n"
3709 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
3710 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
3711 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
3712 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
3713
3714MODULE_PARM_DESC(pdc1,
3715 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
3716 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
3717 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
3718 "implemented yet.\n");
3719
3720MODULE_PARM_DESC(specialtiming,
3721 "\nPlease refer to documentation for more information on this option.\n");
3722
3723MODULE_PARM_DESC(lvdshl,
3724 "\nPlease refer to documentation for more information on this option.\n");
3725
3726MODULE_PARM_DESC(tvstandard,
3727 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
3728 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
3729
3730MODULE_PARM_DESC(tvxposoffset,
3731 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
3732 "Default: 0\n");
3733
3734MODULE_PARM_DESC(tvyposoffset,
3735 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
3736 "Default: 0\n");
3737
3738MODULE_PARM_DESC(filter,
3739 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
3740 "(Possible values 0-7, default: [no filter])\n");
3741
3742MODULE_PARM_DESC(nocrt2rate,
3743 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
3744 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
3745
3746
3747
3748
3749int __init xgifb_init_module(void)
3750{
3751 printk("\nXGIfb_init_module");
3752 if(mode)
3753 XGIfb_search_mode(mode);
3754 else if (vesa != -1)
3755 XGIfb_search_vesamode(vesa);
3756
3757 return(xgifb_init());
3758}
3759
3760static void __exit xgifb_remove_module(void)
3761{
3762 pci_unregister_driver(&xgifb_driver);
3763 printk(KERN_DEBUG "xgifb: Module unloaded\n");
3764}
3765
3766module_init(xgifb_init_module);
3767module_exit(xgifb_remove_module);
3768
3769#endif /* /MODULE */
3770
3771EXPORT_SYMBOL(XGI_malloc);
3772EXPORT_SYMBOL(XGI_free);
3773
diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h
new file mode 100644
index 000000000000..41bf163d4e6b
--- /dev/null
+++ b/drivers/staging/xgifb/XGIfb.h
@@ -0,0 +1,215 @@
1#ifndef _LINUX_XGIFB
2#define _LINUX_XGIFB
3#include <linux/spinlock.h>
4#include <asm/ioctl.h>
5#include <asm/types.h>
6
7#define DISPTYPE_CRT1 0x00000008L
8#define DISPTYPE_CRT2 0x00000004L
9#define DISPTYPE_LCD 0x00000002L
10#define DISPTYPE_TV 0x00000001L
11#define DISPTYPE_DISP1 DISPTYPE_CRT1
12#define DISPTYPE_DISP2 (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
13#define DISPMODE_SINGLE 0x00000020L
14#define DISPMODE_MIRROR 0x00000010L
15#define DISPMODE_DUALVIEW 0x00000040L
16
17#define HASVB_NONE 0x00
18#define HASVB_301 0x01
19#define HASVB_LVDS 0x02
20#define HASVB_TRUMPION 0x04
21#define HASVB_LVDS_CHRONTEL 0x10
22#define HASVB_302 0x20
23#define HASVB_303 0x40
24#define HASVB_CHRONTEL 0x80
25
26#ifndef XGIFB_ID
27#define XGIFB_ID 0x53495346 /* Identify myself with 'XGIF' */
28#endif
29
30typedef enum _XGI_CHIP_TYPE {
31 XGI_VGALegacy = 0,
32 XGI_300,
33 XGI_630,
34 XGI_730,
35 XGI_540,
36 XGI_315H,
37 XGI_315,
38 XGI_315PRO,
39 XGI_550,
40 XGI_640,
41 XGI_740,
42 XGI_650,
43 XGI_650M,
44 XGI_330 = 16,
45 XGI_660,
46 XGI_661,
47 XGI_760,
48 XG40 = 32,
49 XG41,
50 XG42,
51 XG45,
52 XG20 = 48,
53 XG21,
54 XG27,
55 MAX_XGI_CHIP
56} XGI_CHIP_TYPE;
57
58typedef enum _TVTYPE {
59 TVMODE_NTSC = 0,
60 TVMODE_PAL,
61 TVMODE_HIVISION,
62 TVTYPE_PALM, // vicki@030226
63 TVTYPE_PALN, // vicki@030226
64 TVTYPE_NTSCJ, // vicki@030226
65 TVMODE_TOTAL
66} XGI_TV_TYPE;
67
68
69typedef struct _XGIFB_INFO XGIfb_info;
70struct _XGIFB_INFO {
71
72unsigned long XGIfb_id;
73 int chip_id; /* PCI ID of detected chip */
74 int memory; /* video memory in KB which XGIfb manages */
75 int heapstart; /* heap start (= XGIfb "mem" argument) in KB */
76 unsigned char fbvidmode; /* current XGIfb mode */
77
78 unsigned char XGIfb_version;
79 unsigned char XGIfb_revision;
80 unsigned char XGIfb_patchlevel;
81
82 unsigned char XGIfb_caps; /* XGIfb capabilities */
83
84 int XGIfb_tqlen; /* turbo queue length (in KB) */
85
86 unsigned int XGIfb_pcibus; /* The card's PCI ID */
87 unsigned int XGIfb_pcislot;
88 unsigned int XGIfb_pcifunc;
89
90 unsigned char XGIfb_lcdpdc; /* PanelDelayCompensation */
91
92 unsigned char XGIfb_lcda; /* Detected status of LCDA for low res/text modes */
93
94 char reserved[235]; /* for future use */
95};
96
97
98
99
100typedef enum _TVPLUGTYPE { // vicki@030226
101// TVPLUG_Legacy = 0,
102// TVPLUG_COMPOSITE,
103// TVPLUG_SVIDEO,
104// TVPLUG_SCART,
105// TVPLUG_TOTAL
106 TVPLUG_UNKNOWN = 0,
107 TVPLUG_COMPOSITE = 1,
108 TVPLUG_SVIDEO = 2,
109 TVPLUG_COMPOSITE_AND_SVIDEO = 3,
110 TVPLUG_SCART = 4,
111 TVPLUG_YPBPR_525i = 5,
112 TVPLUG_YPBPR_525P = 6,
113 TVPLUG_YPBPR_750P = 7,
114 TVPLUG_YPBPR_1080i = 8,
115 TVPLUG_TOTAL
116} XGI_TV_PLUG;
117
118
119struct mode_info {
120 int bpp;
121 int xres;
122 int yres;
123 int v_xres;
124 int v_yres;
125 int org_x;
126 int org_y;
127 unsigned int vrate;
128};
129
130struct ap_data {
131 struct mode_info minfo;
132 unsigned long iobase;
133 unsigned int mem_size;
134 unsigned long disp_state;
135 XGI_CHIP_TYPE chip;
136 unsigned char hasVB;
137 XGI_TV_TYPE TV_type;
138 XGI_TV_PLUG TV_plug;
139 unsigned long version;
140 char reserved[256];
141};
142
143
144
145/* If changing this, vgatypes.h must also be changed (for X driver) */
146
147
148/*
149 * NOTE! The ioctl types used to be "size_t" by mistake, but were
150 * really meant to be __u32. Changed to "__u32" even though that
151 * changes the value on 64-bit architectures, because the value
152 * (with a 4-byte size) is also hardwired in vgatypes.h for user
153 * space exports. So "__u32" is actually more compatible, duh!
154 */
155#define XGIFB_GET_INFO _IOR('n',0xF8,__u32)
156#define XGIFB_GET_VBRSTATUS _IOR('n',0xF9,__u32)
157
158
159
160struct video_info{
161 int chip_id;
162 unsigned int video_size;
163 unsigned long video_base;
164 char * video_vbase;
165 unsigned long mmio_base;
166 char * mmio_vbase;
167 unsigned long vga_base;
168 unsigned long mtrr;
169 unsigned long heapstart;
170
171 int video_bpp;
172 int video_cmap_len;
173 int video_width;
174 int video_height;
175 int video_vwidth;
176 int video_vheight;
177 int org_x;
178 int org_y;
179 int video_linelength;
180 unsigned int refresh_rate;
181
182 unsigned long disp_state;
183 unsigned char hasVB;
184 unsigned char TV_type;
185 unsigned char TV_plug;
186
187 XGI_CHIP_TYPE chip;
188 unsigned char revision_id;
189
190 unsigned short DstColor;
191 unsigned long XGI310_AccelDepth;
192 unsigned long CommandReg;
193
194 spinlock_t lockaccel;
195
196 unsigned int pcibus;
197 unsigned int pcislot;
198 unsigned int pcifunc;
199
200 int accel;
201 unsigned short subsysvendor;
202 unsigned short subsysdevice;
203
204 char reserved[236];
205};
206
207
208extern struct video_info xgi_video_info;
209
210#ifdef __KERNEL__
211//extern void xgi_malloc(struct xgi_memreq *req);
212extern void xgi_free(unsigned long base);
213extern void xgi_dispinfo(struct ap_data *rec);
214#endif
215#endif
diff --git a/drivers/staging/xgifb/osdef.h b/drivers/staging/xgifb/osdef.h
new file mode 100644
index 000000000000..4bc7d3a7440c
--- /dev/null
+++ b/drivers/staging/xgifb/osdef.h
@@ -0,0 +1,153 @@
1#ifndef _OSDEF_H_
2#define _OSDEF_H_
3
4/* #define WINCE_HEADER*/
5/*#define WIN2000*/
6/* #define TC */
7#define LINUX_KERNEL
8/* #define LINUX_XF86 */
9
10/**********************************************************************/
11#ifdef LINUX_KERNEL
12//#include <linux/config.h>
13#endif
14
15
16/**********************************************************************/
17#ifdef TC
18#endif
19#ifdef WIN2000
20#endif
21#ifdef WINCE_HEADER
22#endif
23#ifdef LINUX_XF86
24#define LINUX
25#endif
26#ifdef LINUX_KERNEL
27#define LINUX
28#endif
29
30/**********************************************************************/
31#ifdef TC
32#define XGI_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
33#endif
34#ifdef WIN2000
35#define XGI_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
36#endif
37#ifdef WINCE_HEADER
38#define XGI_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
39#endif
40#ifdef LINUX_XF86
41#define XGI_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
42#endif
43#ifdef LINUX_KERNEL
44#define XGI_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
45#endif
46/**********************************************************************/
47
48/**********************************************************************/
49
50#ifdef TC
51#define XGI_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
52#endif
53#ifdef WIN2000
54#define XGI_MemoryCopy(Destination,Soruce,Length) /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
55#endif
56#ifdef WINCE_HEADER
57#define XGI_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
58#endif
59#ifdef LINUX_XF86
60#define XGI_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
61#endif
62#ifdef LINUX_KERNEL
63#define XGI_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
64#endif
65
66/**********************************************************************/
67
68#ifdef OutPortByte
69#undef OutPortByte
70#endif /* OutPortByte */
71
72#ifdef OutPortWord
73#undef OutPortWord
74#endif /* OutPortWord */
75
76#ifdef OutPortLong
77#undef OutPortLong
78#endif /* OutPortLong */
79
80#ifdef InPortByte
81#undef InPortByte
82#endif /* InPortByte */
83
84#ifdef InPortWord
85#undef InPortWord
86#endif /* InPortWord */
87
88#ifdef InPortLong
89#undef InPortLong
90#endif /* InPortLong */
91
92/**********************************************************************/
93/* TC */
94/**********************************************************************/
95
96#ifdef TC
97#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
98#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
99#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
100#define InPortByte(p) inp((unsigned short)(p))
101#define InPortWord(p) inp((unsigned short)(p))
102#define InPortLong(p) ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
103#endif
104
105/**********************************************************************/
106/* LINUX XF86 */
107/**********************************************************************/
108
109#ifdef LINUX_XF86
110#define OutPortByte(p,v) outb((CARD16)(p),(CARD8)(v))
111#define OutPortWord(p,v) outw((CARD16)(p),(CARD16)(v))
112#define OutPortLong(p,v) outl((CARD16)(p),(CARD32)(v))
113#define InPortByte(p) inb((CARD16)(p))
114#define InPortWord(p) inw((CARD16)(p))
115#define InPortLong(p) inl((CARD16)(p))
116#endif
117
118#ifdef LINUX_KERNEL
119#define OutPortByte(p,v) outb((u8)(v),(p))
120#define OutPortWord(p,v) outw((u16)(v),(p))
121#define OutPortLong(p,v) outl((u32)(v),(p))
122#define InPortByte(p) inb(p)
123#define InPortWord(p) inw(p)
124#define InPortLong(p) inl(p)
125#endif
126
127/**********************************************************************/
128/* WIN 2000 */
129/**********************************************************************/
130
131#ifdef WIN2000
132#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
133#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
134#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
135#define InPortByte(p) VideoPortReadPortUchar ((PUCHAR) (p))
136#define InPortWord(p) VideoPortReadPortUshort ((PUSHORT) (p))
137#define InPortLong(p) VideoPortReadPortUlong ((PULONG) (p))
138#endif
139
140
141/**********************************************************************/
142/* WIN CE */
143/**********************************************************************/
144
145#ifdef WINCE_HEADER
146#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
147#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
148#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
149#define InPortByte(p) READ_PORT_UCHAR ((PUCHAR) (p))
150#define InPortWord(p) READ_PORT_USHORT ((PUSHORT) (p))
151#define InPortLong(p) READ_PORT_ULONG ((PULONG) (p))
152#endif
153#endif // _OSDEF_H_
diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h
new file mode 100644
index 000000000000..17a7ada4926e
--- /dev/null
+++ b/drivers/staging/xgifb/vb_def.h
@@ -0,0 +1,1017 @@
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/xgi/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
2#ifndef _INITDEF_
3#define _INITDEF_
4
5#ifndef NewScratch
6#define NewScratch
7#endif
8/* shampoo */
9#ifdef LINUX_KERNEL
10#define SEQ_ADDRESS_PORT 0x0014
11#define SEQ_DATA_PORT 0x0015
12#define MISC_OUTPUT_REG_READ_PORT 0x001C
13#define MISC_OUTPUT_REG_WRITE_PORT 0x0012
14#define GRAPH_DATA_PORT 0x1F
15#define GRAPH_ADDRESS_PORT 0x1E
16#define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */
17#define CRTC_ADDRESS_PORT_COLOR 0x0024
18#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013
19#define PCI_COMMAND 0x04
20#endif
21/* ~shampoo */
22
23
24#define VB_XGI301 0x0001 /*301b*/
25#define VB_XGI301B 0x0002
26#define VB_XGI302B 0x0004
27#define VB_XGI301LV 0x0008 /*301lv*/
28#define VB_XGI302LV 0x0010
29#define VB_XGI301C 0x0020 /* for 301C */
30#define VB_NoLCD 0x8000
31/*end 301b*/
32
33#define VB_YPbPrInfo 0x07 /*301lv*/
34#define VB_YPbPr525i 0x00
35#define VB_YPbPr525p 0x01
36#define VB_YPbPr750p 0x02
37#define VB_YPbPr1080i 0x03
38
39/* #define CRT1Len 17 */
40#define LVDSCRT1Len 15
41#define CHTVRegDataLen 5
42
43/* #define ModeInfoFlag 0x07 */
44/* #define IsTextMode 0x07 */
45/* #define ModeText 0x00 */
46/* #define ModeCGA 0x01 */
47/* #define ModeEGA 0x02 */
48/* #define ModeVGA 0x03 */
49/* #define Mode15Bpp 0x04 */
50/* #define Mode16Bpp 0x05 */
51/* #define Mode24Bpp 0x06 */
52/* #define Mode32Bpp 0x07 */
53
54/* #define DACInfoFlag 0x18 */
55/* #define MemoryInfoFlag 0x1E0 */
56/* #define MemorySizeShift 0x05 */
57
58#define Charx8Dot 0x0200
59#define LineCompareOff 0x0400
60#define CRT2Mode 0x0800
61#define HalfDCLK 0x1000
62#define NoSupportSimuTV 0x2000
63#define DoubleScanMode 0x8000
64
65#define SupportAllCRT2 0x0078
66#define SupportTV 0x0008
67#define SupportHiVisionTV 0x0010
68#define SupportLCD 0x0020
69#define SupportRAMDAC2 0x0040
70#define NoSupportTV 0x0070
71#define NoSupportHiVisionTV 0x0060
72#define NoSupportLCD 0x0058
73#define SupportCHTV 0x0800
74#define SupportCRT2in301C 0x0100 /* for 301C */
75#define SupportTV1024 0x0800 /*301b*/
76#define SupportYPbPr 0x1000 /*301lv*/
77#define InterlaceMode 0x0080
78#define SyncPP 0x0000
79#define SyncPN 0x4000
80#define SyncNP 0x8000
81/* #define SyncNN 0xc000 */
82#define ECLKindex0 0x0000
83#define ECLKindex1 0x0100
84#define ECLKindex2 0x0200
85#define ECLKindex3 0x0300
86#define ECLKindex4 0x0400
87
88#define SetSimuScanMode 0x0001
89#define SwitchToCRT2 0x0002
90/* #define SetCRT2ToTV 0x009C */
91#define SetCRT2ToAVIDEO 0x0004
92#define SetCRT2ToSVIDEO 0x0008
93#define SetCRT2ToSCART 0x0010
94#define SetCRT2ToLCD 0x0020
95#define SetCRT2ToRAMDAC 0x0040
96#define SetCRT2ToHiVisionTV 0x0080
97#define SetNTSCTV 0x0000
98/* #define SetPALTV 0x0100 */
99#define SetInSlaveMode 0x0200
100#define SetNotSimuMode 0x0400
101#define SetNotSimuTVMode 0x0400
102#define SetDispDevSwitch 0x0800
103#define LoadDACFlag 0x1000
104#define DisableCRT2Display 0x2000
105#define DriverMode 0x4000
106#define HotKeySwitch 0x8000
107#define SetCHTVOverScan 0x8000
108/* #define SetCRT2ToLCDA 0x8000 301b */
109#define PanelRGB18Bit 0x0100
110#define PanelRGB24Bit 0x0000
111
112#define TVOverScan 0x10
113#define TVOverScanShift 4
114#define ClearBufferFlag 0x20
115#define EnableDualEdge 0x01 /*301b*/
116#define SetToLCDA 0x02
117
118#define YPbPrModeInfo 0x38
119/* #define YPbPrMode525i 0x00 */
120/* #define YPbPrMode525p 0x08 */
121/* #define YPbPrMode750p 0x10 */
122/* #define YPbPrMode1080i 0x18 */
123
124#define SetSCARTOutput 0x01
125#define BoardTVType 0x02
126#define EnablePALMN 0x40
127/* #define ProgrammingCRT2 0x01 */
128/* #define TVSimuMode 0x02 */
129/* #define RPLLDIV2XO 0x04 */
130/* #define LCDVESATiming 0x08 */
131/* #define EnableLVDSDDA 0x10 */
132#define SetDispDevSwitchFlag 0x20
133#define CheckWinDos 0x40
134#define SetJDOSMode 0x80
135
136#define Panel320x480 0x07/*fstn*/
137/* [ycchen] 02/12/03 Modify for Multi-Sync. LCD Support */
138#define PanelResInfo 0x1F /* CR36 Panel Type/LCDResInfo */
139#define PanelRefInfo 0x60
140#define Panel800x600 0x01
141#define Panel1024x768 0x02
142#define Panel1024x768x75 0x22
143#define Panel1280x1024 0x03
144#define Panel1280x1024x75 0x23
145#define Panel640x480 0x04
146#define Panel1024x600 0x05
147#define Panel1152x864 0x06
148#define Panel1280x960 0x07
149#define Panel1152x768 0x08
150#define Panel1400x1050 0x09
151#define Panel1280x768 0x0A
152#define Panel1600x1200 0x0B
153
154#define PanelRef60Hz 0x00
155#define PanelRef75Hz 0x20
156#define LCDRGB18Bit 0x01
157
158#define ExtChipTrumpion 0x06
159#define ExtChipCH7005 0x08
160#define ExtChipMitacTV 0x0a
161#define LCDNonExpanding 0x10
162#define LCDNonExpandingShift 4
163#define LCDSync 0x20
164#define LCDSyncBit 0xe0
165#define LCDSyncShift 6
166
167/* #define DDC2DelayTime 300 */
168
169#define CRT2DisplayFlag 0x2000
170/* #define LCDDataLen 8 */
171/* #define HiTVDataLen 12 */
172/* #define TVDataLen 16 */
173/* #define SetPALTV 0x0100 */
174#define HalfDCLK 0x1000
175#define NTSCHT 1716
176#define NTSCVT 525
177#define PALHT 1728
178#define PALVT 625
179#define StHiTVHT 892
180#define StHiTVVT 1126
181#define StHiTextTVHT 1000
182#define StHiTextTVVT 1126
183#define ExtHiTVHT 2100
184#define ExtHiTVVT 1125
185
186#define St750pTVHT 1716
187#define St750pTVVT 525
188#define Ext750pTVHT 1716
189#define Ext750pTVVT 525
190#define St525pTVHT 1716
191#define St525pTVVT 525
192#define Ext525pTVHT 1716
193#define Ext525pTVVT 525
194#define St525iTVHT 1716
195#define St525iTVVT 525
196#define Ext525iTVHT 1716
197#define Ext525iTVVT 525
198
199#define VCLKStartFreq 25
200#define SoftDramType 0x80
201#define VCLK40 0x04
202
203#define VCLK162 0x21
204
205#define LCDRGB18Bit 0x01
206#define LoadDACFlag 0x1000
207#define AfterLockCRT2 0x4000
208#define SetCRT2ToAVIDEO 0x0004
209#define SetCRT2ToSCART 0x0010
210#define Ext2StructSize 5
211
212
213#define YPbPr525iVCLK 0x03B
214#define YPbPr525iVCLK_2 0x03A
215
216#define SwitchToCRT2 0x0002
217/* #define LCDVESATiming 0x08 */
218#define SetSCARTOutput 0x01
219#define AVIDEOSense 0x01
220#define SVIDEOSense 0x02
221#define SCARTSense 0x04
222#define LCDSense 0x08
223#define Monitor1Sense 0x20
224#define Monitor2Sense 0x10
225#define HiTVSense 0x40
226#define BoardTVType 0x02
227#define HotPlugFunction 0x08
228#define StStructSize 0x06
229
230
231#define XGI_CRT2_PORT_00 0x00 - 0x030
232#define XGI_CRT2_PORT_04 0x04 - 0x030
233#define XGI_CRT2_PORT_10 0x10 - 0x30
234#define XGI_CRT2_PORT_12 0x12 - 0x30
235#define XGI_CRT2_PORT_14 0x14 - 0x30
236
237
238#define LCDNonExpanding 0x10
239#define ADR_CRT2PtrData 0x20E
240#define offset_Zurac 0x210
241#define ADR_LVDSDesPtrData 0x212
242#define ADR_LVDSCRT1DataPtr 0x214
243#define ADR_CHTVVCLKPtr 0x216
244#define ADR_CHTVRegDataPtr 0x218
245
246#define LVDSDataLen 6
247/* #define EnableLVDSDDA 0x10 */
248/* #define LVDSDesDataLen 3 */
249#define ActiveNonExpanding 0x40
250#define ActiveNonExpandingShift 6
251/* #define ActivePAL 0x20 */
252#define ActivePALShift 5
253/* #define ModeSwitchStatus 0x0F */
254#define SoftTVType 0x40
255#define SoftSettingAddr 0x52
256#define ModeSettingAddr 0x53
257
258/* #define SelectCRT1Rate 0x4 */
259
260#define _PanelType00 0x00
261#define _PanelType01 0x08
262#define _PanelType02 0x10
263#define _PanelType03 0x18
264#define _PanelType04 0x20
265#define _PanelType05 0x28
266#define _PanelType06 0x30
267#define _PanelType07 0x38
268#define _PanelType08 0x40
269#define _PanelType09 0x48
270#define _PanelType0A 0x50
271#define _PanelType0B 0x58
272#define _PanelType0C 0x60
273#define _PanelType0D 0x68
274#define _PanelType0E 0x70
275#define _PanelType0F 0x78
276
277
278#define PRIMARY_VGA 0 /* 1: XGI is primary vga 0:XGI is secondary vga */
279#define BIOSIDCodeAddr 0x235
280#define OEMUtilIDCodeAddr 0x237
281#define VBModeIDTableAddr 0x239
282#define OEMTVPtrAddr 0x241
283#define PhaseTableAddr 0x243
284#define NTSCFilterTableAddr 0x245
285#define PALFilterTableAddr 0x247
286#define OEMLCDPtr_1Addr 0x249
287#define OEMLCDPtr_2Addr 0x24B
288#define LCDHPosTable_1Addr 0x24D
289#define LCDHPosTable_2Addr 0x24F
290#define LCDVPosTable_1Addr 0x251
291#define LCDVPosTable_2Addr 0x253
292#define OEMLCDPIDTableAddr 0x255
293
294#define VBModeStructSize 5
295#define PhaseTableSize 4
296#define FilterTableSize 4
297#define LCDHPosTableSize 7
298#define LCDVPosTableSize 5
299#define OEMLVDSPIDTableSize 4
300#define LVDSHPosTableSize 4
301#define LVDSVPosTableSize 6
302
303#define VB_ModeID 0
304#define VB_TVTableIndex 1
305#define VB_LCDTableIndex 2
306#define VB_LCDHIndex 3
307#define VB_LCDVIndex 4
308
309#define OEMLCDEnable 0x0001
310#define OEMLCDDelayEnable 0x0002
311#define OEMLCDPOSEnable 0x0004
312#define OEMTVEnable 0x0100
313#define OEMTVDelayEnable 0x0200
314#define OEMTVFlickerEnable 0x0400
315#define OEMTVPhaseEnable 0x0800
316#define OEMTVFilterEnable 0x1000
317
318#define OEMLCDPanelIDSupport 0x0080
319
320/* #define LCDVESATiming 0x0001 //LCD Info CR37 */
321/* #define EnableLVDSDDA 0x0002 */
322#define EnableScalingLCD 0x0008
323#define SetPWDEnable 0x0004
324#define SetLCDtoNonExpanding 0x0010
325/* #define SetLCDPolarity 0x00E0 */
326#define SetLCDDualLink 0x0100
327#define SetLCDLowResolution 0x0200
328#define SetLCDStdMode 0x0400
329#define SetTVStdMode 0x0200
330#define SetTVLowResolution 0x0400
331/* =============================================================
332 for 310
333============================================================== */
334#define SoftDRAMType 0x80
335#define SoftSetting_OFFSET 0x52
336#define SR07_OFFSET 0x7C
337#define SR15_OFFSET 0x7D
338#define SR16_OFFSET 0x81
339#define SR17_OFFSET 0x85
340#define SR19_OFFSET 0x8D
341#define SR1F_OFFSET 0x99
342#define SR21_OFFSET 0x9A
343#define SR22_OFFSET 0x9B
344#define SR23_OFFSET 0x9C
345#define SR24_OFFSET 0x9D
346#define SR25_OFFSET 0x9E
347#define SR31_OFFSET 0x9F
348#define SR32_OFFSET 0xA0
349#define SR33_OFFSET 0xA1
350
351#define CR40_OFFSET 0xA2
352#define SR25_1_OFFSET 0xF6
353#define CR49_OFFSET 0xF7
354
355#define VB310Data_1_2_Offset 0xB6
356#define VB310Data_4_D_Offset 0xB7
357#define VB310Data_4_E_Offset 0xB8
358#define VB310Data_4_10_Offset 0xBB
359
360#define RGBSenseDataOffset 0xBD
361#define YCSenseDataOffset 0xBF
362#define VideoSenseDataOffset 0xC1
363#define OutputSelectOffset 0xF3
364
365#define ECLK_MCLK_DISTANCE 0x14
366#define VBIOSTablePointerStart 0x200
367#define StandTablePtrOffset VBIOSTablePointerStart+0x02
368#define EModeIDTablePtrOffset VBIOSTablePointerStart+0x04
369#define CRT1TablePtrOffset VBIOSTablePointerStart+0x06
370#define ScreenOffsetPtrOffset VBIOSTablePointerStart+0x08
371#define VCLKDataPtrOffset VBIOSTablePointerStart+0x0A
372#define MCLKDataPtrOffset VBIOSTablePointerStart+0x0E
373#define CRT2PtrDataPtrOffset VBIOSTablePointerStart+0x10
374#define TVAntiFlickPtrOffset VBIOSTablePointerStart+0x12
375#define TVDelayPtr1Offset VBIOSTablePointerStart+0x14
376#define TVPhaseIncrPtr1Offset VBIOSTablePointerStart+0x16
377#define TVYFilterPtr1Offset VBIOSTablePointerStart+0x18
378#define LCDDelayPtr1Offset VBIOSTablePointerStart+0x20
379#define TVEdgePtr1Offset VBIOSTablePointerStart+0x24
380#define CRT2Delay1Offset VBIOSTablePointerStart+0x28
381#define LCDDataDesOffset VBIOSTablePointerStart-0x02
382#define LCDDataPtrOffset VBIOSTablePointerStart+0x2A
383#define LCDDesDataPtrOffset VBIOSTablePointerStart+0x2C
384#define LCDDataList VBIOSTablePointerStart+0x22 /* add for GetLCDPtr */
385#define TVDataList VBIOSTablePointerStart+0x36 /* add for GetTVPtr */
386/* */
387/* Modify from 310.inc */
388/* */
389/* */
390
391
392#define ShowMsgFlag 0x20 /* SoftSetting */
393#define ShowVESAFlag 0x10
394#define HotPlugFunction 0x08
395#define ModeSoftSetting 0x04
396#define TVSoftSetting 0x02
397#define LCDSoftSetting 0x01
398
399#define GatingCRTinLCDA 0x10
400#define SetHiTVOutput 0x08
401#define SetYPbPrOutput 0x04
402#define BoardTVType 0x02
403#define SetSCARTOutput 0x01
404
405#define ModeSettingYPbPr 0x02 /* TVModeSetting, Others as same as CR30 */
406
407/* TVModeSetting same as CR35 */
408
409/* LCDModeSetting same as CR37 */
410
411#define EnableNewTVFont 0x10 /* MiscCapability */
412
413#define EnableLCDOutput 0x80 /* LCDCfgSetting */
414
415#define SoftDRAMType 0x80 /* DRAMSetting */
416#define SoftDRAMConfig 0x40
417#define MosSelDRAMType 0x20
418#define SDRAM 000h
419#define SGRAM 0x01
420#define ESDRAM 0x02
421
422#define EnableAGPCfgSetting 0x01 /* AGPCfgSetting */
423
424/* ---------------- SetMode Stack */
425#define CRT1Len 15
426#define VCLKLen 4
427#define DefThreshold 0x0100
428#define ExtRegsSize (57+8+37+70+63+28+768+1)/64+1
429
430#define VGA_XGI315 0x0001 /* VGA Type Info */
431#define VGA_SNewis315e 0x0002 /* 315 series */
432#define VGA_XGI550 0x0004
433#define VGA_XGI640 0x0008
434#define VGA_XGI740 0x0010
435#define VGA_XGI650 0x0020
436#define VGA_XGI650M 0x0040
437#define VGA_XGI651 0x0080
438#define VGA_XGI340 0x0001 /* 340 series */
439#define VGA_XGI330 0x0001 /* 330 series */
440#define VGA_XGI660 0x0001 /* 660 series */
441
442#define VB_XGI301 0x0001 /* VB Type Info */
443#define VB_XGI301B 0x0002 /* 301 series */
444#define VB_XGI302B 0x0004
445#define VB_NoLCD 0x8000
446#define VB_XGI301LV 0x0008
447#define VB_XGI302LV 0x0010
448#define VB_LVDS_NS 0x0001 /* 3rd party chip */
449#define VB_CH7017 0x0002
450#define VB_CH7007 0x0080 /* [Billy] 07/05/03 */
451/* #define VB_LVDS_SI 0x0004 */
452
453#define ModeInfoFlag 0x0007
454#define IsTextMode 0x0007
455#define ModeText 0x0000
456#define ModeCGA 0x0001
457#define ModeEGA 0x0002 /* 16 colors mode */
458#define ModeVGA 0x0003 /* 256 colors mode */
459#define Mode15Bpp 0x0004 /* 15 Bpp Color Mode */
460#define Mode16Bpp 0x0005 /* 16 Bpp Color Mode */
461#define Mode24Bpp 0x0006 /* 24 Bpp Color Mode */
462#define Mode32Bpp 0x0007 /* 32 Bpp Color Mode */
463
464#define DACInfoFlag 0x0018
465#define MONODAC 0x0000
466#define CGADAC 0x0008
467#define EGADAC 0x0010
468#define VGADAC 0x0018
469
470#define MemoryInfoFlag 0x01e0
471#define MemorySizeShift 5
472#define Need1MSize 0x0000
473#define Need2MSize 0x0020
474#define Need4MSize 0x0060
475#define Need8MSize 0x00e0
476#define Need16MSize 0x01e0
477
478#define Charx8Dot 0x0200
479#define LineCompareOff 0x0400
480#define CRT2Mode 0x0800
481#define HalfDCLK 0x1000
482#define NoSupportSimuTV 0x2000
483#define DoubleScanMode 0x8000
484
485/* -------------- Ext_InfoFlag */
486#define SupportModeInfo 0x0007
487#define Support256 0x0003
488#define Support15Bpp 0x0004
489#define Support16Bpp 0x0005
490#define Support24Bpp 0x0006
491#define Support32Bpp 0x0007
492
493#define SupportAllCRT2 0x0078
494#define SupportTV 0x0008
495#define SupportHiVisionTV 0x0010
496#define SupportLCD 0x0020
497#define SupportRAMDAC2 0x0040
498#define NoSupportTV 0x0070
499#define NoSupportHiVisionTV 0x0060
500#define NoSupportLCD 0x0058
501#define SupportTV1024 0x0800 /* 301btest */
502#define SupportYPbPr 0x1000 /* 301lv */
503#define InterlaceMode 0x0080
504#define SyncPP 0x0000
505#define SyncPN 0x4000
506#define SyncNP 0x8000
507#define SyncNN 0xC000
508
509/* -------------- SetMode Stack/Scratch */
510#define SetSimuScanMode 0x0001 /* VBInfo/CR30 & CR31 */
511#define SwitchToCRT2 0x0002
512#define SetCRT2ToTV1 0x009C
513#define SetCRT2ToTV 0x089C
514#define SetCRT2ToAVIDEO 0x0004
515#define SetCRT2ToSVIDEO 0x0008
516#define SetCRT2ToSCART 0x0010
517#define SetCRT2ToLCD 0x0020
518#define SetCRT2ToRAMDAC 0x0040
519#define SetCRT2ToHiVisionTV 0x0080
520#define SetCRT2ToLCDA 0x0100
521#define SetInSlaveMode 0x0200
522#define SetNotSimuMode 0x0400
523#define HKEventMode 0x0800
524#define SetCRT2ToYPbPr 0x0800
525#define LoadDACFlag 0x1000
526#define DisableCRT2Display 0x2000
527#define DriverMode 0x4000
528#define SetCRT2ToDualEdge 0x8000
529#define HotKeySwitch 0x8000
530
531#define ProgrammingCRT2 0x0001 /* Set Flag */
532#define EnableVCMode 0x0002
533#define SetHKEventMode 0x0004
534#define ReserveTVOption 0x0008
535#define DisableRelocateIO 0x0010
536#define Win9xDOSMode 0x0020
537#define JDOSMode 0x0040
538/* #define SetWin9xforJap 0x0080 // not used now */
539/* #define SetWin9xforKorea 0x0100 // not used now */
540#define GatingCRT 0x0800
541#define DisableChB 0x1000
542#define EnableChB 0x2000
543#define DisableChA 0x4000
544#define EnableChA 0x8000
545
546#define SetNTSCTV 0x0000 /* TV Info */
547#define SetPALTV 0x0001
548#define SetNTSCJ 0x0002
549#define SetPALMTV 0x0004
550#define SetPALNTV 0x0008
551#define SetCHTVUnderScan 0x0000
552/* #define SetCHTVOverScan 0x0010 */
553#define SetYPbPrMode525i 0x0020
554#define SetYPbPrMode525p 0x0040
555#define SetYPbPrMode750p 0x0080
556#define SetYPbPrMode1080i 0x0100
557#define SetTVStdMode 0x0200
558#define SetTVLowResolution 0x0400
559#define SetTVSimuMode 0x0800
560#define TVSimuMode 0x0800
561#define RPLLDIV2XO 0x1000
562#define NTSC1024x768 0x2000
563#define SetTVLockMode 0x4000
564
565#define LCDVESATiming 0x0001 /* LCD Info/CR37 */
566#define EnableLVDSDDA 0x0002
567#define EnableScalingLCD 0x0008
568#define SetPWDEnable 0x0004
569#define SetLCDtoNonExpanding 0x0010
570#define SetLCDPolarity 0x00e0
571#define SetLCDDualLink 0x0100
572#define SetLCDLowResolution 0x0200
573#define SetLCDStdMode 0x0400
574
575#define DefaultLCDCap 0x80ea /* LCD Capability shampoo */
576#define RLVDSDHL00 0x0000
577#define RLVDSDHL01 0x0001
578#define RLVDSDHL10 0x0002 /* default */
579#define RLVDSDHL11 0x0003
580#define EnableLCD24bpp 0x0004 /* default */
581#define DisableLCD24bpp 0x0000
582#define RLVDSClkSFT0 0x0000
583#define RLVDSClkSFT1 0x0008 /* default */
584#define EnableLVDSDCBal 0x0010
585#define DisableLVDSDCBal 0x0000 /* default */
586#define SinglePolarity 0x0020 /* default */
587#define MultiPolarity 0x0000
588#define LCDPolarity 0x00c0 /* default: SyncNN */
589#define LCDSingleLink 0x0000 /* default */
590#define LCDDualLink 0x0100
591#define EnableSpectrum 0x0200
592#define DisableSpectrum 0x0000 /* default */
593#define PWDEnable 0x0400
594#define PWDDisable 0x0000 /* default */
595#define PWMEnable 0x0800
596#define PWMDisable 0x0000 /* default */
597#define EnableVBCLKDRVLOW 0x4000
598#define EnableVBCLKDRVHigh 0x0000 /* default */
599#define EnablePLLSPLOW 0x8000
600#define EnablePLLSPHigh 0x0000 /* default */
601
602#define LCDBToA 0x20 /* LCD SetFlag */
603#define StLCDBToA 0x40
604#define LockLCDBToA 0x80
605#define LCDToFull 0x10
606#define AVIDEOSense 0x01 /* CR32 */
607#define SVIDEOSense 0x02
608#define SCARTSense 0x04
609#define LCDSense 0x08
610#define Monitor2Sense 0x10
611#define Monitor1Sense 0x20
612#define HiTVSense 0x40
613
614#ifdef NewScratch
615#define YPbPrSense 0x80 /* NEW SCRATCH */
616#endif
617
618#define TVSense 0xc7
619
620#define TVOverScan 0x10 /* CR35 */
621#define TVOverScanShift 4
622
623#ifdef NewScratch
624#define NTSCMode 0x00
625#define PALMode 0x00
626#define NTSCJMode 0x02
627#define PALMNMode 0x0c
628#define YPbPrMode 0xe0
629#define YPbPrMode525i 0x00
630#define YPbPrMode525p 0x20
631#define YPbPrMode750p 0x40
632#define YPbPrMode1080i 0x60
633#else /* Old Scratch */
634#define ClearBufferFlag 0x20
635#endif
636
637
638#define LCDRGB18Bit 0x01 /* CR37 */
639#define LCDNonExpanding 0x10
640#define LCDNonExpandingShift 4
641#define LCDSync 0x20
642#define LCDSyncBit 0xe0 /* H/V polarity & sync ID */
643#define LCDSyncShift 6
644
645#ifdef NewScratch
646#define ScalingLCD 0x08
647#else /* Old Scratch */
648#define ExtChipType 0x0e
649#define ExtChip301 0x02
650#define ExtChipLVDS 0x04
651#define ExtChipCH7019 0x06
652#define ScalingLCD 0x10
653#endif
654
655#define EnableDualEdge 0x01 /* CR38 */
656#define SetToLCDA 0x02
657#ifdef NewScratch
658#define SetYPbPr 0x04
659#define DisableChannelA 0x08
660#define DisableChannelB 0x10
661#define ExtChipType 0xe0
662#define ExtChip301 0x20
663#define ExtChipLVDS 0x40
664#define ExtChipCH7019 0x60
665#else /* Old Scratch */
666#define YPbPrSense 0x04
667#define SetYPbPr 0x08
668#define YPbPrMode 0x30
669#define YPbPrMode525i 0x00
670#define YPbPrMode525p 0x10
671#define YPbPrMode750p 0x20
672#define YPbPrMode1080i 0x30
673#define PALMNMode 0xc0
674#endif
675
676#define BacklightControlBit 0x01 /* CR3A */
677#define Win9xforJap 0x40
678#define Win9xforKorea 0x80
679
680#define ForceMDBits 0x07 /* CR3B */
681#define ForceMD_JDOS 0x00
682#define ForceMD_640x400T 0x01
683#define ForceMD_640x350T 0x02
684#define ForceMD_720x400T 0x03
685#define ForceMD_640x480E 0x04
686#define ForceMD_640x400E 0x05
687#define ForceP1Bit 0x10
688#define ForceP2Bit 0x20
689#define EnableForceMDinBIOS 0x40
690#define EnableForceMDinDrv 0x80
691
692#ifdef NewScratch /* New Scratch */
693/* ---------------------- VUMA Information */
694#define LCDSettingFromCMOS 0x04 /* CR3C */
695#define TVSettingFromCMOS 0x08
696#define DisplayDeviceFromCMOS 0x10
697#define HKSupportInSBIOS 0x20
698#define OSDSupportInSBIOS 0x40
699#define DisableLogo 0x80
700
701/* ---------------------- HK Evnet Definition */
702#define HKEvent 0x0f /* CR3D */
703#define HK_ModeSwitch 0x01
704#define HK_Expanding 0x02
705#define HK_OverScan 0x03
706#define HK_Brightness 0x04
707#define HK_Contrast 0x05
708#define HK_Mute 0x06
709#define HK_Volume 0x07
710#define ModeSwitchStatus 0xf0
711#define ActiveCRT1 0x10
712#define ActiveLCD 0x0020
713#define ActiveTV 0x40
714#define ActiveCRT2 0x80
715
716#define TVSwitchStatus 0x1f /* CR3E */
717#define ActiveAVideo 0x01
718#define ActiveSVideo 0x02
719#define ActiveSCART 0x04
720#define ActiveHiTV 0x08
721#define ActiveYPbPr 0x10
722
723#define EnableHKEvent 0x01 /* CR3F */
724#define EnableOSDEvent 0x02
725#define StartOSDEvent 0x04
726#define IgnoreHKEvent 0x08
727#define IgnoreOSDEvent 0x10
728#else /* Old Scratch */
729#define OSD_SBIOS 0x02 /* SR17 */
730#define DisableLogo 0x04
731#define SelectKDOS 0x08
732#define KorWinMode 0x10
733#define KorMode3Bit 0x0020
734#define PSCCtrlBit 0x40
735#define NPSCCtrlBitShift 6
736#define BlueScreenBit 0x80
737
738#define HKEvent 0x0f /* CR79 */
739#define HK_ModeSwitch 0x01
740#define HK_Expanding 0x02
741#define HK_OverScan 0x03
742#define HK_Brightness 0x04
743#define HK_Contrast 0x05
744#define HK_Mute 0x06
745#define HK_Volume 0x07
746#define ActivePAL 0x0020
747#define ActivePALShift 5
748#define ActiveNonExpanding 0x40
749#define ActiveNonExpandingShift 6
750#define ActiveOverScan 0x80
751#define ActiveOverScanShift 7
752
753#define ModeSwitchStatus 0x0b /* SR15 */
754#define ActiveCRT1 0x01
755#define ActiveLCD 0x02
756#define ActiveCRT2 0x08
757
758#define TVSwitchStatus 0xf0 /* SR16 */
759#define TVConfigShift 3
760#define ActiveTV 0x01
761#define ActiveYPbPr 0x04
762#define ActiveAVideo 0x10
763#define ActiveSVideo 0x0020
764#define ActiveSCART 0x40
765#define ActiveHiTV 0x80
766
767#define EnableHKEvent 0x01 /* CR7A */
768#define EnableOSDEvent 0x02
769#define StartOSDEvent 0x04
770#define CMOSSupport 0x08
771#define HotKeySupport 0x10
772#define IngoreHKOSDEvent 0x20
773#endif
774
775/* //------------- Misc. Definition */
776#define SelectCRT1Rate 00h
777/* #define SelectCRT2Rate 04h */
778
779#define DDC1DelayTime 1000
780#ifdef TRUMPION
781#define DDC2DelayTime 15
782#else
783#define DDC2DelayTime 150
784#endif
785
786#define R_FACTOR 04Dh
787#define G_FACTOR 097h
788#define B_FACTOR 01Ch
789/* --------------------------------------------------------- */
790/* translated from asm code 301def.h */
791/* */
792/* --------------------------------------------------------- */
793#define LCDDataLen 8
794#define HiTVDataLen 12
795#define TVDataLen 12
796#define LVDSCRT1Len_H 8
797#define LVDSCRT1Len_V 7
798#define LVDSDataLen 6
799#define LVDSDesDataLen 6
800#define LCDDesDataLen 6
801#define LVDSDesDataLen2 8
802#define LCDDesDataLen2 8
803#define CHTVRegLen 16
804#define CHLVRegLen 12
805
806#define StHiTVHT 892
807#define StHiTVVT 1126
808#define StHiTextTVHT 1000
809#define StHiTextTVVT 1126
810#define ExtHiTVHT 2100
811#define ExtHiTVVT 1125
812#define NTSCHT 1716
813#define NTSCVT 525
814#define NTSC1024x768HT 1908
815#define NTSC1024x768VT 525
816#define PALHT 1728
817#define PALVT 625
818
819#define YPbPrTV525iHT 1716 /* YPbPr */
820#define YPbPrTV525iVT 525
821#define YPbPrTV525pHT 1716
822#define YPbPrTV525pVT 525
823#define YPbPrTV750pHT 1650
824#define YPbPrTV750pVT 750
825
826#define CRT2VCLKSel 0xc0
827
828#define CRT2Delay1 0x04 /* XGI301 */
829#define CRT2Delay2 0x0A /* 301B,302 */
830
831
832#define VCLK25_175 0x00
833#define VCLK28_322 0x01
834#define VCLK31_5 0x02
835#define VCLK36 0x03
836#define VCLK40 0x04
837#define VCLK43_163 0x05
838#define VCLK44_9 0x06
839#define VCLK49_5 0x07
840#define VCLK50 0x08
841#define VCLK52_406 0x09
842#define VCLK56_25 0x0A
843#define VCLK65 0x0B
844#define VCLK67_765 0x0C
845#define VCLK68_179 0x0D
846#define VCLK72_852 0x0E
847#define VCLK75 0x0F
848#define VCLK75_8 0x10
849#define VCLK78_75 0x11
850#define VCLK79_411 0x12
851#define VCLK83_95 0x13
852#define VCLK84_8 0x14
853#define VCLK86_6 0x15
854#define VCLK94_5 0x16
855#define VCLK104_998 0x17
856#define VCLK105_882 0x18
857#define VCLK108_2 0x19
858#define VCLK109_175 0x1A
859#define VCLK113_309 0x1B
860#define VCLK116_406 0x1C
861#define VCLK132_258 0x1D
862#define VCLK135_5 0x1E
863#define VCLK139_054 0x1F
864#define VCLK157_5 0x20
865#define VCLK162 0x21
866#define VCLK175 0x22
867#define VCLK189 0x23
868#define VCLK194_4 0x24
869#define VCLK202_5 0x25
870#define VCLK229_5 0x26
871#define VCLK234 0x27
872#define VCLK252_699 0x28
873#define VCLK254_817 0x29
874#define VCLK265_728 0x2A
875#define VCLK266_952 0x2B
876#define VCLK269_655 0x2C
877#define VCLK272_042 0x2D
878#define VCLK277_015 0x2E
879#define VCLK286_359 0x2F
880#define VCLK291_132 0x30
881#define VCLK291_766 0x31
882#define VCLK309_789 0x32
883#define VCLK315_195 0x33
884#define VCLK323_586 0x34
885#define VCLK330_615 0x35
886#define VCLK332_177 0x36
887#define VCLK340_477 0x37
888#define VCLK375_847 0x38
889#define VCLK388_631 0x39
890#define VCLK125_999 0x51
891#define VCLK148_5 0x52
892#define VCLK178_992 0x54
893#define VCLK217_325 0x55
894#define VCLK299_505 0x56
895#define YPbPr750pVCLK 0x57
896
897#define TVVCLKDIV2 0x3A
898#define TVVCLK 0x3B
899#define HiTVVCLKDIV2 0x3C
900#define HiTVVCLK 0x3D
901#define HiTVSimuVCLK 0x3E
902#define HiTVTextVCLK 0x3F
903#define VCLK39_77 0x40
904/* #define YPbPr750pVCLK 0x0F */
905#define YPbPr525pVCLK 0x3A
906/* #define ;;YPbPr525iVCLK 0x3B */
907/* #define ;;YPbPr525iVCLK_2 0x3A */
908#define NTSC1024VCLK 0x41
909#define VCLK25_175_41 0x42 /* ; ScaleLCD */
910#define VCLK25_175_42 0x43
911#define VCLK28_322_43 0x44
912#define VCLK40_44 0x45
913#define VCLKQVGA_1 0x46 /* ; QVGA */
914#define VCLKQVGA_2 0x47
915#define VCLKQVGA_3 0x48
916#define VCLK35_2 0x49 /* ; 800x480 */
917#define VCLK122_61 0x4A
918#define VCLK80_350 0x4B
919#define VCLK107_385 0x4C
920
921#define CHTVVCLK30_2 0x50 /* ;;CHTV */
922#define CHTVVCLK28_1 0x51
923#define CHTVVCLK43_6 0x52
924#define CHTVVCLK26_4 0x53
925#define CHTVVCLK24_6 0x54
926#define CHTVVCLK47_8 0x55
927#define CHTVVCLK31_5 0x56
928#define CHTVVCLK26_2 0x57
929#define CHTVVCLK39 0x58
930#define CHTVVCLK36 0x59
931
932#define CH7007TVVCLK30_2 0x00 /* [Billy] 2007/05/18 For CH7007 */
933#define CH7007TVVCLK28_1 0x01
934#define CH7007TVVCLK43_6 0x02
935#define CH7007TVVCLK26_4 0x03
936#define CH7007TVVCLK24_6 0x04
937#define CH7007TVVCLK47_8 0x05
938#define CH7007TVVCLK31_5 0x06
939#define CH7007TVVCLK26_2 0x07
940#define CH7007TVVCLK39 0x08
941#define CH7007TVVCLK36 0x09
942
943#define RES320x200 0x00
944#define RES320x240 0x01
945#define RES400x300 0x02
946#define RES512x384 0x03
947#define RES640x400 0x04
948#define RES640x480x60 0x05
949#define RES640x480x72 0x06
950#define RES640x480x75 0x07
951#define RES640x480x85 0x08
952#define RES640x480x100 0x09
953#define RES640x480x120 0x0A
954#define RES640x480x160 0x0B
955#define RES640x480x200 0x0C
956#define RES800x600x56 0x0D
957#define RES800x600x60 0x0E
958#define RES800x600x72 0x0F
959#define RES800x600x75 0x10
960#define RES800x600x85 0x11
961#define RES800x600x100 0x12
962#define RES800x600x120 0x13
963#define RES800x600x160 0x14
964#define RES1024x768x43 0x15
965#define RES1024x768x60 0x16
966#define RES1024x768x70 0x17
967#define RES1024x768x75 0x18
968#define RES1024x768x85 0x19
969#define RES1024x768x100 0x1A
970#define RES1024x768x120 0x1B
971#define RES1280x1024x43 0x1C
972#define RES1280x1024x60 0x1D
973#define RES1280x1024x75 0x1E
974#define RES1280x1024x85 0x1F
975#define RES1600x1200x60 0x20
976#define RES1600x1200x65 0x21
977#define RES1600x1200x70 0x22
978#define RES1600x1200x75 0x23
979#define RES1600x1200x85 0x24
980#define RES1600x1200x100 0x25
981#define RES1600x1200x120 0x26
982#define RES1920x1440x60 0x27
983#define RES1920x1440x65 0x28
984#define RES1920x1440x70 0x29
985#define RES1920x1440x75 0x2A
986#define RES1920x1440x85 0x2B
987#define RES1920x1440x100 0x2C
988#define RES2048x1536x60 0x2D
989#define RES2048x1536x65 0x2E
990#define RES2048x1536x70 0x2F
991#define RES2048x1536x75 0x30
992#define RES2048x1536x85 0x31
993#define RES800x480x60 0x32
994#define RES800x480x75 0x33
995#define RES800x480x85 0x34
996#define RES1024x576x60 0x35
997#define RES1024x576x75 0x36
998#define RES1024x576x85 0x37
999#define RES1280x720x60 0x38
1000#define RES1280x720x75 0x39
1001#define RES1280x720x85 0x3A
1002#define RES1280x960x60 0x3B
1003#define RES720x480x60 0x3C
1004#define RES720x576x56 0x3D
1005#define RES856x480x79I 0x3E
1006#define RES856x480x60 0x3F
1007#define RES1280x768x60 0x40
1008#define RES1400x1050x60 0x41
1009#define RES1152x864x60 0x42
1010#define RES1152x864x75 0x43
1011#define RES1024x768x160 0x44
1012#define RES1280x960x75 0x45
1013#define RES1280x960x85 0x46
1014#define RES1280x960x120 0x47
1015
1016#define LFBDRAMTrap 0x30
1017#endif
diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c
new file mode 100644
index 000000000000..49b39ee93a89
--- /dev/null
+++ b/drivers/staging/xgifb/vb_ext.c
@@ -0,0 +1,1370 @@
1#include "osdef.h"
2
3
4
5
6#ifdef WIN2000
7
8#include <dderror.h>
9#include <devioctl.h>
10#include <miniport.h>
11#include <ntddvdeo.h>
12#include <video.h>
13#include "xgiv.h"
14#include "dd_i2c.h"
15#include "tools.h"
16#endif /* WIN2000 */
17
18#ifdef LINUX_XF86
19#include "xf86.h"
20#include "xf86PciInfo.h"
21#include "xgi.h"
22#include "xgi_regs.h"
23#endif
24
25#ifdef LINUX_KERNEL
26#include <linux/version.h>
27#include <asm/io.h>
28#include <linux/types.h>
29#include "XGIfb.h"
30/*#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
31#include <video/XGIfb.h>
32#else
33#include <linux/XGIfb.h>
34#endif*/
35#endif
36
37
38
39#include "vb_def.h"
40#include "vgatypes.h"
41#include "vb_struct.h"
42#include "vb_util.h"
43#include "vb_setmode.h"
44#include "vb_ext.h"
45extern UCHAR XGI330_SoftSetting;
46extern UCHAR XGI330_OutputSelect;
47extern USHORT XGI330_RGBSenseData2;
48extern USHORT XGI330_YCSenseData2;
49extern USHORT XGI330_VideoSenseData2;
50#ifdef WIN2000
51extern UCHAR SenseCHTV(PHW_DEVICE_EXTENSION pHWDE); /* 2007/05/17 Billy */
52#endif
53void XGI_GetSenseStatus( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo );
54BOOLEAN XGINew_GetPanelID(PVB_DEVICE_INFO pVBInfo);
55USHORT XGINew_SenseLCD(PXGI_HW_DEVICE_INFO,PVB_DEVICE_INFO pVBInfo);
56BOOLEAN XGINew_GetLCDDDCInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
57void XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE ) ;
58BOOLEAN XGINew_BridgeIsEnable(PXGI_HW_DEVICE_INFO,PVB_DEVICE_INFO pVBInfo );
59BOOLEAN XGINew_Sense(USHORT tempbx,USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
60BOOLEAN XGINew_SenseHiTV( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
61
62/**************************************************************
63 Dynamic Sense
64*************************************************************/
65
66void XGI_WaitDisplay(void);
67BOOLEAN XGI_Is301C(PVB_DEVICE_INFO);
68BOOLEAN XGI_Is301LV(PVB_DEVICE_INFO);
69
70#ifdef WIN2000
71UCHAR XGI_SenseLCD(PHW_DEVICE_EXTENSION, PVB_DEVICE_INFO);
72UCHAR XGI_GetLCDDDCInfo(PHW_DEVICE_EXTENSION,PVB_DEVICE_INFO);
73
74extern BOOL bGetDdcInfo(
75PHW_DEVICE_EXTENSION pHWDE,
76ULONG ulWhichOne,
77PUCHAR pjQueryBuffer,
78ULONG ulBufferSize
79 );
80
81#endif
82
83
84/* --------------------------------------------------------------------- */
85/* Function : XGINew_Is301B */
86/* Input : */
87/* Output : */
88/* Description : */
89/* --------------------------------------------------------------------- */
90BOOLEAN XGINew_Is301B( PVB_DEVICE_INFO pVBInfo )
91{
92 USHORT flag ;
93
94 flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) ;
95
96 if ( flag > 0x0B0 )
97 return( 0 ) ; /* 301b */
98 else
99 return( 1 ) ;
100}
101
102/* --------------------------------------------------------------------- */
103/* Function : XGI_Is301C */
104/* Input : */
105/* Output : */
106/* Description : */
107/* --------------------------------------------------------------------- */
108BOOLEAN XGI_Is301C( PVB_DEVICE_INFO pVBInfo )
109{
110 if ( ( XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) & 0xF0 ) == 0xC0 )
111 return( 1 ) ;
112
113 if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) >= 0xD0 )
114 {
115 if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x39 ) == 0xE0 )
116 return( 1 ) ;
117 }
118
119 return( 0 ) ;
120}
121
122
123/* --------------------------------------------------------------------- */
124/* Function : XGI_Is301LV */
125/* Input : */
126/* Output : */
127/* Description : */
128/* --------------------------------------------------------------------- */
129BOOLEAN XGI_Is301LV( PVB_DEVICE_INFO pVBInfo )
130{
131 if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) >= 0xD0 )
132 {
133 if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x39 ) == 0xFF )
134 {
135 return( 1 ) ;
136 }
137 }
138 return( 0 ) ;
139}
140
141
142/* --------------------------------------------------------------------- */
143/* Function : XGINew_Sense */
144/* Input : */
145/* Output : */
146/* Description : */
147/* --------------------------------------------------------------------- */
148BOOLEAN XGINew_Sense( USHORT tempbx , USHORT tempcx, PVB_DEVICE_INFO pVBInfo )
149{
150 USHORT temp , i , tempch ;
151
152 temp = tempbx & 0xFF ;
153 XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
154 temp = ( tempbx & 0xFF00 ) >> 8 ;
155 temp |= ( tempcx & 0x00FF ) ;
156 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x10 , ~0x1F , temp ) ;
157
158 for( i = 0 ; i < 10 ; i++ )
159 XGI_LongWait( pVBInfo) ;
160
161 tempch = ( tempcx & 0x7F00 ) >> 8 ;
162 temp = XGINew_GetReg1( pVBInfo->Part4Port , 0x03 ) ;
163 temp = temp ^ ( 0x0E ) ;
164 temp &= tempch ;
165
166 if ( temp > 0 )
167 return( 1 ) ;
168 else
169 return( 0 ) ;
170}
171
172#ifdef WIN2000
173/* --------------------------------------------------------------------- */
174/* Function : XGI_SenseLCD */
175/* Input : */
176/* Output : */
177/* Description : */
178/* --------------------------------------------------------------------- */
179UCHAR XGI_SenseLCD( PHW_DEVICE_EXTENSION pHWDE, PVB_DEVICE_INFO pVBInfo)
180{
181 USHORT tempax , tempbx , tempcx ;
182 UCHAR SoftSetting = XGI330_SoftSetting ;
183
184 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV ) )
185 return( 1 ) ;
186
187
188 if ( SoftSetting & HotPlugFunction ) /* Hot Plug Detection */
189 {
190 XGINew_SetRegAND( pVBInfo->Part4Port , 0x0F , 0x3F ) ;
191 tempbx = 0 ;
192 tempcx = 0x9010 ;
193 if ( XGINew_Sense( tempbx , tempcx, pVBInfo ) )
194 return( 1 ) ;
195
196 return( 0 ) ;
197 }
198 else /* Get LCD Info from EDID */
199 return(XGI_GetLCDDDCInfo(pHWDE, pVBInfo));
200}
201
202
203/* --------------------------------------------------------------------- */
204/* Function : XGI_GetLCDDDCInfo */
205/* Input : */
206/* Output : */
207/* Description : */
208/* --------------------------------------------------------------------- */
209UCHAR XGI_GetLCDDDCInfo( PHW_DEVICE_EXTENSION pHWDE , PVB_DEVICE_INFO pVBInfo)
210{
211 UCHAR tempah , tempbl , tempbh ;
212 USHORT tempbx , temp ;
213 UCHAR pjEDIDBuf[ 256 ] ;
214 ULONG ulBufferSize = 256 ;
215 UCHAR bMASK_OUTPUTSTATE_CRT2LCD = 2 ; /* 0423 shampoo */
216
217 bGetDdcInfo( pHWDE , MASK_OUTPUTSTATE_CRT2LCD , pjEDIDBuf , ulBufferSize ) ;
218 if ( ( *( ( PULONG )pjEDIDBuf ) == 0xFFFFFF00 ) && ( *( ( PULONG )( pjEDIDBuf + 4 ) ) == 0x00FFFFFF ) )
219 {
220 tempah = Panel1024x768 ;
221 tempbl=( *( pjEDIDBuf + 0x3A ) ) & 0xf0 ;
222
223 if ( tempbl != 0x40 )
224 {
225 tempah = Panel1600x1200 ;
226 if ( tempbl != 0x60 )
227 {
228 tempah = Panel1280x1024 ;
229 tempbh = ( *( pjEDIDBuf + 0x3B ) ) ;
230 if ( tempbh != 0x00 )
231 {
232 tempah = Panel1280x960 ;
233 if ( tempbh != 0x0C0 )
234 {
235 tempbx = ( ( *( pjEDIDBuf + 0x24 ) ) << 8 ) | ( *( pjEDIDBuf + 0x23 ) ) ;
236 tempah = Panel1280x1024 ;
237 if ( !( tempbx & 0x0100 ) )
238 {
239 tempah = Panel1024x768 ;
240 if ( !( tempbx & 0x0E00 ) )
241 {
242 tempah = Panel1280x1024 ;
243 }
244 }
245 }
246
247 if ( tempbx & 0x00FF )
248 {
249 temp = ScalingLCD ;
250 XGINew_SetRegOR( pVBInfo->P3d4 , 0x37 , temp ) ;
251 }
252 }
253 }
254 }
255 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x36 , ( ~0x07 ) , tempah ) ;
256 tempah = ( ( *( pjEDIDBuf + 0x47 ) ) & 0x06 ) ; /* Polarity */
257 tempah = ( tempah ^ 0x06 ) << 4 ;
258 tempah |= LCDSync ;
259 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , ( ~LCDSyncBit ) , tempah ) ;
260 tempbh= XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ;
261 tempbh &= 0x07 ;
262 if ( tempbh == Panel1280x960 )
263 XGINew_SetRegAND( pVBInfo->P3d4 , 0x37 , 0x0E ) ;
264 }
265 else if ( *pjEDIDBuf == 0x20 )
266 {
267 tempah = Panel1024x768 ;
268 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x36 , ( ~0x07 ) , tempah ) ;
269 }
270 else
271 {
272 return( 0 ) ;
273 }
274
275 return( 1 ) ;
276}
277
278
279/* --------------------------------------------------------------------- */
280/* Function : XGI_DySense */
281/* Input : */
282/* Output : */
283/* Description : */
284/* --------------------------------------------------------------------- */
285BOOLEAN XGI_DySense( PHW_DEVICE_EXTENSION pHWDE , PUCHAR ujConnectStatus)
286{
287 UCHAR pre_CRD,pre_SR1E , pre_Part2_0 , pre_Part4_D ;
288 USHORT tempax , tempbx , tempcx , pushax , temp ;
289 VB_DEVICE_INFO VBINF;
290 PVB_DEVICE_INFO pVBInfo = &VBINF;
291 UCHAR OutputSelect = XGI330_OutputSelect ;
292 PXGI_HW_DEVICE_INFO HwDeviceExtension= pHWDE->pXGIHWDE ;
293 UCHAR bConnectStatus = 0 ;
294 pVBInfo->BaseAddr = HwDeviceExtension->pjIOAddress ;
295 pVBInfo->ROMAddr = pHWDE->pjVirtualRomBase ;
296
297 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
298 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
299 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
300 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
301 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
302 pushax = XGINew_GetReg1( pVBInfo->P3d4 , 0x17 ) ; /* 0512 Fix Dysense hanged */
303 temp = ( pushax & 0x00FF ) | 0x80 ;
304 XGINew_SetRegOR( pVBInfo->P3d4 , 0x17 , temp ) ;
305 XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
306 /* beginning of dynamic sense CRT1 */
307
308 pVBInfo->IF_DEF_CH7007 = 0;
309 if (pHWDE->bCH7007)
310 {
311 InitTo330Pointer( pHWDE->pXGIHWDE->jChipType, pVBInfo ) ;
312 HwDeviceExtension->pDevice = (PVOID)pHWDE;
313 pVBInfo->IF_DEF_CH7007 = 1;
314 /* [Billy] 2007/05/14 For CH7007 */
315 if ( pVBInfo->IF_DEF_CH7007 == 1 )
316 {
317 bConnectStatus = SenseCHTV(HwDeviceExtension->pDevice) ; /* 07/05/28 */
318 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~0x03 , (UCHAR)bConnectStatus ) ;
319 }
320 }
321 if(( pHWDE->jChipID >= XG40 ) || ( pHWDE->jChipID >= XG20 ))
322 {
323
324 if ( pHWDE->jChipID >= XG40 )
325 XGINew_SetReg1( pVBInfo->P3d4 , 0x57 , 0x4A ) ; /* write sense pattern 30->4a */
326 else
327 XGINew_SetReg1( pVBInfo->P3d4 , 0x57 , 0x5F ) ; /* write sense pattern */
328
329 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x53 , 0xFF , 0x02 ) ; /* enable sense DAC */
330 XGI_WaitDisply(pVBInfo) ;
331
332 if(XGINew_GetReg2( pVBInfo->P3c2 ) & 0x10 )
333 bConnectStatus |= Monitor1Sense ;
334
335 XGINew_SetRegAND( pVBInfo->P3d4 , 0x53 , 0xFD ) ; /* disable sense DAC */
336 XGINew_SetRegAND( pVBInfo->P3d4 , 0x57 , 0x00 ) ; /* clear sense pattern */
337
338
339 /* ---------- End of dynamic sense CRT1 ----------- */
340
341 /* ---------- beginning of dynamic sense VB ------------ */
342 pre_SR1E = XGINew_GetReg1( pVBInfo->P3c4 , 0x1E ) ;
343 XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x20 ) ; /* Enable CRT2,work-a-round for 301B/301LV/302LV */
344 pre_Part2_0 = XGINew_GetReg1( pVBInfo->Part2Port , 0x00 ) ;
345 pre_Part4_D = XGINew_GetReg1( pVBInfo->Part4Port , 0x0D ) ;
346
347 if ( XGI_Is301C( pVBInfo ) ) /* 301C only */
348 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x0D , ~0x07 , 0x01 ) ; /* Set Part4 0x0D D[2:0] to 001b */
349
350 /* tempax = 0 ; */
351 if ( !XGI_Is301LV( pVBInfo ) )
352 {
353 tempbx = XGI330_RGBSenseData2 ;
354 tempcx = 0x0E08 ;
355 if(XGINew_Sense( tempbx , tempcx, pVBInfo ) )
356 {
357 bConnectStatus |= Monitor2Sense ;
358 if ( OutputSelect & SetSCARTOutput )
359 {
360 bConnectStatus ^= ( Monitor2Sense | SCARTSense ) ;
361 }
362 }
363 }
364 if ( XGI_Is301C( pVBInfo ) ) /* 301C only */
365 XGINew_SetRegOR( pVBInfo->Part4Port , 0x0D , 0x04 ) ; /* Set Part4 0x0D D[2]=1 for dynamic sense */
366
367 if ( ( XGINew_Is301B( pVBInfo ) ) )
368 XGINew_SetRegOR( pVBInfo->Part2Port , 0x00 , 0x0C ) ; /* ????????? */
369
370 if ( XGINew_SenseHiTV( HwDeviceExtension , pVBInfo) ) /* add by kuku for Dysense HiTV //start */
371 {
372 bConnectStatus|= YPbPrSense ;
373 }
374 else
375 {
376 tempbx = XGI330_YCSenseData2 ; /* Y/C Sense Data Ptr */
377 tempcx = 0x0604 ;
378 if ( XGINew_Sense( tempbx , tempcx , pVBInfo) )
379 bConnectStatus |= SVIDEOSense ;
380
381 if ( OutputSelect & BoardTVType )
382 {
383 tempbx = XGI330_VideoSenseData2 ;
384 tempcx = 0x0804 ;
385 if ( XGINew_Sense(tempbx , tempcx, pVBInfo) )
386 bConnectStatus|= AVIDEOSense ;
387 }
388 else
389 {
390 if ( !( bConnectStatus & SVIDEOSense ) )
391 {
392 tempbx = XGI330_VideoSenseData2 ;
393 tempcx = 0x0804 ;
394 if ( XGINew_Sense( tempbx , tempcx, pVBInfo ) )
395 bConnectStatus |= AVIDEOSense ;
396 }
397 }
398 } /* end */
399 /* DySenseVBCnt */
400
401 tempbx = 0 ;
402 tempcx = 0 ;
403 XGINew_Sense(tempbx , tempcx, pVBInfo ) ;
404
405 if ( !( bConnectStatus & Monitor2Sense ) )
406 {
407 if ( XGI_SenseLCD( pHWDE , pVBInfo ) )
408 bConnectStatus |= LCDSense ;
409 }
410
411 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~( AVIDEOSense | SVIDEOSense | LCDSense | Monitor2Sense | Monitor1Sense ) , bConnectStatus ) ;
412
413 XGINew_SetReg1( pVBInfo->Part4Port , 0x0D , pre_Part4_D ) ;
414 XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , pre_Part2_0 ) ;
415 XGINew_SetReg1( pVBInfo->P3c4 , 0x1E , pre_SR1E ) ;
416
417 if ( XGI_Is301C( pVBInfo ) ) /* 301C only */
418 {
419 tempax = XGINew_GetReg1( pVBInfo->Part2Port , 0x00 ) ;
420 if ( tempax & 0x20 )
421 {
422 /* Reset VBPro */
423 for( tempcx = 2 ; tempcx > 0 ; tempcx-- )
424 {
425 tempax ^= 0x20 ;
426 XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , tempax ) ;
427 }
428 }
429 }
430 /* End of dynamic sense VB */
431 }
432 else
433 {
434 XGI_SenseCRT1(pVBInfo) ;
435 XGI_GetSenseStatus( HwDeviceExtension, pVBInfo ) ; /* sense CRT2 */
436 bConnectStatus = XGINew_GetReg1( pVBInfo->P3d4 , 0x32 ) ;
437 }
438 temp = pushax & 0x00FF ; /* 0512 Fix Dysense hanged */
439 XGINew_SetReg1( pVBInfo->P3d4 , 0x17 , temp ) ;
440 if ( bConnectStatus )
441 {
442 *ujConnectStatus = bConnectStatus ;
443 return( 1 ) ;
444 }
445 else
446 return( 0 ) ;
447}
448
449#endif /* WIN2000 */
450
451/* --------------------------------------------------------------------- */
452/* Function : XGISetDPMS */
453/* Input : */
454/* Output : */
455/* Description : */
456/* --------------------------------------------------------------------- */
457VOID XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE )
458{
459 USHORT ModeNo, ModeIdIndex ;
460 UCHAR temp ;
461 VB_DEVICE_INFO VBINF;
462 PVB_DEVICE_INFO pVBInfo = &VBINF;
463 pVBInfo->BaseAddr = (ULONG)pXGIHWDE->pjIOAddress ;
464 pVBInfo->ROMAddr = pXGIHWDE->pjVirtualRomBase ;
465
466
467 pVBInfo->IF_DEF_LVDS = 0 ;
468 pVBInfo->IF_DEF_CH7005 = 0 ;
469 pVBInfo->IF_DEF_HiVision = 1 ;
470 pVBInfo->IF_DEF_LCDA = 1 ;
471 pVBInfo->IF_DEF_CH7017 = 0 ;
472 pVBInfo->IF_DEF_YPbPr = 1 ;
473 pVBInfo->IF_DEF_CRT2Monitor = 0 ;
474 pVBInfo->IF_DEF_VideoCapture = 0 ;
475 pVBInfo->IF_DEF_ScaleLCD = 0 ;
476 pVBInfo->IF_DEF_OEMUtil = 0 ;
477 pVBInfo->IF_DEF_PWD = 0 ;
478
479 InitTo330Pointer( pXGIHWDE->jChipType, pVBInfo ) ;
480 ReadVBIOSTablData( pXGIHWDE->jChipType , pVBInfo) ;
481
482 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
483 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
484 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
485 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
486 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
487 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
488 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
489 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
490 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
491 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
492 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
493 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
494 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
495 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
496 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
497 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
498 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
499
500 if ( pXGIHWDE->jChipType == XG27 )
501 {
502 if ( ( XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) & 0xE0 ) == 0xC0 )
503 {
504 if ( XGINew_GetReg1( pVBInfo->P3d4 , 0x30 ) & 0x20 )
505 {
506 pVBInfo->IF_DEF_LVDS = 1 ;
507 }
508 }
509 }
510
511 if ( pVBInfo->IF_DEF_CH7007 == 0 )
512 {
513 XGINew_SetModeScratch ( pXGIHWDE , pVBInfo ) ;
514 }
515 XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ; /* 1.Openkey */
516 XGI_UnLockCRT2( pXGIHWDE , pVBInfo) ;
517 ModeNo = XGINew_GetReg1( pVBInfo->P3d4 , 0x34 ) ;
518 XGI_SearchModeID( ModeNo , &ModeIdIndex, pVBInfo ) ;
519 XGI_GetVGAType( pXGIHWDE , pVBInfo ) ;
520
521 if ( ( pXGIHWDE->ujVBChipID == VB_CHIP_301 ) || ( pXGIHWDE->ujVBChipID == VB_CHIP_302 ) || ( pVBInfo->IF_DEF_CH7007 == 1 ))
522 {
523 XGI_GetVBType( pVBInfo ) ;
524 XGI_GetVBInfo( ModeNo , ModeIdIndex , pXGIHWDE, pVBInfo ) ;
525 XGI_GetTVInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
526 XGI_GetLCDInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
527 }
528
529 if ( VESA_POWER_STATE == 0x00000400 )
530 XGINew_SetReg1( pVBInfo->Part4Port , 0x31 , ( UCHAR )( XGINew_GetReg1( pVBInfo->Part4Port , 0x31 ) & 0xFE ) ) ;
531 else
532 XGINew_SetReg1( pVBInfo->Part4Port , 0x31 , ( UCHAR )( XGINew_GetReg1( pVBInfo->Part4Port , 0x31 ) | 0x01 ) ) ;
533
534 temp = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x1f ) ;
535 temp &= 0x3f ;
536 switch ( VESA_POWER_STATE )
537 {
538 case 0x00000000: /* on */
539 if ( ( pXGIHWDE->ujVBChipID == VB_CHIP_301 ) || ( pXGIHWDE->ujVBChipID == VB_CHIP_302 ) )
540 {
541 XGINew_SetReg1( pVBInfo->P3c4 , 0x1f , ( UCHAR )( temp | 0x00 ) ) ;
542 XGI_EnableBridge( pXGIHWDE, pVBInfo ) ;
543 }
544 else
545 {
546 if ( pXGIHWDE->jChipType == XG21 )
547 {
548 if ( pVBInfo->IF_DEF_LVDS == 1 )
549 {
550 XGI_XG21BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
551 XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
552 }
553 }
554 if ( pXGIHWDE->jChipType == XG27 )
555 {
556 if ( pVBInfo->IF_DEF_LVDS == 1 )
557 {
558 XGI_XG27BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
559 XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
560 }
561 }
562 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1F , ~0xC0 , 0x00 ) ;
563 XGINew_SetRegAND( pVBInfo->P3c4 , 0x01 , ~0x20 ) ; /* CRT on */
564
565 if ( pXGIHWDE->jChipType == XG21 )
566 {
567 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
568 if ( temp & 0xE0 )
569 {
570 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0x80 , 0x80 ) ; /* DVO ON */
571 XGI_SetXG21FPBits( pVBInfo );
572 XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Enable write GPIOF */
573 /*XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x48 , ~0x20 , 0x20 ) ;*/ /* LCD Display ON */
574 }
575 XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
576 XGI_DisplayOn( pXGIHWDE, pVBInfo );
577 }
578 if ( pXGIHWDE->jChipType == XG27 )
579 {
580 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
581 if ( temp & 0xE0 )
582 {
583 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0x80 , 0x80 ) ; /* DVO ON */
584 XGI_SetXG27FPBits( pVBInfo );
585 XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Enable write GPIOF */
586 /*XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x48 , ~0x20 , 0x20 ) ;*/ /* LCD Display ON */
587 }
588 XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
589 XGI_DisplayOn( pXGIHWDE, pVBInfo );
590 }
591 }
592 break ;
593 case 0x00000100: /* standby */
594 if ( pXGIHWDE->jChipType >= XG21 )
595 {
596 XGI_DisplayOff( pXGIHWDE, pVBInfo );
597 }
598
599 XGINew_SetReg1( pVBInfo->P3c4 , 0x1f , ( UCHAR )( temp | 0x40 ) ) ;
600 break ;
601 case 0x00000200: /* suspend */
602 if ( pXGIHWDE->jChipType == XG21 )
603 {
604 XGI_DisplayOff( pXGIHWDE, pVBInfo );
605 XGI_XG21BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
606 }
607 if ( pXGIHWDE->jChipType == XG27 )
608 {
609 XGI_DisplayOff( pXGIHWDE, pVBInfo );
610 XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
611 }
612 XGINew_SetReg1( pVBInfo->P3c4 , 0x1f , ( UCHAR )( temp | 0x80 ) ) ;
613 break ;
614 case 0x00000400: /* off */
615 if ( (pXGIHWDE->ujVBChipID == VB_CHIP_301 ) || ( pXGIHWDE->ujVBChipID == VB_CHIP_302 ) )
616 {
617 XGINew_SetReg1( pVBInfo->P3c4 , 0x1f , ( UCHAR )( temp | 0xc0 ) ) ;
618 XGI_DisableBridge( pXGIHWDE, pVBInfo ) ;
619 }
620 else
621 {
622 if ( pXGIHWDE->jChipType == XG21 )
623 {
624 XGI_DisplayOff( pXGIHWDE, pVBInfo );
625
626 XGI_XG21BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
627
628 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
629 if ( temp & 0xE0 )
630 {
631 XGINew_SetRegAND( pVBInfo->P3c4 , 0x09 , ~0x80 ) ; /* DVO Off */
632 XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Enable write GPIOF */
633 /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x48 , ~0x20 ) ;*/ /* LCD Display OFF */
634 }
635 }
636 if ( pXGIHWDE->jChipType == XG27 )
637 {
638 XGI_DisplayOff( pXGIHWDE, pVBInfo );
639
640 XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
641
642 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
643 if ( temp & 0xE0 )
644 {
645 XGINew_SetRegAND( pVBInfo->P3c4 , 0x09 , ~0x80 ) ; /* DVO Off */
646 }
647 }
648 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1F , ~0xC0 , 0xC0 ) ;
649 XGINew_SetRegOR( pVBInfo->P3c4 , 0x01 , 0x20 ) ; /* CRT Off */
650
651 if ( ( pXGIHWDE->jChipType == XG21 ) && ( pVBInfo->IF_DEF_LVDS == 1 ) )
652 {
653 XGI_XG21SetPanelDelay( 4,pVBInfo ) ;
654 XGI_XG21BLSignalVDD( 0x01 , 0x00, pVBInfo ) ; /* LVDS VDD off */
655 XGI_XG21SetPanelDelay( 5,pVBInfo ) ;
656 }
657 if ( ( pXGIHWDE->jChipType == XG27 ) && ( pVBInfo->IF_DEF_LVDS == 1 ) )
658 {
659 XGI_XG21SetPanelDelay( 4,pVBInfo ) ;
660 XGI_XG27BLSignalVDD( 0x01 , 0x00, pVBInfo ) ; /* LVDS VDD off */
661 XGI_XG21SetPanelDelay( 5,pVBInfo ) ;
662 }
663 }
664 break ;
665
666 default:
667 break ;
668 }
669 XGI_LockCRT2( pXGIHWDE , pVBInfo ) ;
670}
671
672
673
674/* --------------------------------------------------------------------- */
675/* Function : XGI_GetSenseStatus */
676/* Input : */
677/* Output : */
678/* Description : */
679/* --------------------------------------------------------------------- */
680void XGI_GetSenseStatus( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
681{
682 USHORT tempax = 0 , tempbx , tempcx , temp ,
683 P2reg0 = 0 , SenseModeNo = 0 , OutputSelect = *pVBInfo->pOutputSelect ,
684 ModeIdIndex , i ;
685 pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
686
687 if ( pVBInfo->IF_DEF_LVDS == 1 )
688 {
689 tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x1A ) ; /* ynlai 02/27/2002 */
690 tempbx = XGINew_GetReg1( pVBInfo->P3c4 , 0x1B ) ;
691 tempax = ( ( tempax & 0xFE ) >> 1 ) | ( tempbx << 8 ) ;
692 if ( tempax == 0x00 )
693 { /* Get Panel id from DDC */
694 temp = XGINew_GetLCDDDCInfo( HwDeviceExtension, pVBInfo ) ;
695 if ( temp == 1 )
696 { /* LCD connect */
697 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x39 , 0xFF , 0x01 ) ; /* set CR39 bit0="1" */
698 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , 0xEF , 0x00 ) ; /* clean CR37 bit4="0" */
699 temp = LCDSense ;
700 }
701 else
702 { /* LCD don't connect */
703 temp = 0 ;
704 }
705 }
706 else
707 {
708 XGINew_GetPanelID(pVBInfo) ;
709 temp = LCDSense ;
710 }
711
712 tempbx = ~( LCDSense | AVIDEOSense | SVIDEOSense ) ;
713 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , tempbx , temp ) ;
714 }
715 else
716 { /* for 301 */
717 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
718 { /* for HiVision */
719 tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x38 ) ;
720 temp = tempax & 0x01 ;
721 tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x3A ) ;
722 temp = temp | ( tempax & 0x02 ) ;
723 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , 0xA0 , temp ) ;
724 }
725 else
726 {
727 if ( XGI_BridgeIsOn( pVBInfo ) )
728 {
729 P2reg0 = XGINew_GetReg1( pVBInfo->Part2Port , 0x00 ) ;
730 if ( !XGINew_BridgeIsEnable( HwDeviceExtension, pVBInfo ) )
731 {
732 SenseModeNo = 0x2e ;
733 /* XGINew_SetReg1( pVBInfo->P3d4 , 0x30 , 0x41 ) ; */
734 /* XGISetModeNew( HwDeviceExtension , 0x2e ) ; // ynlai InitMode */
735
736 temp = XGI_SearchModeID( SenseModeNo , &ModeIdIndex, pVBInfo ) ;
737 XGI_GetVGAType( HwDeviceExtension , pVBInfo) ;
738 XGI_GetVBType( pVBInfo ) ;
739 pVBInfo->SetFlag = 0x00 ;
740 pVBInfo->ModeType = ModeVGA ;
741 pVBInfo->VBInfo = SetCRT2ToRAMDAC | LoadDACFlag | SetInSlaveMode ;
742 XGI_GetLCDInfo( 0x2e , ModeIdIndex, pVBInfo ) ;
743 XGI_GetTVInfo( 0x2e , ModeIdIndex, pVBInfo ) ;
744 XGI_EnableBridge( HwDeviceExtension, pVBInfo ) ;
745 XGI_SetCRT2Group301( SenseModeNo , HwDeviceExtension, pVBInfo ) ;
746 XGI_SetCRT2ModeRegs( 0x2e , HwDeviceExtension, pVBInfo ) ;
747 /* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */
748 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xDF , 0x20 ) ; /* Display Off 0212 */
749 for( i = 0 ; i < 20 ; i++ )
750 {
751 XGI_LongWait(pVBInfo) ;
752 }
753 }
754 XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , 0x1c ) ;
755 tempax = 0 ;
756 tempbx = *pVBInfo->pRGBSenseData ;
757
758 if ( !( XGINew_Is301B( pVBInfo ) ) )
759 {
760 tempbx = *pVBInfo->pRGBSenseData2 ;
761 }
762
763 tempcx = 0x0E08 ;
764 if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
765 {
766 if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
767 {
768 tempax |= Monitor2Sense ;
769 }
770 }
771
772 if ( pVBInfo->VBType & VB_XGI301C)
773 {
774 XGINew_SetRegOR( pVBInfo->Part4Port , 0x0d , 0x04 ) ;
775 }
776
777 if ( XGINew_SenseHiTV( HwDeviceExtension , pVBInfo) ) /* add by kuku for Multi-adapter sense HiTV */
778 {
779 tempax |= HiTVSense ;
780 if ( ( pVBInfo->VBType & VB_XGI301C ) )
781 {
782 tempax ^= ( HiTVSense | YPbPrSense ) ;
783 }
784 }
785
786 if ( !( tempax & ( HiTVSense | YPbPrSense ) ) ) /* start */
787 {
788
789 tempbx = *pVBInfo->pYCSenseData ;
790
791 if ( !( XGINew_Is301B( pVBInfo ) ) )
792 {
793 tempbx=*pVBInfo->pYCSenseData2;
794 }
795
796 tempcx = 0x0604 ;
797 if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
798 {
799 if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
800 {
801 tempax |= SVIDEOSense ;
802 }
803 }
804
805 if ( OutputSelect & BoardTVType )
806 {
807 tempbx = *pVBInfo->pVideoSenseData ;
808
809 if ( !( XGINew_Is301B( pVBInfo ) ) )
810 {
811 tempbx = *pVBInfo->pVideoSenseData2 ;
812 }
813
814 tempcx = 0x0804 ;
815 if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
816 {
817 if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
818 {
819 tempax |= AVIDEOSense ;
820 }
821 }
822 }
823 else
824 {
825 if ( !( tempax & SVIDEOSense ) )
826 {
827 tempbx = *pVBInfo->pVideoSenseData ;
828
829 if ( !( XGINew_Is301B( pVBInfo ) ) )
830 {
831 tempbx=*pVBInfo->pVideoSenseData2;
832 }
833
834 tempcx = 0x0804 ;
835 if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
836 {
837 if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
838 {
839 tempax |= AVIDEOSense ;
840 }
841 }
842 }
843 }
844 }
845 } /* end */
846 if ( !( tempax & Monitor2Sense ) )
847 {
848 if ( XGINew_SenseLCD( HwDeviceExtension, pVBInfo ) )
849 {
850 tempax |= LCDSense ;
851 }
852 }
853 tempbx = 0 ;
854 tempcx = 0 ;
855 XGINew_Sense(tempbx , tempcx, pVBInfo ) ;
856
857 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~0xDF , tempax ) ;
858 XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , P2reg0 ) ;
859
860 if ( !( P2reg0 & 0x20 ) )
861 {
862 pVBInfo->VBInfo = DisableCRT2Display ;
863 /* XGI_SetCRT2Group301( SenseModeNo , HwDeviceExtension, pVBInfo ) ; */
864 }
865 }
866 }
867 XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; /* shampoo 0226 */
868
869}
870
871
872
873/* --------------------------------------------------------------------- */
874/* Function : XGINew_SenseLCD */
875/* Input : */
876/* Output : */
877/* Description : */
878/* --------------------------------------------------------------------- */
879USHORT XGINew_SenseLCD( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
880{
881 /* USHORT SoftSetting ; */
882 USHORT temp ;
883
884 if ( ( HwDeviceExtension->jChipType >= XG20 ) || ( HwDeviceExtension->jChipType >= XG40 ) )
885 temp = 0 ;
886 else
887 temp=XGINew_GetPanelID(pVBInfo) ;
888
889 if( !temp )
890 temp = XGINew_GetLCDDDCInfo( HwDeviceExtension, pVBInfo ) ;
891
892 return( temp ) ;
893}
894
895
896/* --------------------------------------------------------------------- */
897/* Function : XGINew_GetLCDDDCInfo */
898/* Input : */
899/* Output : */
900/* Description : */
901/* --------------------------------------------------------------------- */
902BOOLEAN XGINew_GetLCDDDCInfo( PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo)
903{
904 USHORT temp ;
905
906 /* add lcd sense */
907 if ( HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN )
908 {
909 return( 0 ) ;
910 }
911 else
912 {
913 temp = ( USHORT )HwDeviceExtension->ulCRT2LCDType ;
914 switch( HwDeviceExtension->ulCRT2LCDType )
915 {
916 case LCD_INVALID:
917 case LCD_800x600:
918 case LCD_1024x768:
919 case LCD_1280x1024:
920 break ;
921
922 case LCD_640x480:
923 case LCD_1024x600:
924 case LCD_1152x864:
925 case LCD_1280x960:
926 case LCD_1152x768:
927 temp = 0 ;
928 break ;
929
930 case LCD_1400x1050:
931 case LCD_1280x768:
932 case LCD_1600x1200:
933 break ;
934
935 case LCD_1920x1440:
936 case LCD_2048x1536:
937 temp = 0 ;
938 break ;
939
940 default:
941 break ;
942 }
943 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x36 , 0xF0 , temp ) ;
944 return( 1 ) ;
945 }
946}
947
948
949/* --------------------------------------------------------------------- */
950/* Function : */
951/* Input : */
952/* Output : */
953/* Description : */
954/* --------------------------------------------------------------------- */
955BOOLEAN XGINew_GetPanelID(PVB_DEVICE_INFO pVBInfo )
956{
957 USHORT PanelTypeTable[ 16 ] = { SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType00 ,
958 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01 ,
959 SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType02 ,
960 SyncNN | PanelRGB18Bit | Panel640x480 | _PanelType03 ,
961 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04 ,
962 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05 ,
963 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06 ,
964 SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07 ,
965 SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType08 ,
966 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09 ,
967 SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType0A ,
968 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B ,
969 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C ,
970 SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D ,
971 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E ,
972 SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F } ;
973 USHORT tempax , tempbx , temp ;
974 /* USHORT return_flag ; */
975
976 tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x1A ) ;
977 tempbx = tempax & 0x1E ;
978
979 if ( tempax == 0 )
980 return( 0 ) ;
981 else
982 {
983/*
984 if ( !( tempax & 0x10 ) )
985 {
986 if ( pVBInfo->IF_DEF_LVDS == 1 )
987 {
988 tempbx = 0 ;
989 temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x38 ) ;
990 if ( temp & 0x40 )
991 tempbx |= 0x08 ;
992 if ( temp & 0x20 )
993 tempbx |= 0x02 ;
994 if ( temp & 0x01 )
995 tempbx |= 0x01 ;
996
997 temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x39 ) ;
998 if ( temp & 0x80 )
999 tempbx |= 0x04 ;
1000 }
1001 else
1002 {
1003 return( 0 ) ;
1004 }
1005 }
1006*/
1007
1008 tempbx = tempbx >> 1 ;
1009 temp = tempbx & 0x00F ;
1010 XGINew_SetReg1( pVBInfo->P3d4 , 0x36 , temp ) ;
1011 tempbx-- ;
1012 tempbx = PanelTypeTable[ tempbx ] ;
1013
1014 temp = ( tempbx & 0xFF00 ) >> 8 ;
1015 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , ~( LCDSyncBit | LCDRGB18Bit ) , temp ) ;
1016 return( 1 ) ;
1017 }
1018}
1019
1020
1021/* --------------------------------------------------------------------- */
1022/* Function : XGINew_BridgeIsEnable */
1023/* Input : */
1024/* Output : */
1025/* Description : */
1026/* --------------------------------------------------------------------- */
1027BOOLEAN XGINew_BridgeIsEnable( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
1028{
1029 USHORT flag ;
1030
1031 if ( XGI_BridgeIsOn( pVBInfo ) == 0 )
1032 {
1033 flag = XGINew_GetReg1( pVBInfo->Part1Port , 0x0 ) ;
1034
1035 if ( flag & 0x050 )
1036 {
1037 return( 1 ) ;
1038 }
1039 else
1040 {
1041 return( 0 ) ;
1042 }
1043
1044 }
1045 return( 0 ) ;
1046}
1047
1048/* ------------------------------------------------------ */
1049/* Function : XGINew_SenseHiTV */
1050/* Input : */
1051/* Output : */
1052/* Description : */
1053/* ------------------------------------------------------ */
1054BOOLEAN XGINew_SenseHiTV( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo )
1055{
1056 USHORT tempbx , tempcx , temp , i , tempch;
1057
1058 tempbx = *pVBInfo->pYCSenseData2 ;
1059
1060 tempcx = 0x0604 ;
1061
1062 temp = tempbx & 0xFF ;
1063 XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
1064 temp = ( tempbx & 0xFF00 ) >> 8 ;
1065 temp |= ( tempcx & 0x00FF ) ;
1066 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x10 , ~0x1F , temp ) ;
1067
1068 for( i = 0 ; i < 10 ; i++ )
1069 XGI_LongWait(pVBInfo) ;
1070
1071 tempch = ( tempcx & 0xFF00 ) >> 8;
1072 temp = XGINew_GetReg1( pVBInfo->Part4Port , 0x03 ) ;
1073 temp = temp ^ ( 0x0E ) ;
1074 temp &= tempch ;
1075
1076 if ( temp != tempch )
1077 return( 0 ) ;
1078
1079 tempbx = *pVBInfo->pVideoSenseData2 ;
1080
1081 tempcx = 0x0804 ;
1082 temp = tempbx & 0xFF ;
1083 XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
1084 temp = ( tempbx & 0xFF00 ) >> 8 ;
1085 temp |= ( tempcx & 0x00FF ) ;
1086 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x10 , ~0x1F , temp ) ;
1087
1088 for( i = 0 ; i < 10 ; i++ )
1089 XGI_LongWait(pVBInfo) ;
1090
1091 tempch = ( tempcx & 0xFF00 ) >> 8;
1092 temp = XGINew_GetReg1( pVBInfo->Part4Port , 0x03 ) ;
1093 temp = temp ^ ( 0x0E ) ;
1094 temp &= tempch ;
1095
1096 if ( temp != tempch )
1097 return( 0 ) ;
1098 else
1099 {
1100 tempbx = 0x3FF ;
1101 tempcx = 0x0804 ;
1102 temp = tempbx & 0xFF ;
1103 XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
1104 temp = ( tempbx & 0xFF00 ) >> 8 ;
1105 temp |= ( tempcx & 0x00FF ) ;
1106 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x10 , ~0x1F , temp ) ;
1107
1108 for( i = 0 ; i < 10 ; i++ )
1109 XGI_LongWait(pVBInfo) ;
1110
1111 tempch = ( tempcx & 0xFF00 ) >> 8;
1112 temp = XGINew_GetReg1( pVBInfo->Part4Port , 0x03 ) ;
1113 temp = temp ^ ( 0x0E ) ;
1114 temp &= tempch ;
1115
1116 if ( temp != tempch )
1117 return( 1 ) ;
1118 else
1119 return( 0 ) ;
1120 }
1121}
1122
1123
1124
1125/*
1126;-----------------------------------------------------------------------------
1127; Description: Get Panel support
1128; O/P :
1129; BL: Panel ID=81h for no scaler LVDS
1130; BH: Panel enhanced Mode Count
1131; CX: Panel H. resolution
1132; DX: PAnel V. resolution
1133;-----------------------------------------------------------------------------
1134*/
1135void XGI_XG21Fun14Sub70( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
1136{
1137
1138 USHORT ModeIdIndex;
1139 USHORT ModeNo;
1140
1141 USHORT EModeCount;
1142 USHORT lvdstableindex;
1143
1144 lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
1145 pBiosArguments->h.bl = 0x81;
1146 pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
1147 pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
1148 EModeCount = 0;
1149
1150 pBiosArguments->x.ax = 0x0014;
1151 for( ModeIdIndex = 0 ; ; ModeIdIndex ++ )
1152 {
1153 ModeNo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID;
1154 if ( pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID == 0xFF )
1155 {
1156 pBiosArguments->h.bh = (UCHAR) EModeCount;
1157 return;
1158 }
1159 if ( !XGI_XG21CheckLVDSMode( ModeNo , ModeIdIndex, pVBInfo) )
1160 {
1161 continue;
1162 }
1163 EModeCount++ ;
1164 }
1165}
1166/*(
1167;-----------------------------------------------------------------------------
1168;
1169; Description: Get Panel mode ID for enhanced mode
1170; I/P : BH: EModeIndex ( which < Panel enhanced Mode Count )
1171; O/P :
1172; BL: Mode ID
1173; CX: H. resolution of the assigned by the index
1174; DX: V. resolution of the assigned by the index
1175;
1176;-----------------------------------------------------------------------------
1177*/
1178void XGI_XG21Fun14Sub71( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
1179{
1180
1181 USHORT EModeCount;
1182 USHORT ModeIdIndex,resindex;
1183 USHORT ModeNo;
1184 USHORT EModeIndex = pBiosArguments->h.bh;
1185
1186 EModeCount = 0;
1187 for( ModeIdIndex = 0 ; ; ModeIdIndex ++ )
1188 {
1189 ModeNo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID;
1190 if ( pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID == 0xFF )
1191 {
1192 pBiosArguments->x.ax = 0x0114;
1193 return;
1194 }
1195 if ( !XGI_XG21CheckLVDSMode( ModeNo , ModeIdIndex, pVBInfo) )
1196 {
1197 continue;
1198 }
1199 if (EModeCount == EModeIndex)
1200 {
1201 resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
1202 pBiosArguments->h.bl = (UCHAR) ModeNo;
1203 pBiosArguments->x.cx = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
1204 pBiosArguments->x.dx = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
1205 pBiosArguments->x.ax = 0x0014;
1206 }
1207 EModeCount++ ;
1208
1209 }
1210
1211}
1212/*
1213;-----------------------------------------------------------------------------
1214;
1215; Description: Validate Panel modes ID support
1216; I/P :
1217; BL: ModeID
1218; O/P :
1219; CX: H. resolution of the assigned by the index
1220; DX: V. resolution of the assigned by the index
1221;
1222;-----------------------------------------------------------------------------
1223*/
1224void XGI_XG21Fun14Sub72( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
1225{
1226 USHORT ModeIdIndex,resindex;
1227 USHORT ModeNo;
1228
1229
1230 ModeNo = pBiosArguments->h.bl ;
1231 XGI_SearchModeID( ModeNo, &ModeIdIndex, pVBInfo);
1232 if ( !XGI_XG21CheckLVDSMode( ModeNo , ModeIdIndex, pVBInfo) )
1233 {
1234 pBiosArguments->x.cx = 0;
1235 pBiosArguments->x.dx = 0;
1236 pBiosArguments->x.ax = 0x0114;
1237 return;
1238 }
1239 resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
1240 if ( ModeNo <= 0x13 )
1241 {
1242 pBiosArguments->x.cx = pVBInfo->StResInfo[ resindex ].HTotal ;
1243 pBiosArguments->x.dx = pVBInfo->StResInfo[ resindex ].VTotal ;
1244 }
1245 else
1246 {
1247 pBiosArguments->x.cx = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
1248 pBiosArguments->x.dx = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
1249 }
1250
1251 pBiosArguments->x.ax = 0x0014;
1252
1253}
1254
1255/*
1256;-----------------------------------------------------------------------------
1257; Description: Get Customized Panel misc. information support
1258; I/P : Select
1259; to get panel horizontal timing
1260; to get panel vertical timing
1261; to get channel clock parameter
1262; to get panel misc information
1263;
1264; O/P :
1265; BL: for input Select = 0 ;
1266; BX: *Value1 = Horizontal total
1267; CX: *Value2 = Horizontal front porch
1268; DX: *Value2 = Horizontal sync width
1269; BL: for input Select = 1 ;
1270; BX: *Value1 = Vertical total
1271; CX: *Value2 = Vertical front porch
1272; DX: *Value2 = Vertical sync width
1273; BL: for input Select = 2 ;
1274; BX: Value1 = The first CLK parameter
1275; CX: Value2 = The second CLK parameter
1276; BL: for input Select = 4 ;
1277; BX[15]: *Value1 D[15] VESA V. Polarity
1278; BX[14]: *Value1 D[14] VESA H. Polarity
1279; BX[7]: *Value1 D[7] Panel V. Polarity
1280; BX[6]: *Value1 D[6] Panel H. Polarity
1281;-----------------------------------------------------------------------------
1282*/
1283void XGI_XG21Fun14Sub73( PVB_DEVICE_INFO pVBInfo , PX86_REGS pBiosArguments )
1284{
1285 UCHAR Select;
1286
1287 USHORT lvdstableindex;
1288
1289 lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
1290 Select = pBiosArguments->h.bl;
1291
1292 switch (Select)
1293 {
1294 case 0:
1295 pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
1296 pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
1297 pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
1298 break;
1299 case 1:
1300 pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
1301 pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
1302 pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
1303 break;
1304 case 2:
1305 pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1;
1306 pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2;
1307 break;
1308 case 4:
1309 pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability;
1310 break;
1311 }
1312
1313 pBiosArguments->x.ax = 0x0014;
1314}
1315
1316
1317void XGI_XG21Fun14( PXGI_HW_DEVICE_INFO pXGIHWDE, PX86_REGS pBiosArguments)
1318{
1319 VB_DEVICE_INFO VBINF;
1320 PVB_DEVICE_INFO pVBInfo = &VBINF;
1321
1322 pVBInfo->IF_DEF_LVDS = 0 ;
1323 pVBInfo->IF_DEF_CH7005 = 0 ;
1324 pVBInfo->IF_DEF_HiVision = 1 ;
1325 pVBInfo->IF_DEF_LCDA = 1 ;
1326 pVBInfo->IF_DEF_CH7017 = 0 ;
1327 pVBInfo->IF_DEF_YPbPr = 1 ;
1328 pVBInfo->IF_DEF_CRT2Monitor = 0 ;
1329 pVBInfo->IF_DEF_VideoCapture = 0 ;
1330 pVBInfo->IF_DEF_ScaleLCD = 0 ;
1331 pVBInfo->IF_DEF_OEMUtil = 0 ;
1332 pVBInfo->IF_DEF_PWD = 0 ;
1333
1334 InitTo330Pointer( pXGIHWDE->jChipType, pVBInfo ) ;
1335 ReadVBIOSTablData( pXGIHWDE->jChipType , pVBInfo) ;
1336
1337 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
1338 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
1339 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
1340 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
1341 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
1342 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
1343 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
1344 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
1345 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
1346 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
1347 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
1348 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
1349 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
1350 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
1351 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
1352 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
1353 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
1354
1355 switch(pBiosArguments->x.ax)
1356 {
1357 case 0x1470:
1358 XGI_XG21Fun14Sub70( pVBInfo , pBiosArguments ) ;
1359 break;
1360 case 0x1471:
1361 XGI_XG21Fun14Sub71( pVBInfo , pBiosArguments ) ;
1362 break;
1363 case 0x1472:
1364 XGI_XG21Fun14Sub72( pVBInfo , pBiosArguments ) ;
1365 break;
1366 case 0x1473:
1367 XGI_XG21Fun14Sub73( pVBInfo , pBiosArguments ) ;
1368 break;
1369 }
1370}
diff --git a/drivers/staging/xgifb/vb_ext.h b/drivers/staging/xgifb/vb_ext.h
new file mode 100644
index 000000000000..9a72f5ecb713
--- /dev/null
+++ b/drivers/staging/xgifb/vb_ext.h
@@ -0,0 +1,32 @@
1#ifndef _VBEXT_
2#define _VBEXT_
3
4struct DWORDREGS {
5 ULONG Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp;
6};
7
8struct WORDREGS {
9 USHORT ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si, hi_si, di ,hi_di, bp, hi_bp;
10};
11
12struct BYTEREGS {
13 UCHAR al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch, hi_cl, hi_ch, dl, dh, hi_dl, hi_dh;
14};
15
16typedef union _X86_REGS {
17 struct DWORDREGS e;
18 struct WORDREGS x;
19 struct BYTEREGS h;
20} X86_REGS, *PX86_REGS;
21
22extern void XGI_XG21Fun14( PXGI_HW_DEVICE_INFO pXGIHWDE, PX86_REGS pBiosArguments);
23extern void XGISetDPMS( PXGI_HW_DEVICE_INFO pXGIHWDE , ULONG VESA_POWER_STATE ) ;
24extern void XGI_GetSenseStatus( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo );
25extern void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
26extern void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo);
27extern USHORT XGINew_SenseLCD(PXGI_HW_DEVICE_INFO,PVB_DEVICE_INFO pVBInfo);
28#ifdef WIN2000
29extern BOOLEAN XGI_DySense( PHW_DEVICE_EXTENSION pHWDE , PUCHAR ujConnectStatus );
30#endif /* WIN2000 */
31
32#endif
diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c
new file mode 100644
index 000000000000..b85ca9ba8076
--- /dev/null
+++ b/drivers/staging/xgifb/vb_init.c
@@ -0,0 +1,3444 @@
1#include "osdef.h"
2#include "vgatypes.h"
3
4
5#ifdef LINUX_KERNEL
6#include <linux/version.h>
7#include <linux/types.h>
8#include <linux/delay.h> /* udelay */
9#include "XGIfb.h"
10/*#if LINUX_VERSxION_CODE >= KERNEL_VERSION(2,5,0)
11#include <video/XGIfb.h>
12#else
13#include <linux/XGIfb.h>
14#endif */
15#endif
16
17#ifdef WIN2000
18#include <dderror.h>
19#include <devioctl.h>
20#include <miniport.h>
21#include <ntddvdeo.h>
22#include <video.h>
23#include "xgiv.h"
24#include "dd_i2c.h"
25#include "tools.h"
26#endif
27
28#include "vb_def.h"
29#include "vb_struct.h"
30#include "vb_util.h"
31#include "vb_setmode.h"
32#include "vb_init.h"
33#include "vb_ext.h"
34
35#ifdef LINUX_XF86
36#include "xf86.h"
37#include "xf86PciInfo.h"
38#include "xgi.h"
39#include "xgi_regs.h"
40#endif
41
42#ifdef LINUX_KERNEL
43#include <asm/io.h>
44#include <linux/types.h>
45#endif
46
47
48
49
50UCHAR XGINew_ChannelAB,XGINew_DataBusWidth;
51
52USHORT XGINew_DRAMType[17][5]={{0x0C,0x0A,0x02,0x40,0x39},{0x0D,0x0A,0x01,0x40,0x48},
53 {0x0C,0x09,0x02,0x20,0x35},{0x0D,0x09,0x01,0x20,0x44},
54 {0x0C,0x08,0x02,0x10,0x31},{0x0D,0x08,0x01,0x10,0x40},
55 {0x0C,0x0A,0x01,0x20,0x34},{0x0C,0x09,0x01,0x08,0x32},
56 {0x0B,0x08,0x02,0x08,0x21},{0x0C,0x08,0x01,0x08,0x30},
57 {0x0A,0x08,0x02,0x04,0x11},{0x0B,0x0A,0x01,0x10,0x28},
58 {0x09,0x08,0x02,0x02,0x01},{0x0B,0x09,0x01,0x08,0x24},
59 {0x0B,0x08,0x01,0x04,0x20},{0x0A,0x08,0x01,0x02,0x10},
60 {0x09,0x08,0x01,0x01,0x00}};
61
62USHORT XGINew_SDRDRAM_TYPE[13][5]=
63{
64{ 2,12, 9,64,0x35},
65{ 1,13, 9,64,0x44},
66{ 2,12, 8,32,0x31},
67{ 2,11, 9,32,0x25},
68{ 1,12, 9,32,0x34},
69{ 1,13, 8,32,0x40},
70{ 2,11, 8,16,0x21},
71{ 1,12, 8,16,0x30},
72{ 1,11, 9,16,0x24},
73{ 1,11, 8, 8,0x20},
74{ 2, 9, 8, 4,0x01},
75{ 1,10, 8, 4,0x10},
76{ 1, 9, 8, 2,0x00}
77};
78
79USHORT XGINew_DDRDRAM_TYPE[4][5]=
80{
81{ 2,12, 9,64,0x35},
82{ 2,12, 8,32,0x31},
83{ 2,11, 8,16,0x21},
84{ 2, 9, 8, 4,0x01}
85};
86USHORT XGINew_DDRDRAM_TYPE340[4][5]=
87{
88{ 2,13, 9,64,0x45},
89{ 2,12, 9,32,0x35},
90{ 2,12, 8,16,0x31},
91{ 2,11, 8, 8,0x21}
92};
93USHORT XGINew_DDRDRAM_TYPE20[12][5]=
94{
95{ 2,14,11,128,0x5D},
96{ 2,14,10,64,0x59},
97{ 2,13,11,64,0x4D},
98{ 2,14, 9,32,0x55},
99{ 2,13,10,32,0x49},
100{ 2,12,11,32,0x3D},
101{ 2,14, 8,16,0x51},
102{ 2,13, 9,16,0x45},
103{ 2,12,10,16,0x39},
104{ 2,13, 8, 8,0x41},
105{ 2,12, 9, 8,0x35},
106{ 2,12, 8, 4,0x31}
107};
108
109void XGINew_SetDRAMSize_340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
110void XGINew_SetDRAMSize_310(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
111void XGINew_SetMemoryClock(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
112void XGINew_SetDRAMModeRegister(PVB_DEVICE_INFO );
113void XGINew_SetDRAMModeRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension );
114void XGINew_SetDRAMDefaultRegister340(PXGI_HW_DEVICE_INFO HwDeviceExtension, ULONG, PVB_DEVICE_INFO );
115UCHAR XGINew_GetXG20DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo);
116BOOLEAN XGIInitNew( PXGI_HW_DEVICE_INFO HwDeviceExtension) ;
117
118int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
119void XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO ,PVB_DEVICE_INFO) ;
120void XGINew_CheckBusWidth_310( PVB_DEVICE_INFO) ;
121int XGINew_SDRSizing(PVB_DEVICE_INFO);
122int XGINew_DDRSizing( PVB_DEVICE_INFO );
123void XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
124int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
125ULONG UNIROM; /* UNIROM */
126BOOLEAN ChkLFB( PVB_DEVICE_INFO );
127void XGINew_Delay15us(ULONG);
128void SetPowerConsume (PXGI_HW_DEVICE_INFO HwDeviceExtension,ULONG XGI_P3d4Port);
129void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo);
130void XGINew_DDR1x_MRS_XG20( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo);
131void XGINew_SetDRAMModeRegister_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension );
132void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension );
133void XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
134void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
135void XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
136UCHAR GetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
137void XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
138UCHAR GetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
139
140#ifdef WIN2000
141/* [Billy] 2007/05/20 For CH7007 */
142extern UCHAR CH7007TVReg_UNTSC[][8],CH7007TVReg_ONTSC[][8],CH7007TVReg_UPAL[][8],CH7007TVReg_OPAL[][8];
143extern UCHAR XGI7007_CHTVVCLKUNTSC[],XGI7007_CHTVVCLKONTSC[],XGI7007_CHTVVCLKUPAL[],XGI7007_CHTVVCLKOPAL[];
144#endif
145
146#ifdef LINUX_KERNEL
147void DelayUS(ULONG MicroSeconds)
148{
149 udelay(MicroSeconds);
150}
151#endif
152
153/* --------------------------------------------------------------------- */
154/* Function : XGIInitNew */
155/* Input : */
156/* Output : */
157/* Description : */
158/* --------------------------------------------------------------------- */
159BOOLEAN XGIInitNew( PXGI_HW_DEVICE_INFO HwDeviceExtension )
160{
161
162 VB_DEVICE_INFO VBINF;
163 PVB_DEVICE_INFO pVBInfo = &VBINF;
164 UCHAR i , temp = 0 , temp1 ;
165 // VBIOSVersion[ 5 ] ;
166 PUCHAR volatile pVideoMemory;
167
168 /* ULONG j, k ; */
169
170 PXGI_DSReg pSR ;
171
172 ULONG Temp ;
173
174 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
175
176 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
177
178 pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
179
180 pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr;
181
182
183// Newdebugcode( 0x99 ) ;
184
185
186 /* if ( pVBInfo->ROMAddr == 0 ) */
187 /* return( FALSE ) ; */
188
189 if ( pVBInfo->FBAddr == 0 )
190{
191 printk("\n pVBInfo->FBAddr == 0 ");
192 return( FALSE ) ;
193}
194printk("1");
195 if ( pVBInfo->BaseAddr == 0 )
196{
197 printk("\npVBInfo->BaseAddr == 0 ");
198 return( FALSE ) ;
199}
200printk("2");
201
202 XGINew_SetReg3( ( pVBInfo->BaseAddr + 0x12 ) , 0x67 ) ; /* 3c2 <- 67 ,ynlai */
203
204 pVBInfo->ISXPDOS = 0 ;
205printk("3");
206
207if ( !HwDeviceExtension->bIntegratedMMEnabled )
208{
209 return( FALSE ) ; /* alan */
210}
211printk("4");
212
213// XGI_MemoryCopy( VBIOSVersion , HwDeviceExtension->szVBIOSVer , 4 ) ;
214
215 // VBIOSVersion[ 4 ] = 0x0 ;
216
217 /* 09/07/99 modify by domao */
218
219 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
220 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
221 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
222 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
223 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
224 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
225 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
226 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
227 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
228 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
229 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
230 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
231 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
232 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
233 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
234 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
235 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
236printk("5");
237
238 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
239 XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
240
241 InitTo330Pointer( HwDeviceExtension->jChipType, pVBInfo ) ;
242
243 /* ReadVBIOSData */
244 ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
245
246 /* 1.Openkey */
247 XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
248printk("6");
249
250 /* GetXG21Sense (GPIO) */
251 if ( HwDeviceExtension->jChipType == XG21 )
252 {
253 XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo) ;
254 }
255 if ( HwDeviceExtension->jChipType == XG27 )
256 {
257 XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo) ;
258 }
259printk("7");
260
261 /* 2.Reset Extended register */
262
263 for( i = 0x06 ; i < 0x20 ; i++ )
264 XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ;
265
266 for( i = 0x21 ; i <= 0x27 ; i++ )
267 XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ;
268
269 /* for( i = 0x06 ; i <= 0x27 ; i++ ) */
270 /* XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ; */
271
272printk("8");
273
274 if(( HwDeviceExtension->jChipType >= XG20 ) || ( HwDeviceExtension->jChipType >= XG40))
275 {
276 for( i = 0x31 ; i <= 0x3B ; i++ )
277 XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ;
278 }
279 else
280 {
281 for( i = 0x31 ; i <= 0x3D ; i++ )
282 XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ;
283 }
284printk("9");
285
286 if ( HwDeviceExtension->jChipType == XG42 ) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
287 XGINew_SetReg1( pVBInfo->P3c4 , 0x3B , 0xC0 ) ;
288
289 /* for( i = 0x30 ; i <= 0x3F ; i++ ) */
290 /* XGINew_SetReg1( pVBInfo->P3d4 , i , 0 ) ; */
291
292 for( i = 0x79 ; i <= 0x7C ; i++ )
293 XGINew_SetReg1( pVBInfo->P3d4 , i , 0 ) ; /* shampoo 0208 */
294
295printk("10");
296
297 if ( HwDeviceExtension->jChipType >= XG20 )
298 XGINew_SetReg1( pVBInfo->P3d4 , 0x97 , *pVBInfo->pXGINew_CR97 ) ;
299
300 /* 3.SetMemoryClock
301
302 if ( HwDeviceExtension->jChipType >= XG40 )
303 XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo) ;
304
305 if ( HwDeviceExtension->jChipType < XG40 )
306 XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ; */
307
308printk("11");
309
310 /* 4.SetDefExt1Regs begin */
311 XGINew_SetReg1( pVBInfo->P3c4 , 0x07 , *pVBInfo->pSR07 ) ;
312 if ( HwDeviceExtension->jChipType == XG27 )
313 {
314 XGINew_SetReg1( pVBInfo->P3c4 , 0x40 , *pVBInfo->pSR40 ) ;
315 XGINew_SetReg1( pVBInfo->P3c4 , 0x41 , *pVBInfo->pSR41 ) ;
316 }
317 XGINew_SetReg1( pVBInfo->P3c4 , 0x11 , 0x0F ) ;
318 XGINew_SetReg1( pVBInfo->P3c4 , 0x1F , *pVBInfo->pSR1F ) ;
319 /* XGINew_SetReg1( pVBInfo->P3c4 , 0x20 , 0x20 ) ; */
320 XGINew_SetReg1( pVBInfo->P3c4 , 0x20 , 0xA0 ) ; /* alan, 2001/6/26 Frame buffer can read/write SR20 */
321 XGINew_SetReg1( pVBInfo->P3c4 , 0x36 , 0x70 ) ; /* Hsuan, 2006/01/01 H/W request for slow corner chip */
322 if ( HwDeviceExtension->jChipType == XG27 ) /* Alan 12/07/2006 */
323 XGINew_SetReg1( pVBInfo->P3c4 , 0x36 , *pVBInfo->pSR36 ) ;
324
325 /* SR11 = 0x0F ; */
326 /* XGINew_SetReg1( pVBInfo->P3c4 , 0x11 , SR11 ) ; */
327
328printk("12");
329
330 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
331 {
332// /* Set AGP Rate */
333// temp1 = XGINew_GetReg1( pVBInfo->P3c4 , 0x3B ) ;
334// temp1 &= 0x02 ;
335// if ( temp1 == 0x02 )
336// {
337// XGINew_SetReg4( 0xcf8 , 0x80000000 ) ;
338// ChipsetID = XGINew_GetReg3( 0x0cfc ) ;
339// XGINew_SetReg4( 0xcf8 , 0x8000002C ) ;
340// VendorID = XGINew_GetReg3( 0x0cfc ) ;
341// VendorID &= 0x0000FFFF ;
342// XGINew_SetReg4( 0xcf8 , 0x8001002C ) ;
343// GraphicVendorID = XGINew_GetReg3( 0x0cfc ) ;
344// GraphicVendorID &= 0x0000FFFF;
345//
346// if ( ChipsetID == 0x7301039 )
347/// XGINew_SetReg1( pVBInfo->P3d4 , 0x5F , 0x09 ) ;
348//
349// ChipsetID &= 0x0000FFFF ;
350///
351// if ( ( ChipsetID == 0x700E ) || ( ChipsetID == 0x1022 ) || ( ChipsetID == 0x1106 ) || ( ChipsetID == 0x10DE ) )
352// {
353// if ( ChipsetID == 0x1106 )
354// {
355// if ( ( VendorID == 0x1019 ) && ( GraphicVendorID == 0x1019 ) )
356// XGINew_SetReg1( pVBInfo->P3d4 , 0x5F , 0x0D ) ;
357// else
358// XGINew_SetReg1( pVBInfo->P3d4 , 0x5F , 0x0B ) ;
359// }
360// else
361// XGINew_SetReg1( pVBInfo->P3d4 , 0x5F , 0x0B ) ;
362// }
363// }
364
365printk("13");
366
367 if ( HwDeviceExtension->jChipType >= XG40 )
368 {
369 /* Set AGP customize registers (in SetDefAGPRegs) Start */
370 for( i = 0x47 ; i <= 0x4C ; i++ )
371 XGINew_SetReg1( pVBInfo->P3d4 , i , pVBInfo->AGPReg[ i - 0x47 ] ) ;
372
373 for( i = 0x70 ; i <= 0x71 ; i++ )
374 XGINew_SetReg1( pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 6 + i - 0x70 ] ) ;
375
376 for( i = 0x74 ; i <= 0x77 ; i++ )
377 XGINew_SetReg1( pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 8 + i - 0x74 ] ) ;
378 /* Set AGP customize registers (in SetDefAGPRegs) End */
379 /*[Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
380// XGINew_SetReg4( 0xcf8 , 0x80000000 ) ;
381// ChipsetID = XGINew_GetReg3( 0x0cfc ) ;
382// if ( ChipsetID == 0x25308086 )
383// XGINew_SetReg1( pVBInfo->P3d4 , 0x77 , 0xF0 ) ;
384
385 HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x50 , 0 , &Temp ) ; /* Get */
386 Temp >>= 20 ;
387 Temp &= 0xF ;
388
389 if ( Temp == 1 )
390 XGINew_SetReg1( pVBInfo->P3d4 , 0x48 , 0x20 ) ; /* CR48 */
391 }
392printk("14");
393
394 if ( HwDeviceExtension->jChipType < XG40 )
395 XGINew_SetReg1( pVBInfo->P3d4 , 0x49 , pVBInfo->CR49[ 0 ] ) ;
396 } /* != XG20 */
397
398 /* Set PCI */
399 XGINew_SetReg1( pVBInfo->P3c4 , 0x23 , *pVBInfo->pSR23 ) ;
400 XGINew_SetReg1( pVBInfo->P3c4 , 0x24 , *pVBInfo->pSR24 ) ;
401 XGINew_SetReg1( pVBInfo->P3c4 , 0x25 , pVBInfo->SR25[ 0 ] ) ;
402printk("15");
403
404 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
405 {
406 /* Set VB */
407 XGI_UnLockCRT2( HwDeviceExtension, pVBInfo) ;
408 XGINew_SetRegANDOR( pVBInfo->Part0Port , 0x3F , 0xEF , 0x00 ) ; /* alan, disable VideoCapture */
409 XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , 0x00 ) ;
410 temp1 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x7B ) ; /* chk if BCLK>=100MHz */
411 temp = ( UCHAR )( ( temp1 >> 4 ) & 0x0F ) ;
412
413
414 XGINew_SetReg1( pVBInfo->Part1Port , 0x02 , ( *pVBInfo->pCRT2Data_1_2 ) ) ;
415
416printk("16");
417
418 XGINew_SetReg1( pVBInfo->Part1Port , 0x2E , 0x08 ) ; /* use VB */
419 } /* != XG20 */
420
421
422 XGINew_SetReg1( pVBInfo->P3c4 , 0x27 , 0x1F ) ;
423
424 if ( ( HwDeviceExtension->jChipType == XG42 ) && XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo) != 0 ) /* Not DDR */
425 {
426 XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , ( *pVBInfo->pSR31 & 0x3F ) | 0x40 ) ;
427 XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , ( *pVBInfo->pSR32 & 0xFC ) | 0x01 ) ;
428 }
429 else
430 {
431 XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , *pVBInfo->pSR31 ) ;
432 XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , *pVBInfo->pSR32 ) ;
433 }
434 XGINew_SetReg1( pVBInfo->P3c4 , 0x33 , *pVBInfo->pSR33 ) ;
435printk("17");
436
437/*
438 if ( HwDeviceExtension->jChipType >= XG40 )
439 SetPowerConsume ( HwDeviceExtension , pVBInfo->P3c4); */
440
441 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
442 {
443 if ( XGI_BridgeIsOn( pVBInfo ) == 1 )
444 {
445 if ( pVBInfo->IF_DEF_LVDS == 0 )
446 {
447 XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , 0x1C ) ;
448 XGINew_SetReg1( pVBInfo->Part4Port , 0x0D , *pVBInfo->pCRT2Data_4_D ) ;
449 XGINew_SetReg1( pVBInfo->Part4Port , 0x0E , *pVBInfo->pCRT2Data_4_E ) ;
450 XGINew_SetReg1( pVBInfo->Part4Port , 0x10 , *pVBInfo->pCRT2Data_4_10 ) ;
451 XGINew_SetReg1( pVBInfo->Part4Port , 0x0F , 0x3F ) ;
452 }
453
454 XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
455 }
456 } /* != XG20 */
457printk("18");
458
459 if ( HwDeviceExtension->jChipType < XG40 )
460 XGINew_SetReg1( pVBInfo->P3d4 , 0x83 , 0x00 ) ;
461printk("181");
462
463 if ( HwDeviceExtension->bSkipSense == FALSE )
464 {
465printk("182");
466
467 XGI_SenseCRT1(pVBInfo) ;
468
469printk("183");
470 /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
471pVBInfo->IF_DEF_CH7007 = 0;
472 if ( ( HwDeviceExtension->jChipType == XG21 ) && (pVBInfo->IF_DEF_CH7007) )
473 {
474printk("184");
475 XGI_GetSenseStatus( HwDeviceExtension , pVBInfo ) ; /* sense CRT2 */
476printk("185");
477
478 }
479 if ( HwDeviceExtension->jChipType == XG21 )
480 {
481printk("186");
482
483 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~Monitor1Sense , Monitor1Sense ) ; /* Z9 default has CRT */
484 temp = GetXG21FPBits( pVBInfo ) ;
485 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , ~0x01, temp ) ;
486printk("187");
487
488 }
489 if ( HwDeviceExtension->jChipType == XG27 )
490 {
491 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~Monitor1Sense , Monitor1Sense ) ; /* Z9 default has CRT */
492 temp = GetXG27FPBits( pVBInfo ) ;
493 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , ~0x03, temp ) ;
494 }
495 }
496printk("19");
497
498 if ( HwDeviceExtension->jChipType >= XG40 )
499 {
500 if ( HwDeviceExtension->jChipType >= XG40 )
501 {
502 XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
503 }
504
505 XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
506
507 if ( HwDeviceExtension->bSkipDramSizing == TRUE )
508 {
509 pSR = HwDeviceExtension->pSR ;
510 if ( pSR!=NULL )
511 {
512 while( pSR->jIdx != 0xFF )
513 {
514 XGINew_SetReg1( pVBInfo->P3c4 , pSR->jIdx , pSR->jVal ) ;
515 pSR++ ;
516 }
517 }
518 /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
519 } /* SkipDramSizing */
520 else
521 {
522#if 0
523 if ( HwDeviceExtension->jChipType == XG20 )
524 {
525 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , pVBInfo->SR15[0][XGINew_RAMType] ) ;
526 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , pVBInfo->SR15[1][XGINew_RAMType] ) ;
527 XGINew_SetReg1( pVBInfo->P3c4 , 0x20 , 0x20 ) ;
528 }
529 else
530#endif
531{
532printk("20");
533
534 XGINew_SetDRAMSize_340( HwDeviceExtension , pVBInfo) ;
535}
536printk("21");
537
538 }
539 } /* XG40 */
540
541printk("22");
542
543
544 /* SetDefExt2Regs begin */
545/*
546 AGP = 1 ;
547 temp =( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x3A ) ;
548 temp &= 0x30 ;
549 if ( temp == 0x30 )
550 AGP = 0 ;
551
552 if ( AGP == 0 )
553 *pVBInfo->pSR21 &= 0xEF ;
554
555 XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , *pVBInfo->pSR21 ) ;
556 if ( AGP == 1 )
557 *pVBInfo->pSR22 &= 0x20 ;
558 XGINew_SetReg1( pVBInfo->P3c4 , 0x22 , *pVBInfo->pSR22 ) ;
559*/
560
561// base = 0x80000000 ;
562// OutPortLong( 0xcf8 , base ) ;
563// Temp = ( InPortLong( 0xcfc ) & 0xFFFF ) ;
564// if ( Temp == 0x1039 )
565// {
566 XGINew_SetReg1( pVBInfo->P3c4 , 0x22 , ( UCHAR )( ( *pVBInfo->pSR22 ) & 0xFE ) ) ;
567// }
568// else
569// {
570// XGINew_SetReg1( pVBInfo->P3c4 , 0x22 , *pVBInfo->pSR22 ) ;
571// }
572
573 XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , *pVBInfo->pSR21 ) ;
574
575printk("23");
576
577
578 XGINew_ChkSenseStatus ( HwDeviceExtension , pVBInfo ) ;
579 XGINew_SetModeScratch ( HwDeviceExtension , pVBInfo ) ;
580
581printk("24");
582
583
584XGINew_SetReg1( pVBInfo->P3d4 , 0x8c , 0x87);
585XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x31);
586printk("25");
587
588 return( TRUE ) ;
589} /* end of init */
590
591
592
593
594
595/* ============== alan ====================== */
596
597/* --------------------------------------------------------------------- */
598/* Function : XGINew_GetXG20DRAMType */
599/* Input : */
600/* Output : */
601/* Description : */
602/* --------------------------------------------------------------------- */
603UCHAR XGINew_GetXG20DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
604{
605 UCHAR data, temp ;
606
607 if ( HwDeviceExtension->jChipType < XG20 )
608 {
609 if ( *pVBInfo->pSoftSetting & SoftDRAMType )
610 {
611 data = *pVBInfo->pSoftSetting & 0x07 ;
612 return( data ) ;
613 }
614 else
615 {
616 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x39 ) & 0x02 ;
617
618 if ( data == 0 )
619 data = ( XGINew_GetReg1( pVBInfo->P3c4 , 0x3A ) & 0x02 ) >> 1 ;
620
621 return( data ) ;
622 }
623 }
624 else if ( HwDeviceExtension->jChipType == XG27 )
625 {
626 if ( *pVBInfo->pSoftSetting & SoftDRAMType )
627 {
628 data = *pVBInfo->pSoftSetting & 0x07 ;
629 return( data ) ;
630 }
631 temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x3B ) ;
632
633 if (( temp & 0x88 )==0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
634 data = 0 ; /*DDR*/
635 else
636 data = 1 ; /*DDRII*/
637 return( data ) ;
638 }
639 else if ( HwDeviceExtension->jChipType == XG21 )
640 {
641 XGINew_SetRegAND( pVBInfo->P3d4 , 0xB4 , ~0x02 ) ; /* Independent GPIO control */
642 DelayUS(800);
643 XGINew_SetRegOR( pVBInfo->P3d4 , 0x4A , 0x80 ) ; /* Enable GPIOH read */
644 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ; /* GPIOF 0:DVI 1:DVO */
645// HOTPLUG_SUPPORT
646// for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily
647 if ( temp & 0x01 ) /* DVI read GPIOH */
648 data = 1 ; /*DDRII*/
649 else
650 data = 0 ; /*DDR*/
651//~HOTPLUG_SUPPORT
652 XGINew_SetRegOR( pVBInfo->P3d4 , 0xB4 , 0x02 ) ;
653 return( data ) ;
654 }
655 else
656 {
657 data = XGINew_GetReg1( pVBInfo->P3d4 , 0x97 ) & 0x01 ;
658
659 if ( data == 1 )
660 data ++ ;
661
662 return( data );
663 }
664}
665
666
667/* --------------------------------------------------------------------- */
668/* Function : XGINew_Get310DRAMType */
669/* Input : */
670/* Output : */
671/* Description : */
672/* --------------------------------------------------------------------- */
673UCHAR XGINew_Get310DRAMType(PVB_DEVICE_INFO pVBInfo)
674{
675 UCHAR data ;
676
677 /* index = XGINew_GetReg1( pVBInfo->P3c4 , 0x1A ) ; */
678 /* index &= 07 ; */
679
680 if ( *pVBInfo->pSoftSetting & SoftDRAMType )
681 data = *pVBInfo->pSoftSetting & 0x03 ;
682 else
683 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x3a ) & 0x03 ;
684
685 return( data ) ;
686}
687
688
689
690/* --------------------------------------------------------------------- */
691/* Function : XGINew_Delay15us */
692/* Input : */
693/* Output : */
694/* Description : */
695/* --------------------------------------------------------------------- */
696/*
697void XGINew_Delay15us(ULONG ulMicrsoSec)
698{
699}
700*/
701
702
703/* --------------------------------------------------------------------- */
704/* Function : XGINew_SDR_MRS */
705/* Input : */
706/* Output : */
707/* Description : */
708/* --------------------------------------------------------------------- */
709void XGINew_SDR_MRS( PVB_DEVICE_INFO pVBInfo )
710{
711 USHORT data ;
712
713 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x16 ) ;
714 data &= 0x3F ; /* SR16 D7=0,D6=0 */
715 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) low */
716 /* XGINew_Delay15us( 0x100 ) ; */
717 data |= 0x80 ; /* SR16 D7=1,D6=0 */
718 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) high */
719 /* XGINew_Delay15us( 0x100 ) ; */
720}
721
722
723/* --------------------------------------------------------------------- */
724/* Function : XGINew_DDR1x_MRS_340 */
725/* Input : */
726/* Output : */
727/* Description : */
728/* --------------------------------------------------------------------- */
729void XGINew_DDR1x_MRS_340( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
730{
731 XGINew_SetReg1( P3c4 , 0x18 , 0x01 ) ;
732 XGINew_SetReg1( P3c4 , 0x19 , 0x20 ) ;
733 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
734 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
735
736 if ( *pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C ) /* Samsung F Die */
737 {
738 DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
739 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ;
740 XGINew_SetReg1( P3c4 , 0x19 , 0x20 ) ;
741 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
742 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
743 }
744
745 DelayUS( 60 ) ;
746 XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
747 XGINew_SetReg1( P3c4 , 0x19 , 0x01 ) ;
748 XGINew_SetReg1( P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
749 XGINew_SetReg1( P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
750 DelayUS( 1000 ) ;
751 XGINew_SetReg1( P3c4 , 0x1B , 0x03 ) ;
752 DelayUS( 500 ) ;
753 XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
754 XGINew_SetReg1( P3c4 , 0x19 , 0x00 ) ;
755 XGINew_SetReg1( P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
756 XGINew_SetReg1( P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
757 XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ;
758}
759
760
761/* --------------------------------------------------------------------- */
762/* Function : XGINew_DDR2x_MRS_340 */
763/* Input : */
764/* Output : */
765/* Description : */
766/* --------------------------------------------------------------------- */
767void XGINew_DDR2x_MRS_340( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
768{
769 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ;
770 XGINew_SetReg1( P3c4 , 0x19 , 0x20 ) ;
771 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
772 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
773 DelayUS( 60 ) ;
774 XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
775 /* XGINew_SetReg1( P3c4 , 0x18 , 0x31 ) ; */
776 XGINew_SetReg1( P3c4 , 0x19 , 0x01 ) ;
777 XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
778 XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
779 DelayUS( 1000 ) ;
780 XGINew_SetReg1( P3c4 , 0x1B , 0x03 ) ;
781 DelayUS( 500 ) ;
782 /* XGINew_SetReg1( P3c4 , 0x18 , 0x31 ) ; */
783 XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
784 XGINew_SetReg1( P3c4 , 0x19 , 0x00 ) ;
785 XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
786 XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
787 XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ;
788}
789
790/* --------------------------------------------------------------------- */
791/* Function : XGINew_DDRII_Bootup_XG27 */
792/* Input : */
793/* Output : */
794/* Description : */
795/* --------------------------------------------------------------------- */
796void XGINew_DDRII_Bootup_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
797{
798 ULONG P3d4 = P3c4 + 0x10 ;
799 XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
800 XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
801
802 /* Set Double Frequency */
803 /* XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ; */ /* CR97 */
804 XGINew_SetReg1( P3d4 , 0x97 , *pVBInfo->pXGINew_CR97 ) ; /* CR97 */
805
806 DelayUS( 200 ) ;
807
808 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ //EMRS2
809 XGINew_SetReg1( P3c4 , 0x19 , 0x80 ) ; /* Set SR19 */
810 XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
811 DelayUS( 15 ) ;
812 XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
813 DelayUS( 15 ) ;
814
815 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ //EMRS3
816 XGINew_SetReg1( P3c4 , 0x19 , 0xC0 ) ; /* Set SR19 */
817 XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
818 DelayUS( 15 ) ;
819 XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
820 DelayUS( 15) ;
821
822 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ //EMRS1
823 XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ; /* Set SR19 */
824 XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
825 DelayUS( 30 ) ;
826 XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
827 DelayUS( 15 ) ;
828
829 XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* Set SR18 */ //MRS, DLL Enable
830 XGINew_SetReg1( P3c4 , 0x19 , 0x0A ) ; /* Set SR19 */
831 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
832 DelayUS( 30 ) ;
833 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
834 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ; /* Set SR16 */
835 /* DelayUS( 15 ) ; */
836
837 XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* Set SR1B */
838 DelayUS( 60 ) ;
839 XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ; /* Set SR1B */
840
841 XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* Set SR18 */ //MRS, DLL Reset
842 XGINew_SetReg1( P3c4 , 0x19 , 0x08 ) ; /* Set SR19 */
843 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
844
845 DelayUS( 30 ) ;
846 XGINew_SetReg1( P3c4 , 0x16 , 0x83 ) ; /* Set SR16 */
847 DelayUS( 15 ) ;
848
849 XGINew_SetReg1( P3c4 , 0x18 , 0x80 ) ; /* Set SR18 */ //MRS, ODT
850 XGINew_SetReg1( P3c4 , 0x19 , 0x46 ) ; /* Set SR19 */
851 XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
852 DelayUS( 30 ) ;
853 XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
854 DelayUS( 15 ) ;
855
856 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ //EMRS
857 XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ; /* Set SR19 */
858 XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
859 DelayUS( 30 ) ;
860 XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
861 DelayUS( 15 ) ;
862
863 XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* Set SR1B refresh control 000:close; 010:open */
864 DelayUS( 200 ) ;
865
866
867}
868/* --------------------------------------------------------------------- */
869/* Function : XGINew_DDR2_MRS_XG20 */
870/* Input : */
871/* Output : */
872/* Description : */
873/* --------------------------------------------------------------------- */
874void XGINew_DDR2_MRS_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
875{
876 ULONG P3d4 = P3c4 + 0x10 ;
877
878 XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
879 XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
880
881 XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ; /* CR97 */
882
883 DelayUS( 200 ) ;
884 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS2 */
885 XGINew_SetReg1( P3c4 , 0x19 , 0x80 ) ;
886 XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
887 XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
888
889 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS3 */
890 XGINew_SetReg1( P3c4 , 0x19 , 0xC0 ) ;
891 XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
892 XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
893
894 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS1 */
895 XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ;
896 XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
897 XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
898
899 // XGINew_SetReg1( P3c4 , 0x18 , 0x52 ) ; /* MRS1 */
900 XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
901 XGINew_SetReg1( P3c4 , 0x19 , 0x02 ) ;
902 XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
903 XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
904
905 DelayUS( 15 ) ;
906 XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* SR1B */
907 DelayUS( 30 ) ;
908 XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ; /* SR1B */
909 DelayUS( 100 ) ;
910
911 //XGINew_SetReg1( P3c4 , 0x18 , 0x52 ) ; /* MRS2 */
912 XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
913 XGINew_SetReg1( P3c4 , 0x19 , 0x00 ) ;
914 XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
915 XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
916
917 DelayUS( 200 ) ;
918}
919
920/* --------------------------------------------------------------------- */
921/* Function : XGINew_DDR2_MRS_XG20 */
922/* Input : */
923/* Output : */
924/* Description : */
925/* --------------------------------------------------------------------- */
926void XGINew_DDR2_MRS_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
927{
928 ULONG P3d4 = P3c4 + 0x10 ;
929
930 XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
931 XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
932
933 XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ; /* CR97 */
934 DelayUS( 200 ) ;
935 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS2 */
936 XGINew_SetReg1( P3c4 , 0x19 , 0x80 ) ;
937
938 XGINew_SetReg1( P3c4 , 0x16 , 0x10 ) ;
939 DelayUS( 15 ) ; ////06/11/23 XG27 A0 for CKE enable
940 XGINew_SetReg1( P3c4 , 0x16 , 0x90 ) ;
941
942 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS3 */
943 XGINew_SetReg1( P3c4 , 0x19 , 0xC0 ) ;
944
945 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
946 DelayUS( 15 ) ; ////06/11/22 XG27 A0
947 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
948
949
950 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS1 */
951 XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ;
952
953 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
954 DelayUS( 15 ) ; ////06/11/22 XG27 A0
955 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
956
957 XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
958 XGINew_SetReg1( P3c4 , 0x19 , 0x06 ) ; ////[Billy]06/11/22 DLL Reset for XG27 Hynix DRAM
959
960 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
961 DelayUS( 15 ) ; ////06/11/23 XG27 A0
962 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
963
964 DelayUS( 30 ) ; ////06/11/23 XG27 A0 Start Auto-PreCharge
965 XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* SR1B */
966 DelayUS( 60 ) ;
967 XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ; /* SR1B */
968
969
970 XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
971 XGINew_SetReg1( P3c4 , 0x19 , 0x04 ) ; //// DLL without Reset for XG27 Hynix DRAM
972
973 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
974 DelayUS( 30 ) ;
975 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
976
977 XGINew_SetReg1( P3c4 , 0x18 , 0x80 ); ////XG27 OCD ON
978 XGINew_SetReg1( P3c4 , 0x19 , 0x46 );
979
980 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
981 DelayUS( 30 ) ;
982 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
983
984 XGINew_SetReg1( P3c4 , 0x18 , 0x00 );
985 XGINew_SetReg1( P3c4 , 0x19 , 0x40 );
986
987 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
988 DelayUS( 30 ) ;
989 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
990
991 DelayUS( 15 ) ; ////Start Auto-PreCharge
992 XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* SR1B */
993 DelayUS( 200 ) ;
994 XGINew_SetReg1( P3c4 , 0x1B , 0x03 ) ; /* SR1B */
995
996}
997
998/* --------------------------------------------------------------------- */
999/* Function : XGINew_DDR1x_DefaultRegister */
1000/* Input : */
1001/* Output : */
1002/* Description : */
1003/* --------------------------------------------------------------------- */
1004void XGINew_DDR1x_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG Port , PVB_DEVICE_INFO pVBInfo)
1005{
1006 ULONG P3d4 = Port ,
1007 P3c4 = Port - 0x10 ;
1008
1009 if ( HwDeviceExtension->jChipType >= XG20 )
1010 {
1011 XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
1012 XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
1013 XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
1014 XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
1015
1016 XGINew_SetReg1( P3d4 , 0x98 , 0x01 ) ;
1017 XGINew_SetReg1( P3d4 , 0x9A , 0x02 ) ;
1018
1019 XGINew_DDR1x_MRS_XG20( P3c4 , pVBInfo) ;
1020 }
1021 else
1022 {
1023 XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
1024
1025 switch( HwDeviceExtension->jChipType )
1026 {
1027 case XG41:
1028 case XG42:
1029 XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
1030 XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
1031 XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
1032 break ;
1033 default:
1034 XGINew_SetReg1( P3d4 , 0x82 , 0x88 ) ;
1035 XGINew_SetReg1( P3d4 , 0x86 , 0x00 ) ;
1036 XGINew_GetReg1( P3d4 , 0x86 ) ; /* Insert read command for delay */
1037 XGINew_SetReg1( P3d4 , 0x86 , 0x88 ) ;
1038 XGINew_GetReg1( P3d4 , 0x86 ) ;
1039 XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ;
1040 XGINew_SetReg1( P3d4 , 0x82 , 0x77 ) ;
1041 XGINew_SetReg1( P3d4 , 0x85 , 0x00 ) ;
1042 XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
1043 XGINew_SetReg1( P3d4 , 0x85 , 0x88 ) ;
1044 XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
1045 XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
1046 XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
1047 break ;
1048 }
1049
1050 XGINew_SetReg1( P3d4 , 0x97 , 0x00 ) ;
1051 XGINew_SetReg1( P3d4 , 0x98 , 0x01 ) ;
1052 XGINew_SetReg1( P3d4 , 0x9A , 0x02 ) ;
1053 XGINew_DDR1x_MRS_340( P3c4 , pVBInfo ) ;
1054 }
1055}
1056
1057
1058/* --------------------------------------------------------------------- */
1059/* Function : XGINew_DDR2x_DefaultRegister */
1060/* Input : */
1061/* Output : */
1062/* Description : */
1063/* --------------------------------------------------------------------- */
1064void XGINew_DDR2x_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG Port ,PVB_DEVICE_INFO pVBInfo)
1065{
1066 ULONG P3d4 = Port ,
1067 P3c4 = Port - 0x10 ;
1068
1069 XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
1070
1071 /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */
1072 switch( HwDeviceExtension->jChipType )
1073 {
1074 case XG41:
1075 case XG42:
1076 XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
1077 XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
1078 XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
1079 break ;
1080 default:
1081 /* keep following setting sequence, each setting in the same reg insert idle */
1082 XGINew_SetReg1( P3d4 , 0x82 , 0x88 ) ;
1083 XGINew_SetReg1( P3d4 , 0x86 , 0x00 ) ;
1084 XGINew_GetReg1( P3d4 , 0x86 ) ; /* Insert read command for delay */
1085 XGINew_SetReg1( P3d4 , 0x86 , 0x88 ) ;
1086 XGINew_SetReg1( P3d4 , 0x82 , 0x77 ) ;
1087 XGINew_SetReg1( P3d4 , 0x85 , 0x00 ) ;
1088 XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
1089 XGINew_SetReg1( P3d4 , 0x85 , 0x88 ) ;
1090 XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
1091 XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
1092 XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
1093 }
1094 XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ;
1095 if ( HwDeviceExtension->jChipType == XG42 )
1096 {
1097 XGINew_SetReg1( P3d4 , 0x98 , 0x01 ) ;
1098 }
1099 else
1100 {
1101 XGINew_SetReg1( P3d4 , 0x98 , 0x03 ) ;
1102 }
1103 XGINew_SetReg1( P3d4 , 0x9A , 0x02 ) ;
1104
1105 XGINew_DDR2x_MRS_340( P3c4 , pVBInfo ) ;
1106}
1107
1108
1109/* --------------------------------------------------------------------- */
1110/* Function : XGINew_DDR2_DefaultRegister */
1111/* Input : */
1112/* Output : */
1113/* Description : */
1114/* --------------------------------------------------------------------- */
1115void XGINew_DDR2_DefaultRegister( PXGI_HW_DEVICE_INFO HwDeviceExtension, ULONG Port , PVB_DEVICE_INFO pVBInfo)
1116{
1117 ULONG P3d4 = Port ,
1118 P3c4 = Port - 0x10 ;
1119
1120 /* keep following setting sequence, each setting in the same reg insert idle */
1121 XGINew_SetReg1( P3d4 , 0x82 , 0x77 ) ;
1122 XGINew_SetReg1( P3d4 , 0x86 , 0x00 ) ;
1123 XGINew_GetReg1( P3d4 , 0x86 ) ; /* Insert read command for delay */
1124 XGINew_SetReg1( P3d4 , 0x86 , 0x88 ) ;
1125 XGINew_GetReg1( P3d4 , 0x86 ) ; /* Insert read command for delay */
1126 XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
1127 XGINew_SetReg1( P3d4 , 0x82 , 0x77 ) ;
1128 XGINew_SetReg1( P3d4 , 0x85 , 0x00 ) ;
1129 XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
1130 XGINew_SetReg1( P3d4 , 0x85 , 0x88 ) ;
1131 XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
1132 XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
1133 if ( HwDeviceExtension->jChipType == XG27 )
1134 XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
1135 else
1136 XGINew_SetReg1( P3d4 , 0x82 , 0xA8 ) ; /* CR82 */
1137
1138 XGINew_SetReg1( P3d4 , 0x98 , 0x01 ) ;
1139 XGINew_SetReg1( P3d4 , 0x9A , 0x02 ) ;
1140 if ( HwDeviceExtension->jChipType == XG27 )
1141 XGINew_DDRII_Bootup_XG27( HwDeviceExtension , P3c4 , pVBInfo) ;
1142 else
1143 XGINew_DDR2_MRS_XG20( HwDeviceExtension , P3c4, pVBInfo ) ;
1144}
1145
1146
1147/* --------------------------------------------------------------------- */
1148/* Function : XGINew_SetDRAMDefaultRegister340 */
1149/* Input : */
1150/* Output : */
1151/* Description : */
1152/* --------------------------------------------------------------------- */
1153void XGINew_SetDRAMDefaultRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG Port , PVB_DEVICE_INFO pVBInfo)
1154{
1155 UCHAR temp , temp1 , temp2 , temp3 ,
1156 i , j , k ;
1157
1158 ULONG P3d4 = Port ,
1159 P3c4 = Port - 0x10 ;
1160
1161 XGINew_SetReg1( P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
1162 XGINew_SetReg1( P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
1163 XGINew_SetReg1( P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
1164 XGINew_SetReg1( P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
1165
1166 temp2 = 0 ;
1167 for( i = 0 ; i < 4 ; i++ )
1168 {
1169 temp = pVBInfo->CR6B[ XGINew_RAMType ][ i ] ; /* CR6B DQS fine tune delay */
1170 for( j = 0 ; j < 4 ; j++ )
1171 {
1172 temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
1173 temp2 |= temp1 ;
1174 XGINew_SetReg1( P3d4 , 0x6B , temp2 ) ;
1175 XGINew_GetReg1( P3d4 , 0x6B ) ; /* Insert read command for delay */
1176 temp2 &= 0xF0 ;
1177 temp2 += 0x10 ;
1178 }
1179 }
1180
1181 temp2 = 0 ;
1182 for( i = 0 ; i < 4 ; i++ )
1183 {
1184 temp = pVBInfo->CR6E[ XGINew_RAMType ][ i ] ; /* CR6E DQM fine tune delay */
1185 for( j = 0 ; j < 4 ; j++ )
1186 {
1187 temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
1188 temp2 |= temp1 ;
1189 XGINew_SetReg1( P3d4 , 0x6E , temp2 ) ;
1190 XGINew_GetReg1( P3d4 , 0x6E ) ; /* Insert read command for delay */
1191 temp2 &= 0xF0 ;
1192 temp2 += 0x10 ;
1193 }
1194 }
1195
1196 temp3 = 0 ;
1197 for( k = 0 ; k < 4 ; k++ )
1198 {
1199 XGINew_SetRegANDOR( P3d4 , 0x6E , 0xFC , temp3 ) ; /* CR6E_D[1:0] select channel */
1200 temp2 = 0 ;
1201 for( i = 0 ; i < 8 ; i++ )
1202 {
1203 temp = pVBInfo->CR6F[ XGINew_RAMType ][ 8 * k + i ] ; /* CR6F DQ fine tune delay */
1204 for( j = 0 ; j < 4 ; j++ )
1205 {
1206 temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
1207 temp2 |= temp1 ;
1208 XGINew_SetReg1( P3d4 , 0x6F , temp2 ) ;
1209 XGINew_GetReg1( P3d4 , 0x6F ) ; /* Insert read command for delay */
1210 temp2 &= 0xF8 ;
1211 temp2 += 0x08 ;
1212 }
1213 }
1214 temp3 += 0x01 ;
1215 }
1216
1217 XGINew_SetReg1( P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
1218 XGINew_SetReg1( P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
1219
1220 temp2 = 0x80 ;
1221 temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
1222 for( j = 0 ; j < 4 ; j++ )
1223 {
1224 temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
1225 temp2 |= temp1 ;
1226 XGINew_SetReg1( P3d4 , 0x89 , temp2 ) ;
1227 XGINew_GetReg1( P3d4 , 0x89 ) ; /* Insert read command for delay */
1228 temp2 &= 0xF0 ;
1229 temp2 += 0x10 ;
1230 }
1231
1232 temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
1233 temp1 = temp & 0x03 ;
1234 temp2 |= temp1 ;
1235 XGINew_SetReg1( P3d4 , 0x89 , temp2 ) ;
1236
1237 temp = pVBInfo->CR40[ 3 ][ XGINew_RAMType ] ;
1238 temp1 = temp & 0x0F ;
1239 temp2 = ( temp >> 4 ) & 0x07 ;
1240 temp3 = temp & 0x80 ;
1241 XGINew_SetReg1( P3d4 , 0x45 , temp1 ) ; /* CR45 */
1242 XGINew_SetReg1( P3d4 , 0x99 , temp2 ) ; /* CR99 */
1243 XGINew_SetRegOR( P3d4 , 0x40 , temp3 ) ; /* CR40_D[7] */
1244 XGINew_SetReg1( P3d4 , 0x41 , pVBInfo->CR40[ 0 ][ XGINew_RAMType ] ) ; /* CR41 */
1245
1246 if ( HwDeviceExtension->jChipType == XG27 )
1247 XGINew_SetReg1( P3d4 , 0x8F , *pVBInfo->pCR8F ) ; /* CR8F */
1248
1249 for( j = 0 ; j <= 6 ; j++ )
1250 XGINew_SetReg1( P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
1251
1252 for( j = 0 ; j <= 2 ; j++ )
1253 XGINew_SetReg1( P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
1254
1255 for( j = 0 ; j < 2 ; j++ )
1256 XGINew_SetReg1( P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
1257
1258 if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
1259 XGINew_SetReg1( P3d4 , 0x8C , 0x87 ) ;
1260
1261 XGINew_SetReg1( P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
1262
1263 XGINew_SetReg1( P3d4 , 0x83 , 0x09 ) ; /* CR83 */
1264 XGINew_SetReg1( P3d4 , 0x87 , 0x00 ) ; /* CR87 */
1265 XGINew_SetReg1( P3d4 , 0xCF , *pVBInfo->pCRCF ) ; /* CRCF */
1266 if ( XGINew_RAMType )
1267 {
1268 //XGINew_SetReg1( P3c4 , 0x17 , 0xC0 ) ; /* SR17 DDRII */
1269 XGINew_SetReg1( P3c4 , 0x17 , 0x80 ) ; /* SR17 DDRII */
1270 if ( HwDeviceExtension->jChipType == XG27 )
1271 XGINew_SetReg1( P3c4 , 0x17 , 0x02 ) ; /* SR17 DDRII */
1272
1273 }
1274 else
1275 XGINew_SetReg1( P3c4 , 0x17 , 0x00 ) ; /* SR17 DDR */
1276 XGINew_SetReg1( P3c4 , 0x1A , 0x87 ) ; /* SR1A */
1277
1278 temp = XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) ;
1279 if( temp == 0 )
1280 XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
1281 else
1282 {
1283 XGINew_SetReg1( P3d4 , 0xB0 , 0x80 ) ; /* DDRII Dual frequency mode */
1284 XGINew_DDR2_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
1285 }
1286 XGINew_SetReg1( P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
1287}
1288
1289
1290/* --------------------------------------------------------------------- */
1291/* Function : XGINew_DDR_MRS */
1292/* Input : */
1293/* Output : */
1294/* Description : */
1295/* --------------------------------------------------------------------- */
1296void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo)
1297{
1298 USHORT data ;
1299
1300 PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
1301
1302 /* SR16 <- 1F,DF,2F,AF */
1303 /* yriver modified SR16 <- 0F,DF,0F,AF */
1304 /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
1305 data = pVideoMemory[ 0xFB ] ;
1306 /* data = XGINew_GetReg1( pVBInfo->P3c4 , 0x16 ) ; */
1307
1308 data &= 0x0F ;
1309 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
1310 data |= 0xC0 ;
1311 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
1312 data &= 0x0F ;
1313 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
1314 data |= 0x80 ;
1315 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
1316 data &= 0x0F ;
1317 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
1318 data |= 0xD0 ;
1319 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
1320 data &= 0x0F ;
1321 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
1322 data |= 0xA0 ;
1323 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
1324/*
1325 else {
1326 data &= 0x0F;
1327 data |= 0x10;
1328 XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
1329
1330 if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
1331 {
1332 data &= 0x0F;
1333 }
1334
1335 data |= 0xC0;
1336 XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
1337
1338
1339 data &= 0x0F;
1340 data |= 0x20;
1341 XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
1342 if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
1343 {
1344 data &= 0x0F;
1345 }
1346
1347 data |= 0x80;
1348 XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
1349 }
1350*/
1351}
1352
1353
1354/* check if read cache pointer is correct */
1355
1356
1357
1358/* --------------------------------------------------------------------- */
1359/* Function : XGINew_VerifyMclk */
1360/* Input : */
1361/* Output : */
1362/* Description : */
1363/* --------------------------------------------------------------------- */
1364void XGINew_VerifyMclk( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
1365{
1366 PUCHAR pVideoMemory = pVBInfo->FBAddr ;
1367 UCHAR i , j ;
1368 USHORT Temp , SR21 ;
1369
1370 pVideoMemory[ 0 ] = 0xaa ; /* alan */
1371 pVideoMemory[ 16 ] = 0x55 ; /* note: PCI read cache is off */
1372
1373 if ( ( pVideoMemory[ 0 ] != 0xaa ) || ( pVideoMemory[ 16 ] != 0x55 ) )
1374 {
1375 for( i = 0 , j = 16 ; i < 2 ; i++ , j += 16 )
1376 {
1377 SR21 = XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
1378 Temp = SR21 & 0xFB ; /* disable PCI post write buffer empty gating */
1379 XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , Temp ) ;
1380
1381 Temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x3C ) ;
1382 Temp |= 0x01 ; /* MCLK reset */
1383
1384
1385 Temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x3C ) ;
1386 Temp &= 0xFE ; /* MCLK normal operation */
1387
1388 XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , SR21 ) ;
1389
1390 pVideoMemory[ 16 + j ] = j ;
1391 if ( pVideoMemory[ 16 + j ] == j )
1392 {
1393 pVideoMemory[ j ] = j ;
1394 break ;
1395 }
1396 }
1397 }
1398}
1399
1400
1401
1402
1403
1404/* --------------------------------------------------------------------- */
1405/* Function : XGINew_SetDRAMSize_340 */
1406/* Input : */
1407/* Output : */
1408/* Description : */
1409/* --------------------------------------------------------------------- */
1410void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
1411{
1412 USHORT data ;
1413
1414 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
1415 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
1416
1417 XGISetModeNew( HwDeviceExtension , 0x2e ) ;
1418
1419
1420 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
1421 XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /* disable read cache */
1422 XGI_DisplayOff( HwDeviceExtension, pVBInfo );
1423
1424 /*data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1 ) ;*/
1425 /*data |= 0x20 ;*/
1426 /*XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , data ) ;*/ /* Turn OFF Display */
1427 XGINew_DDRSizing340( HwDeviceExtension, pVBInfo ) ;
1428 data=XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
1429 XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /* enable read cache */
1430
1431}
1432
1433
1434/* --------------------------------------------------------------------- */
1435/* Function : */
1436/* Input : */
1437/* Output : */
1438/* Description : */
1439/* --------------------------------------------------------------------- */
1440void XGINew_SetDRAMSize_310( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
1441{
1442 USHORT data ;
1443 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ,
1444 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
1445#ifdef XGI301
1446 /* XGINew_SetReg1( pVBInfo->P3d4 , 0x30 , 0x40 ) ; */
1447#endif
1448
1449#ifdef XGI302 /* alan,should change value */
1450 XGINew_SetReg1( pVBInfo->P3d4 , 0x30 , 0x4D ) ;
1451 XGINew_SetReg1( pVBInfo->P3d4 , 0x31 , 0xc0 ) ;
1452 XGINew_SetReg1( pVBInfo->P3d4 , 0x34 , 0x3F ) ;
1453#endif
1454
1455 XGISetModeNew( HwDeviceExtension , 0x2e ) ;
1456
1457 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
1458 XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /* disable read cache */
1459
1460 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1 ) ;
1461 data |= 0x20 ;
1462 XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , data ) ; /* Turn OFF Display */
1463
1464 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x16 ) ;
1465
1466
1467 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , ( USHORT )( data | 0x0F ) ) ; /* assume lowest speed DRAM */
1468
1469 XGINew_SetDRAMModeRegister( pVBInfo ) ;
1470 XGINew_DisableRefresh( HwDeviceExtension, pVBInfo ) ;
1471 XGINew_CheckBusWidth_310( pVBInfo) ;
1472 XGINew_VerifyMclk( HwDeviceExtension, pVBInfo ) ; /* alan 2000/7/3 */
1473
1474
1475
1476 if ( XGINew_Get310DRAMType( pVBInfo ) < 2 )
1477 {
1478 XGINew_SDRSizing( pVBInfo ) ;
1479 }
1480 else
1481 {
1482 XGINew_DDRSizing( pVBInfo) ;
1483 }
1484
1485
1486
1487
1488 XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , pVBInfo->SR15[ 1 ][ XGINew_RAMType ] ) ; /* restore SR16 */
1489
1490 XGINew_EnableRefresh( HwDeviceExtension, pVBInfo ) ;
1491 data=XGINew_GetReg1( pVBInfo->P3c4 ,0x21 ) ;
1492 XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /* enable read cache */
1493}
1494
1495
1496
1497/* --------------------------------------------------------------------- */
1498/* Function : XGINew_SetDRAMModeRegister340 */
1499/* Input : */
1500/* Output : */
1501/* Description : */
1502/* --------------------------------------------------------------------- */
1503
1504void XGINew_SetDRAMModeRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension )
1505{
1506 UCHAR data ;
1507 VB_DEVICE_INFO VBINF;
1508 PVB_DEVICE_INFO pVBInfo = &VBINF;
1509 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
1510 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
1511 pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
1512 pVBInfo->ISXPDOS = 0 ;
1513
1514 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
1515 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
1516 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
1517 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
1518 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
1519 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
1520 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
1521 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
1522 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
1523 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
1524 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
1525 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
1526 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
1527 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
1528 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
1529 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
1530 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
1531 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
1532 XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
1533
1534 InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
1535
1536 ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
1537
1538 if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
1539 {
1540 data = ( XGINew_GetReg1( pVBInfo->P3c4 , 0x39 ) & 0x02 ) >> 1 ;
1541 if ( data == 0x01 )
1542 XGINew_DDR2x_MRS_340( pVBInfo->P3c4, pVBInfo ) ;
1543 else
1544 XGINew_DDR1x_MRS_340( pVBInfo->P3c4, pVBInfo ) ;
1545 }
1546 else
1547 XGINew_DDR2_MRS_XG20( HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
1548
1549 XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
1550}
1551
1552/* --------------------------------------------------------------------- */
1553/* Function : XGINew_SetDRAMModeRegister */
1554/* Input : */
1555/* Output : */
1556/* Description : */
1557/* --------------------------------------------------------------------- */
1558void XGINew_SetDRAMModeRegister( PVB_DEVICE_INFO pVBInfo)
1559{
1560 if ( XGINew_Get310DRAMType( pVBInfo ) < 2 )
1561 {
1562 XGINew_SDR_MRS(pVBInfo ) ;
1563 }
1564 else
1565 {
1566 /* SR16 <- 0F,CF,0F,8F */
1567 XGINew_DDR_MRS( pVBInfo ) ;
1568 }
1569}
1570
1571
1572/* --------------------------------------------------------------------- */
1573/* Function : XGINew_DisableRefresh */
1574/* Input : */
1575/* Output : */
1576/* Description : */
1577/* --------------------------------------------------------------------- */
1578void XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
1579{
1580 USHORT data ;
1581
1582
1583 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1B ) ;
1584 data &= 0xF8 ;
1585 XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , data ) ;
1586
1587}
1588
1589
1590/* --------------------------------------------------------------------- */
1591/* Function : XGINew_EnableRefresh */
1592/* Input : */
1593/* Output : */
1594/* Description : */
1595/* --------------------------------------------------------------------- */
1596void XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
1597{
1598
1599 XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
1600
1601
1602}
1603
1604
1605/* --------------------------------------------------------------------- */
1606/* Function : XGINew_DisableChannelInterleaving */
1607/* Input : */
1608/* Output : */
1609/* Description : */
1610/* --------------------------------------------------------------------- */
1611void XGINew_DisableChannelInterleaving( int index , USHORT XGINew_DDRDRAM_TYPE[][ 5 ] , PVB_DEVICE_INFO pVBInfo)
1612{
1613 USHORT data ;
1614
1615 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x15 ) ;
1616 data &= 0x1F ;
1617
1618 switch( XGINew_DDRDRAM_TYPE[ index ][ 3 ] )
1619 {
1620 case 64:
1621 data |= 0 ;
1622 break ;
1623 case 32:
1624 data |= 0x20 ;
1625 break ;
1626 case 16:
1627 data |= 0x40 ;
1628 break ;
1629 case 4:
1630 data |= 0x60 ;
1631 break ;
1632 default:
1633 break ;
1634 }
1635 XGINew_SetReg1( pVBInfo->P3c4 , 0x15 , data ) ;
1636}
1637
1638
1639/* --------------------------------------------------------------------- */
1640/* Function : XGINew_SetDRAMSizingType */
1641/* Input : */
1642/* Output : */
1643/* Description : */
1644/* --------------------------------------------------------------------- */
1645void XGINew_SetDRAMSizingType( int index , USHORT DRAMTYPE_TABLE[][ 5 ] ,PVB_DEVICE_INFO pVBInfo)
1646{
1647 USHORT data ;
1648
1649 data = DRAMTYPE_TABLE[ index ][ 4 ] ;
1650 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x13 , 0x80 , data ) ;
1651 DelayUS( 15 ) ;
1652 /* should delay 50 ns */
1653}
1654
1655
1656/* --------------------------------------------------------------------- */
1657/* Function : XGINew_CheckBusWidth_310 */
1658/* Input : */
1659/* Output : */
1660/* Description : */
1661/* --------------------------------------------------------------------- */
1662void XGINew_CheckBusWidth_310( PVB_DEVICE_INFO pVBInfo)
1663{
1664 USHORT data ;
1665 PULONG volatile pVideoMemory ;
1666
1667 pVideoMemory = (PULONG) pVBInfo->FBAddr;
1668
1669 if ( XGINew_Get310DRAMType( pVBInfo ) < 2 )
1670 {
1671 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x00 ) ;
1672 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x12 ) ;
1673 /* should delay */
1674 XGINew_SDR_MRS( pVBInfo ) ;
1675
1676 XGINew_ChannelAB = 0 ;
1677 XGINew_DataBusWidth = 128 ;
1678 pVideoMemory[ 0 ] = 0x01234567L ;
1679 pVideoMemory[ 1 ] = 0x456789ABL ;
1680 pVideoMemory[ 2 ] = 0x89ABCDEFL ;
1681 pVideoMemory[ 3 ] = 0xCDEF0123L ;
1682 pVideoMemory[ 4 ] = 0x55555555L ;
1683 pVideoMemory[ 5 ] = 0x55555555L ;
1684 pVideoMemory[ 6 ] = 0xFFFFFFFFL ;
1685 pVideoMemory[ 7 ] = 0xFFFFFFFFL ;
1686
1687 if ( ( pVideoMemory[ 3 ] != 0xCDEF0123L ) || ( pVideoMemory[ 2 ] != 0x89ABCDEFL ) )
1688 {
1689 /* ChannelA64Bit */
1690 XGINew_DataBusWidth = 64 ;
1691 XGINew_ChannelAB = 0 ;
1692 data=XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
1693 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , ( USHORT )( data & 0xFD ) ) ;
1694 }
1695
1696 if ( ( pVideoMemory[ 1 ] != 0x456789ABL ) || ( pVideoMemory[ 0 ] != 0x01234567L ) )
1697 {
1698 /* ChannelB64Bit */
1699 XGINew_DataBusWidth = 64 ;
1700 XGINew_ChannelAB = 1 ;
1701 data=XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
1702 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , ( USHORT )( ( data & 0xFD ) | 0x01 ) ) ;
1703 }
1704
1705 return ;
1706 }
1707 else
1708 {
1709 /* DDR Dual channel */
1710 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x00 ) ;
1711 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x02 ) ; /* Channel A, 64bit */
1712 /* should delay */
1713 XGINew_DDR_MRS( pVBInfo ) ;
1714
1715 XGINew_ChannelAB = 0 ;
1716 XGINew_DataBusWidth = 64 ;
1717 pVideoMemory[ 0 ] = 0x01234567L ;
1718 pVideoMemory[ 1 ] = 0x456789ABL ;
1719 pVideoMemory[ 2 ] = 0x89ABCDEFL ;
1720 pVideoMemory[ 3 ] = 0xCDEF0123L ;
1721 pVideoMemory[ 4 ] = 0x55555555L ;
1722 pVideoMemory[ 5 ] = 0x55555555L ;
1723 pVideoMemory[ 6 ] = 0xAAAAAAAAL ;
1724 pVideoMemory[ 7 ] = 0xAAAAAAAAL ;
1725
1726 if ( pVideoMemory[ 1 ] == 0x456789ABL )
1727 {
1728 if ( pVideoMemory[ 0 ] == 0x01234567L )
1729 {
1730 /* Channel A 64bit */
1731 return ;
1732 }
1733 }
1734 else
1735 {
1736 if ( pVideoMemory[ 0 ] == 0x01234567L )
1737 {
1738 /* Channel A 32bit */
1739 XGINew_DataBusWidth = 32 ;
1740 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x00 ) ;
1741 return ;
1742 }
1743 }
1744
1745 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x03 ) ; /* Channel B, 64bit */
1746 XGINew_DDR_MRS( pVBInfo);
1747
1748 XGINew_ChannelAB = 1 ;
1749 XGINew_DataBusWidth = 64 ;
1750 pVideoMemory[ 0 ] = 0x01234567L ;
1751 pVideoMemory[ 1 ] = 0x456789ABL ;
1752 pVideoMemory[ 2 ] = 0x89ABCDEFL ;
1753 pVideoMemory[ 3 ] = 0xCDEF0123L ;
1754 pVideoMemory[ 4 ] = 0x55555555L ;
1755 pVideoMemory[ 5 ] = 0x55555555L ;
1756 pVideoMemory[ 6 ] = 0xAAAAAAAAL ;
1757 pVideoMemory[ 7 ] = 0xAAAAAAAAL ;
1758
1759 if ( pVideoMemory[ 1 ] == 0x456789ABL )
1760 {
1761 /* Channel B 64 */
1762 if ( pVideoMemory[ 0 ] == 0x01234567L )
1763 {
1764 /* Channel B 64bit */
1765 return ;
1766 }
1767 else
1768 {
1769 /* error */
1770 }
1771 }
1772 else
1773 {
1774 if ( pVideoMemory[ 0 ] == 0x01234567L )
1775 {
1776 /* Channel B 32 */
1777 XGINew_DataBusWidth = 32 ;
1778 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x01 ) ;
1779 }
1780 else
1781 {
1782 /* error */
1783 }
1784 }
1785 }
1786}
1787
1788
1789/* --------------------------------------------------------------------- */
1790/* Function : XGINew_SetRank */
1791/* Input : */
1792/* Output : */
1793/* Description : */
1794/* --------------------------------------------------------------------- */
1795int XGINew_SetRank( int index , UCHAR RankNo , UCHAR XGINew_ChannelAB , USHORT DRAMTYPE_TABLE[][ 5 ] , PVB_DEVICE_INFO pVBInfo)
1796{
1797 USHORT data ;
1798 int RankSize ;
1799
1800 if ( ( RankNo == 2 ) && ( DRAMTYPE_TABLE[ index ][ 0 ] == 2 ) )
1801 return 0 ;
1802
1803 RankSize = DRAMTYPE_TABLE[ index ][ 3 ] / 2 * XGINew_DataBusWidth / 32 ;
1804
1805 if ( ( RankNo * RankSize ) <= 128 )
1806 {
1807 data = 0 ;
1808
1809 while( ( RankSize >>= 1 ) > 0 )
1810 {
1811 data += 0x10 ;
1812 }
1813 data |= ( RankNo - 1 ) << 2 ;
1814 data |= ( XGINew_DataBusWidth / 64 ) & 2 ;
1815 data |= XGINew_ChannelAB ;
1816 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ;
1817 /* should delay */
1818 XGINew_SDR_MRS( pVBInfo ) ;
1819 return( 1 ) ;
1820 }
1821 else
1822 return( 0 ) ;
1823}
1824
1825
1826/* --------------------------------------------------------------------- */
1827/* Function : XGINew_SetDDRChannel */
1828/* Input : */
1829/* Output : */
1830/* Description : */
1831/* --------------------------------------------------------------------- */
1832int XGINew_SetDDRChannel( int index , UCHAR ChannelNo , UCHAR XGINew_ChannelAB , USHORT DRAMTYPE_TABLE[][ 5 ] , PVB_DEVICE_INFO pVBInfo)
1833{
1834 USHORT data ;
1835 int RankSize ;
1836
1837 RankSize = DRAMTYPE_TABLE[index][3]/2 * XGINew_DataBusWidth/32;
1838 /* RankSize = DRAMTYPE_TABLE[ index ][ 3 ] ; */
1839 if ( ChannelNo * RankSize <= 128 )
1840 {
1841 data = 0 ;
1842 while( ( RankSize >>= 1 ) > 0 )
1843 {
1844 data += 0x10 ;
1845 }
1846
1847 if ( ChannelNo == 2 )
1848 data |= 0x0C ;
1849
1850 data |= ( XGINew_DataBusWidth / 32 ) & 2 ;
1851 data |= XGINew_ChannelAB ;
1852 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ;
1853 /* should delay */
1854 XGINew_DDR_MRS( pVBInfo ) ;
1855 return( 1 ) ;
1856 }
1857 else
1858 return( 0 ) ;
1859}
1860
1861
1862/* --------------------------------------------------------------------- */
1863/* Function : XGINew_CheckColumn */
1864/* Input : */
1865/* Output : */
1866/* Description : */
1867/* --------------------------------------------------------------------- */
1868int XGINew_CheckColumn( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
1869{
1870 int i ;
1871 ULONG Increment , Position ;
1872
1873 /* Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 1 ) ; */
1874 Increment = 1 << ( 10 + XGINew_DataBusWidth / 64 ) ;
1875
1876 for( i = 0 , Position = 0 ; i < 2 ; i++ )
1877 {
1878 *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
1879 Position += Increment ;
1880 }
1881
1882#ifdef WIN2000 /* chiawen for linux solution */
1883 DelayUS( 100 ) ;
1884#endif
1885
1886 for( i = 0 , Position = 0 ; i < 2 ; i++ )
1887 {
1888 /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
1889 if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
1890 return( 0 ) ;
1891 Position += Increment ;
1892 }
1893 return( 1 ) ;
1894}
1895
1896
1897/* --------------------------------------------------------------------- */
1898/* Function : XGINew_CheckBanks */
1899/* Input : */
1900/* Output : */
1901/* Description : */
1902/* --------------------------------------------------------------------- */
1903int XGINew_CheckBanks( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
1904{
1905 int i ;
1906 ULONG Increment , Position ;
1907
1908 Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 2 ) ;
1909
1910 for( i = 0 , Position = 0 ; i < 4 ; i++ )
1911 {
1912 /* pVBInfo->FBAddr[ Position ] = Position ; */
1913 *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
1914 Position += Increment ;
1915 }
1916
1917 for( i = 0 , Position = 0 ; i < 4 ; i++ )
1918 {
1919 /* if (pVBInfo->FBAddr[ Position ] != Position ) */
1920 if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
1921 return( 0 ) ;
1922 Position += Increment ;
1923 }
1924 return( 1 ) ;
1925}
1926
1927
1928/* --------------------------------------------------------------------- */
1929/* Function : XGINew_CheckRank */
1930/* Input : */
1931/* Output : */
1932/* Description : */
1933/* --------------------------------------------------------------------- */
1934int XGINew_CheckRank( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
1935{
1936 int i ;
1937 ULONG Increment , Position ;
1938
1939 Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
1940 DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
1941
1942 for( i = 0 , Position = 0 ; i < 2 ; i++ )
1943 {
1944 /* pVBInfo->FBAddr[ Position ] = Position ; */
1945 /* *( ( PULONG )( pVBInfo->FBAddr ) ) = Position ; */
1946 *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
1947 Position += Increment ;
1948 }
1949
1950 for( i = 0 , Position = 0 ; i < 2 ; i++ )
1951 {
1952 /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
1953 /* if ( ( *( PULONG )( pVBInfo->FBAddr ) ) != Position ) */
1954 if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
1955 return( 0 ) ;
1956 Position += Increment ;
1957 }
1958 return( 1 );
1959}
1960
1961
1962/* --------------------------------------------------------------------- */
1963/* Function : XGINew_CheckDDRRank */
1964/* Input : */
1965/* Output : */
1966/* Description : */
1967/* --------------------------------------------------------------------- */
1968int XGINew_CheckDDRRank( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
1969{
1970 ULONG Increment , Position ;
1971 USHORT data ;
1972
1973 Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
1974 DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
1975
1976 Increment += Increment / 2 ;
1977
1978 Position = 0;
1979 *( ( PULONG )( pVBInfo->FBAddr + Position + 0 ) ) = 0x01234567 ;
1980 *( ( PULONG )( pVBInfo->FBAddr + Position + 1 ) ) = 0x456789AB ;
1981 *( ( PULONG )( pVBInfo->FBAddr + Position + 2 ) ) = 0x55555555 ;
1982 *( ( PULONG )( pVBInfo->FBAddr + Position + 3 ) ) = 0x55555555 ;
1983 *( ( PULONG )( pVBInfo->FBAddr + Position + 4 ) ) = 0xAAAAAAAA ;
1984 *( ( PULONG )( pVBInfo->FBAddr + Position + 5 ) ) = 0xAAAAAAAA ;
1985
1986 if ( ( *( PULONG )( pVBInfo->FBAddr + 1 ) ) == 0x456789AB )
1987 return( 1 ) ;
1988
1989 if ( ( *( PULONG )( pVBInfo->FBAddr + 0 ) ) == 0x01234567 )
1990 return( 0 ) ;
1991
1992 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
1993 data &= 0xF3 ;
1994 data |= 0x0E ;
1995 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ;
1996 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x15 ) ;
1997 data += 0x20 ;
1998 XGINew_SetReg1( pVBInfo->P3c4 , 0x15 , data ) ;
1999
2000 return( 1 ) ;
2001}
2002
2003
2004/* --------------------------------------------------------------------- */
2005/* Function : XGINew_CheckRanks */
2006/* Input : */
2007/* Output : */
2008/* Description : */
2009/* --------------------------------------------------------------------- */
2010int XGINew_CheckRanks( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
2011{
2012 int r ;
2013
2014 for( r = RankNo ; r >= 1 ; r-- )
2015 {
2016 if ( !XGINew_CheckRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
2017 return( 0 ) ;
2018 }
2019
2020 if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
2021 return( 0 ) ;
2022
2023 if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
2024 return( 0 ) ;
2025
2026 return( 1 ) ;
2027}
2028
2029
2030/* --------------------------------------------------------------------- */
2031/* Function : XGINew_CheckDDRRanks */
2032/* Input : */
2033/* Output : */
2034/* Description : */
2035/* --------------------------------------------------------------------- */
2036int XGINew_CheckDDRRanks( int RankNo , int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
2037{
2038 int r ;
2039
2040 for( r = RankNo ; r >= 1 ; r-- )
2041 {
2042 if ( !XGINew_CheckDDRRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
2043 return( 0 ) ;
2044 }
2045
2046 if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
2047 return( 0 ) ;
2048
2049 if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
2050 return( 0 ) ;
2051
2052 return( 1 ) ;
2053}
2054
2055
2056/* --------------------------------------------------------------------- */
2057/* Function : */
2058/* Input : */
2059/* Output : */
2060/* Description : */
2061/* --------------------------------------------------------------------- */
2062int XGINew_SDRSizing(PVB_DEVICE_INFO pVBInfo)
2063{
2064 int i ;
2065 UCHAR j ;
2066
2067 for( i = 0 ; i < 13 ; i++ )
2068 {
2069 XGINew_SetDRAMSizingType( i , XGINew_SDRDRAM_TYPE , pVBInfo) ;
2070
2071 for( j = 2 ; j > 0 ; j-- )
2072 {
2073 if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_SDRDRAM_TYPE , pVBInfo) )
2074 continue ;
2075 else
2076 {
2077 if ( XGINew_CheckRanks( j , i , XGINew_SDRDRAM_TYPE, pVBInfo) )
2078 return( 1 ) ;
2079 }
2080 }
2081 }
2082 return( 0 ) ;
2083}
2084
2085
2086/* --------------------------------------------------------------------- */
2087/* Function : XGINew_SetDRAMSizeReg */
2088/* Input : */
2089/* Output : */
2090/* Description : */
2091/* --------------------------------------------------------------------- */
2092USHORT XGINew_SetDRAMSizeReg( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
2093{
2094 USHORT data = 0 , memsize = 0 ;
2095 int RankSize ;
2096 UCHAR ChannelNo ;
2097
2098 RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 32 ;
2099 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x13 ) ;
2100 data &= 0x80 ;
2101
2102 if ( data == 0x80 )
2103 RankSize *= 2 ;
2104
2105 data = 0 ;
2106
2107 if( XGINew_ChannelAB == 3 )
2108 ChannelNo = 4 ;
2109 else
2110 ChannelNo = XGINew_ChannelAB ;
2111
2112 if ( ChannelNo * RankSize <= 256 )
2113 {
2114 while( ( RankSize >>= 1 ) > 0 )
2115 {
2116 data += 0x10 ;
2117 }
2118
2119 memsize = data >> 4 ;
2120
2121 /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
2122 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , ( XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
2123
2124 /* data |= XGINew_ChannelAB << 2 ; */
2125 /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
2126 /* XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ; */
2127
2128 /* should delay */
2129 /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
2130 }
2131 return( memsize ) ;
2132}
2133
2134
2135/* --------------------------------------------------------------------- */
2136/* Function : XGINew_SetDRAMSize20Reg */
2137/* Input : */
2138/* Output : */
2139/* Description : */
2140/* --------------------------------------------------------------------- */
2141USHORT XGINew_SetDRAMSize20Reg( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
2142{
2143 USHORT data = 0 , memsize = 0 ;
2144 int RankSize ;
2145 UCHAR ChannelNo ;
2146
2147 RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 8 ;
2148 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x13 ) ;
2149 data &= 0x80 ;
2150
2151 if ( data == 0x80 )
2152 RankSize *= 2 ;
2153
2154 data = 0 ;
2155
2156 if( XGINew_ChannelAB == 3 )
2157 ChannelNo = 4 ;
2158 else
2159 ChannelNo = XGINew_ChannelAB ;
2160
2161 if ( ChannelNo * RankSize <= 256 )
2162 {
2163 while( ( RankSize >>= 1 ) > 0 )
2164 {
2165 data += 0x10 ;
2166 }
2167
2168 memsize = data >> 4 ;
2169
2170 /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
2171 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , ( XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
2172 DelayUS( 15 ) ;
2173
2174 /* data |= XGINew_ChannelAB << 2 ; */
2175 /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
2176 /* XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ; */
2177
2178 /* should delay */
2179 /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
2180 }
2181 return( memsize ) ;
2182}
2183
2184
2185/* --------------------------------------------------------------------- */
2186/* Function : XGINew_ReadWriteRest */
2187/* Input : */
2188/* Output : */
2189/* Description : */
2190/* --------------------------------------------------------------------- */
2191int XGINew_ReadWriteRest( USHORT StopAddr , USHORT StartAddr, PVB_DEVICE_INFO pVBInfo)
2192{
2193 int i ;
2194 ULONG Position = 0 ;
2195
2196 *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
2197
2198 for( i = StartAddr ; i <= StopAddr ; i++ )
2199 {
2200 Position = 1 << i ;
2201 *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
2202 }
2203
2204 DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
2205
2206 Position = 0 ;
2207
2208 if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
2209 return( 0 ) ;
2210
2211 for( i = StartAddr ; i <= StopAddr ; i++ )
2212 {
2213 Position = 1 << i ;
2214 if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
2215 return( 0 ) ;
2216 }
2217 return( 1 ) ;
2218}
2219
2220
2221/* --------------------------------------------------------------------- */
2222/* Function : XGINew_CheckFrequence */
2223/* Input : */
2224/* Output : */
2225/* Description : */
2226/* --------------------------------------------------------------------- */
2227UCHAR XGINew_CheckFrequence( PVB_DEVICE_INFO pVBInfo )
2228{
2229 UCHAR data ;
2230
2231 data = XGINew_GetReg1( pVBInfo->P3d4 , 0x97 ) ;
2232
2233 if ( ( data & 0x10 ) == 0 )
2234 {
2235 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x39 ) ;
2236 data = ( data & 0x02 ) >> 1 ;
2237 return( data ) ;
2238 }
2239 else
2240 return( data & 0x01 ) ;
2241}
2242
2243
2244/* --------------------------------------------------------------------- */
2245/* Function : XGINew_CheckChannel */
2246/* Input : */
2247/* Output : */
2248/* Description : */
2249/* --------------------------------------------------------------------- */
2250void XGINew_CheckChannel( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
2251{
2252 UCHAR data;
2253
2254 switch( HwDeviceExtension->jChipType )
2255 {
2256 case XG20:
2257 case XG21:
2258 data = XGINew_GetReg1( pVBInfo->P3d4 , 0x97 ) ;
2259 data = data & 0x01;
2260 XGINew_ChannelAB = 1 ; /* XG20 "JUST" one channel */
2261
2262 if ( data == 0 ) /* Single_32_16 */
2263 {
2264
2265 if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x1000000)
2266 {
2267
2268 XGINew_DataBusWidth = 32 ; /* 32 bits */
2269 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 32bit */
2270 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x52 ) ;
2271 DelayUS( 15 ) ;
2272
2273 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2274 return ;
2275
2276 if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
2277 {
2278 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* 22bit + 1 rank + 32bit */
2279 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x42 ) ;
2280 DelayUS( 15 ) ;
2281
2282 if ( XGINew_ReadWriteRest( 23 , 23 , pVBInfo ) == 1 )
2283 return ;
2284 }
2285 }
2286
2287 if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
2288 {
2289 XGINew_DataBusWidth = 16 ; /* 16 bits */
2290 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 16bit */
2291 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x41 ) ;
2292 DelayUS( 15 ) ;
2293
2294 if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
2295 return ;
2296 else
2297 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x31 ) ;
2298 DelayUS( 15 ) ;
2299 }
2300
2301 }
2302 else /* Dual_16_8 */
2303 {
2304 if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
2305 {
2306
2307 XGINew_DataBusWidth = 16 ; /* 16 bits */
2308 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* (0x31:12x8x2) 22bit + 2 rank */
2309 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x41 ) ; /* 0x41:16Mx16 bit*/
2310 DelayUS( 15 ) ;
2311
2312 if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
2313 return ;
2314
2315 if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x400000)
2316 {
2317 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* (0x31:12x8x2) 22bit + 1 rank */
2318 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x31 ) ; /* 0x31:8Mx16 bit*/
2319 DelayUS( 15 ) ;
2320
2321 if ( XGINew_ReadWriteRest( 22 , 22 , pVBInfo ) == 1 )
2322 return ;
2323 }
2324 }
2325
2326
2327 if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x400000)
2328 {
2329 XGINew_DataBusWidth = 8 ; /* 8 bits */
2330 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* (0x31:12x8x2) 22bit + 2 rank */
2331 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x30 ) ; /* 0x30:8Mx8 bit*/
2332 DelayUS( 15 ) ;
2333
2334 if ( XGINew_ReadWriteRest( 22 , 21 , pVBInfo ) == 1 )
2335 return ;
2336 else
2337 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* (0x31:12x8x2) 22bit + 1 rank */
2338 DelayUS( 15 ) ;
2339 }
2340 }
2341 break ;
2342
2343 case XG27:
2344 XGINew_DataBusWidth = 16 ; /* 16 bits */
2345 XGINew_ChannelAB = 1 ; /* Single channel */
2346 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x51 ) ; /* 32Mx16 bit*/
2347 break ;
2348 case XG41:
2349 if ( XGINew_CheckFrequence(pVBInfo) == 1 )
2350 {
2351 XGINew_DataBusWidth = 32 ; /* 32 bits */
2352 XGINew_ChannelAB = 3 ; /* Quad Channel */
2353 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
2354 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x4C ) ;
2355
2356 if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
2357 return ;
2358
2359 XGINew_ChannelAB = 2 ; /* Dual channels */
2360 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x48 ) ;
2361
2362 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2363 return ;
2364
2365 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x49 ) ;
2366
2367 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2368 return ;
2369
2370 XGINew_ChannelAB = 3 ;
2371 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
2372 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x3C ) ;
2373
2374 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2375 return ;
2376
2377 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x38 ) ;
2378
2379 if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
2380 return ;
2381 else
2382 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x39 ) ;
2383 }
2384 else
2385 { /* DDR */
2386 XGINew_DataBusWidth = 64 ; /* 64 bits */
2387 XGINew_ChannelAB = 2 ; /* Dual channels */
2388 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
2389 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x5A ) ;
2390
2391 if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
2392 return ;
2393
2394 XGINew_ChannelAB = 1 ; /* Single channels */
2395 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x52 ) ;
2396
2397 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2398 return ;
2399
2400 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x53 ) ;
2401
2402 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2403 return ;
2404
2405 XGINew_ChannelAB = 2 ; /* Dual channels */
2406 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
2407 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x4A ) ;
2408
2409 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2410 return ;
2411
2412 XGINew_ChannelAB = 1 ; /* Single channels */
2413 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x42 ) ;
2414
2415 if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
2416 return ;
2417 else
2418 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x43 ) ;
2419 }
2420
2421 break ;
2422
2423 case XG42:
2424/*
2425 XG42 SR14 D[3] Reserve
2426 D[2] = 1, Dual Channel
2427 = 0, Single Channel
2428
2429 It's Different from Other XG40 Series.
2430*/
2431 if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII, DDR2x */
2432 {
2433 XGINew_DataBusWidth = 32 ; /* 32 bits */
2434 XGINew_ChannelAB = 2 ; /* 2 Channel */
2435 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
2436 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x44 ) ;
2437
2438 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2439 return ;
2440
2441 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
2442 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x34 ) ;
2443 if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
2444 return ;
2445
2446 XGINew_ChannelAB = 1 ; /* Single Channel */
2447 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
2448 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x40 ) ;
2449
2450 if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
2451 return ;
2452 else
2453 {
2454 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
2455 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x30 ) ;
2456 }
2457 }
2458 else
2459 { /* DDR */
2460 XGINew_DataBusWidth = 64 ; /* 64 bits */
2461 XGINew_ChannelAB = 1 ; /* 1 channels */
2462 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
2463 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x52 ) ;
2464
2465 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2466 return ;
2467 else
2468 {
2469 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
2470 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x42 ) ;
2471 }
2472 }
2473
2474 break ;
2475
2476 default: /* XG40 */
2477
2478 if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII */
2479 {
2480 XGINew_DataBusWidth = 32 ; /* 32 bits */
2481 XGINew_ChannelAB = 3 ;
2482 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
2483 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x4C ) ;
2484
2485 if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
2486 return ;
2487
2488 XGINew_ChannelAB = 2 ; /* 2 channels */
2489 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x48 ) ;
2490
2491 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2492 return ;
2493
2494 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
2495 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x3C ) ;
2496
2497 if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
2498 XGINew_ChannelAB = 3 ; /* 4 channels */
2499 else
2500 {
2501 XGINew_ChannelAB = 2 ; /* 2 channels */
2502 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x38 ) ;
2503 }
2504 }
2505 else
2506 { /* DDR */
2507 XGINew_DataBusWidth = 64 ; /* 64 bits */
2508 XGINew_ChannelAB = 2 ; /* 2 channels */
2509 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
2510 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x5A ) ;
2511
2512 if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
2513 return ;
2514 else
2515 {
2516 XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
2517 XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x4A ) ;
2518 }
2519 }
2520 break ;
2521 }
2522}
2523
2524
2525/* --------------------------------------------------------------------- */
2526/* Function : XGINew_DDRSizing340 */
2527/* Input : */
2528/* Output : */
2529/* Description : */
2530/* --------------------------------------------------------------------- */
2531int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
2532{
2533 int i ;
2534 USHORT memsize , addr ;
2535
2536 XGINew_SetReg1( pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
2537 XGINew_SetReg1( pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
2538 XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
2539
2540
2541 if ( HwDeviceExtension->jChipType >= XG20 )
2542 {
2543 for( i = 0 ; i < 12 ; i++ )
2544 {
2545 XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE20, pVBInfo ) ;
2546 memsize = XGINew_SetDRAMSize20Reg( i , XGINew_DDRDRAM_TYPE20, pVBInfo ) ;
2547 if ( memsize == 0 )
2548 continue ;
2549
2550 addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
2551 if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
2552 continue ;
2553
2554 if ( XGINew_ReadWriteRest( addr , 5, pVBInfo ) == 1 )
2555 return( 1 ) ;
2556 }
2557 }
2558 else
2559 {
2560 for( i = 0 ; i < 4 ; i++ )
2561 {
2562 XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
2563 memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
2564
2565 if ( memsize == 0 )
2566 continue ;
2567
2568 addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
2569 if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
2570 continue ;
2571
2572 if ( XGINew_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
2573 return( 1 ) ;
2574 }
2575 }
2576 return( 0 ) ;
2577}
2578
2579
2580/* --------------------------------------------------------------------- */
2581/* Function : XGINew_DDRSizing */
2582/* Input : */
2583/* Output : */
2584/* Description : */
2585/* --------------------------------------------------------------------- */
2586int XGINew_DDRSizing(PVB_DEVICE_INFO pVBInfo)
2587{
2588 int i ;
2589 UCHAR j ;
2590
2591 for( i = 0 ; i < 4 ; i++ )
2592 {
2593 XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE, pVBInfo ) ;
2594 XGINew_DisableChannelInterleaving( i , XGINew_DDRDRAM_TYPE , pVBInfo) ;
2595 for( j = 2 ; j > 0 ; j-- )
2596 {
2597 XGINew_SetDDRChannel( i , j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE , pVBInfo ) ;
2598 if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE, pVBInfo ) )
2599 continue ;
2600 else
2601 {
2602 if ( XGINew_CheckDDRRanks( j , i , XGINew_DDRDRAM_TYPE, pVBInfo ) )
2603 return( 1 ) ;
2604 }
2605 }
2606 }
2607 return( 0 ) ;
2608}
2609
2610/* --------------------------------------------------------------------- */
2611/* Function : XGINew_SetMemoryClock */
2612/* Input : */
2613/* Output : */
2614/* Description : */
2615/* --------------------------------------------------------------------- */
2616void XGINew_SetMemoryClock( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
2617{
2618
2619
2620 XGINew_SetReg1( pVBInfo->P3c4 , 0x28 , pVBInfo->MCLKData[ XGINew_RAMType ].SR28 ) ;
2621 XGINew_SetReg1( pVBInfo->P3c4 , 0x29 , pVBInfo->MCLKData[ XGINew_RAMType ].SR29 ) ;
2622 XGINew_SetReg1( pVBInfo->P3c4 , 0x2A , pVBInfo->MCLKData[ XGINew_RAMType ].SR2A ) ;
2623
2624
2625
2626 XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , pVBInfo->ECLKData[ XGINew_RAMType ].SR2E ) ;
2627 XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , pVBInfo->ECLKData[ XGINew_RAMType ].SR2F ) ;
2628 XGINew_SetReg1( pVBInfo->P3c4 , 0x30 , pVBInfo->ECLKData[ XGINew_RAMType ].SR30 ) ;
2629
2630 /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
2631 /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
2632 if ( HwDeviceExtension->jChipType == XG42 )
2633 {
2634 if ( ( pVBInfo->MCLKData[ XGINew_RAMType ].SR28 == 0x1C ) && ( pVBInfo->MCLKData[ XGINew_RAMType ].SR29 == 0x01 )
2635 && ( ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x1C ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) )
2636 || ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x22 ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) ) ) )
2637 {
2638 XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , ( ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x32 ) & 0xFC ) | 0x02 ) ;
2639 }
2640 }
2641}
2642
2643
2644/* --------------------------------------------------------------------- */
2645/* Function : ChkLFB */
2646/* Input : */
2647/* Output : */
2648/* Description : */
2649/* --------------------------------------------------------------------- */
2650BOOLEAN ChkLFB( PVB_DEVICE_INFO pVBInfo )
2651{
2652 if ( LFBDRAMTrap & XGINew_GetReg1( pVBInfo->P3d4 , 0x78 ) )
2653 return( TRUE ) ;
2654 else
2655 return( FALSE );
2656}
2657
2658
2659/* --------------------------------------------------------------------- */
2660/* input : dx ,valid value : CR or second chip's CR */
2661/* */
2662/* SetPowerConsume : */
2663/* Description: reduce 40/43 power consumption in first chip or */
2664/* in second chip, assume CR A1 D[6]="1" in this case */
2665/* output : none */
2666/* --------------------------------------------------------------------- */
2667void SetPowerConsume ( PXGI_HW_DEVICE_INFO HwDeviceExtension , ULONG XGI_P3d4Port )
2668{
2669 ULONG lTemp ;
2670 UCHAR bTemp;
2671
2672 HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x08 , 0 , &lTemp ) ; /* Get */
2673 if ((lTemp&0xFF)==0)
2674 {
2675 /* set CR58 D[5]=0 D[3]=0 */
2676 XGINew_SetRegAND( XGI_P3d4Port , 0x58 , 0xD7 ) ;
2677 bTemp = (UCHAR) XGINew_GetReg1( XGI_P3d4Port , 0xCB ) ;
2678 if (bTemp&0x20)
2679 {
2680 if (!(bTemp&0x10))
2681 {
2682 XGINew_SetRegANDOR( XGI_P3d4Port , 0x58 , 0xD7 , 0x20 ) ; /* CR58 D[5]=1 D[3]=0 */
2683 }
2684 else
2685 {
2686 XGINew_SetRegANDOR( XGI_P3d4Port , 0x58 , 0xD7 , 0x08 ) ; /* CR58 D[5]=0 D[3]=1 */
2687 }
2688
2689 }
2690
2691 }
2692}
2693
2694
2695
2696#if defined(LINUX_XF86)||defined(LINUX_KERNEL)
2697void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
2698{
2699
2700 /* ULONG ROMAddr = (ULONG)HwDeviceExtension->pjVirtualRomBase; */
2701 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
2702 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
2703 pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
2704 pVBInfo->ISXPDOS = 0 ;
2705
2706 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
2707 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
2708 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
2709 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
2710 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
2711 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
2712 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
2713 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
2714 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
2715 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
2716 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
2717 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
2718 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
2719 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
2720 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
2721 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
2722 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
2723 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
2724 XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
2725
2726 switch(HwDeviceExtension->jChipType)
2727 {
2728 case XG40:
2729 case XG41:
2730 case XG42:
2731 case XG20:
2732 case XG21:
2733 default:
2734 InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
2735 return ;
2736 }
2737
2738}
2739#endif /* For Linux */
2740
2741/* --------------------------------------------------------------------- */
2742/* Function : ReadVBIOSTablData */
2743/* Input : */
2744/* Output : */
2745/* Description : */
2746/* --------------------------------------------------------------------- */
2747void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo)
2748{
2749 PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
2750 ULONG i ;
2751 UCHAR j , k ;
2752#if 0
2753 ULONG ii , jj ;
2754 i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ; /* UniROM */
2755 if ( i != 0 )
2756 UNIROM = 1 ;
2757
2758 ii = 0x90 ;
2759 for( jj = 0x00 ; jj < 0x08 ; jj++ )
2760 {
2761 pVBInfo->MCLKData[ jj ].SR28 = pVideoMemory[ ii ] ;
2762 pVBInfo->MCLKData[ jj ].SR29 = pVideoMemory[ ii + 1] ;
2763 pVBInfo->MCLKData[ jj ].SR2A = pVideoMemory[ ii + 2] ;
2764 pVBInfo->MCLKData[ jj ].CLOCK = pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
2765 ii += 0x05 ;
2766 }
2767
2768 ii = 0xB8 ;
2769 for( jj = 0x00 ; jj < 0x08 ; jj++ )
2770 {
2771 pVBInfo->ECLKData[ jj ].SR2E = pVideoMemory[ ii ] ;
2772 pVBInfo->ECLKData[ jj ].SR2F=pVideoMemory[ ii + 1 ] ;
2773 pVBInfo->ECLKData[ jj ].SR30= pVideoMemory[ ii + 2 ] ;
2774 pVBInfo->ECLKData[ jj ].CLOCK= pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
2775 ii += 0x05 ;
2776 }
2777
2778 /* Volari customize data area start */
2779 /* if ( ChipType == XG40 ) */
2780 if ( ChipType >= XG40 )
2781 {
2782 ii = 0xE0 ;
2783 for( jj = 0x00 ; jj < 0x03 ; jj++ )
2784 {
2785 pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR13, SR14, and SR18 */
2786 pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
2787 pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
2788 pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
2789 pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
2790 pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
2791 pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
2792 pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
2793 ii += 0x08 ;
2794 }
2795 ii = 0x110 ;
2796 jj = 0x03 ;
2797 pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR1B */
2798 pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
2799 pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
2800 pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
2801 pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
2802 pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
2803 pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
2804 pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
2805
2806 *pVBInfo->pSR07 = pVideoMemory[ 0x74 ] ;
2807 *pVBInfo->pSR1F = pVideoMemory[ 0x75 ] ;
2808 *pVBInfo->pSR21 = pVideoMemory[ 0x76 ] ;
2809 *pVBInfo->pSR22 = pVideoMemory[ 0x77 ] ;
2810 *pVBInfo->pSR23 = pVideoMemory[ 0x78 ] ;
2811 *pVBInfo->pSR24 = pVideoMemory[ 0x79 ] ;
2812 pVBInfo->SR25[ 0 ] = pVideoMemory[ 0x7A ] ;
2813 *pVBInfo->pSR31 = pVideoMemory[ 0x7B ] ;
2814 *pVBInfo->pSR32 = pVideoMemory[ 0x7C ] ;
2815 *pVBInfo->pSR33 = pVideoMemory[ 0x7D ] ;
2816 ii = 0xF8 ;
2817
2818 for( jj = 0 ; jj < 3 ; jj++ )
2819 {
2820 pVBInfo->CR40[ jj ][ 0 ] = pVideoMemory[ ii ] ;
2821 pVBInfo->CR40[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
2822 pVBInfo->CR40[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
2823 pVBInfo->CR40[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
2824 pVBInfo->CR40[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
2825 pVBInfo->CR40[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
2826 pVBInfo->CR40[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
2827 pVBInfo->CR40[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
2828 ii += 0x08 ;
2829 }
2830
2831 ii = 0x118 ;
2832 for( j = 3 ; j < 24 ; j++ )
2833 {
2834 pVBInfo->CR40[ j ][ 0 ] = pVideoMemory[ ii ] ;
2835 pVBInfo->CR40[ j ][ 1 ] = pVideoMemory[ ii + 1 ] ;
2836 pVBInfo->CR40[ j ][ 2 ] = pVideoMemory[ ii + 2 ] ;
2837 pVBInfo->CR40[ j ][ 3 ] = pVideoMemory[ ii + 3 ] ;
2838 pVBInfo->CR40[ j ][ 4 ] = pVideoMemory[ ii + 4 ] ;
2839 pVBInfo->CR40[ j ][ 5 ] = pVideoMemory[ ii + 5 ] ;
2840 pVBInfo->CR40[ j ][ 6 ] = pVideoMemory[ ii + 6 ] ;
2841 pVBInfo->CR40[ j ][ 7 ] = pVideoMemory[ ii + 7 ] ;
2842 ii += 0x08 ;
2843 }
2844
2845 i = pVideoMemory[ 0x1C0 ] | ( pVideoMemory[ 0x1C1 ] << 8 ) ;
2846
2847 for( j = 0 ; j < 8 ; j++ )
2848 {
2849 for( k = 0 ; k < 4 ; k++ )
2850 pVBInfo->CR6B[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
2851 }
2852
2853 i = pVideoMemory[ 0x1C2 ] | ( pVideoMemory[ 0x1C3 ] << 8 ) ;
2854
2855 for( j = 0 ; j < 8 ; j++ )
2856 {
2857 for( k = 0 ; k < 4 ; k++ )
2858 pVBInfo->CR6E[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
2859 }
2860
2861 i = pVideoMemory[ 0x1C4 ] | ( pVideoMemory[ 0x1C5 ] << 8 ) ;
2862 for( j = 0 ; j < 8 ; j++ )
2863 {
2864 for( k = 0 ; k < 32 ; k++ )
2865 pVBInfo->CR6F[ j ][ k ] = pVideoMemory[ i + 32 * j + k ] ;
2866 }
2867
2868 i = pVideoMemory[ 0x1C6 ] | ( pVideoMemory[ 0x1C7 ] << 8 ) ;
2869
2870 for( j = 0 ; j < 8 ; j++ )
2871 {
2872 for( k = 0 ; k < 2 ; k++ )
2873 pVBInfo->CR89[ j ][ k ] = pVideoMemory[ i + 2 * j + k ] ;
2874 }
2875
2876 i = pVideoMemory[ 0x1C8 ] | ( pVideoMemory[ 0x1C9 ] << 8 ) ;
2877 for( j = 0 ; j < 12 ; j++ )
2878 pVBInfo->AGPReg[ j ] = pVideoMemory[ i + j ] ;
2879
2880 i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ;
2881 for( j = 0 ; j < 4 ; j++ )
2882 pVBInfo->SR16[ j ] = pVideoMemory[ i + j ] ;
2883
2884 if ( ChipType == XG21 )
2885 {
2886 if (pVideoMemory[ 0x67 ] & 0x80)
2887 {
2888 *pVBInfo->pDVOSetting = pVideoMemory[ 0x67 ];
2889 }
2890 if ( (pVideoMemory[ 0x67 ] & 0xC0) == 0xC0 )
2891 {
2892 *pVBInfo->pCR2E = pVideoMemory[ i + 4 ] ;
2893 *pVBInfo->pCR2F = pVideoMemory[ i + 5 ] ;
2894 *pVBInfo->pCR46 = pVideoMemory[ i + 6 ] ;
2895 *pVBInfo->pCR47 = pVideoMemory[ i + 7 ] ;
2896 }
2897 }
2898
2899 if ( ChipType == XG27 )
2900 {
2901 jj = i+j;
2902 for( i = 0 ; i <= 0xB ; i++,jj++ )
2903 pVBInfo->pCRD0[i] = pVideoMemory[ jj ] ;
2904 for( i = 0x0 ; i <= 0x1 ; i++,jj++ )
2905 pVBInfo->pCRDE[i] = pVideoMemory[ jj ] ;
2906
2907 *pVBInfo->pSR40 = pVideoMemory[ jj ] ;
2908 jj++;
2909 *pVBInfo->pSR41 = pVideoMemory[ jj ] ;
2910
2911 if (pVideoMemory[ 0x67 ] & 0x80)
2912 {
2913 *pVBInfo->pDVOSetting = pVideoMemory[ 0x67 ];
2914 }
2915 if ( (pVideoMemory[ 0x67 ] & 0xC0) == 0xC0 )
2916 {
2917 jj++;
2918 *pVBInfo->pCR2E = pVideoMemory[ jj ] ;
2919 *pVBInfo->pCR2F = pVideoMemory[ jj + 1 ] ;
2920 *pVBInfo->pCR46 = pVideoMemory[ jj + 2 ] ;
2921 *pVBInfo->pCR47 = pVideoMemory[ jj + 3 ] ;
2922 }
2923
2924 }
2925
2926 *pVBInfo->pCRCF = pVideoMemory[ 0x1CA ] ;
2927 *pVBInfo->pXGINew_DRAMTypeDefinition = pVideoMemory[ 0x1CB ] ;
2928 *pVBInfo->pXGINew_I2CDefinition = pVideoMemory[ 0x1D1 ] ;
2929 if ( ChipType >= XG20 )
2930 {
2931 *pVBInfo->pXGINew_CR97 = pVideoMemory[ 0x1D2 ] ;
2932 if ( ChipType == XG27 )
2933 {
2934 *pVBInfo->pSR36 = pVideoMemory[ 0x1D3 ] ;
2935 *pVBInfo->pCR8F = pVideoMemory[ 0x1D5 ] ;
2936 }
2937 }
2938
2939 }
2940#endif
2941 /* Volari customize data area end */
2942
2943 if ( ChipType == XG21 )
2944 {
2945 pVBInfo->IF_DEF_LVDS = 0 ;
2946 if (pVideoMemory[ 0x65 ] & 0x1)
2947 {
2948 pVBInfo->IF_DEF_LVDS = 1 ;
2949 i = pVideoMemory[ 0x316 ] | ( pVideoMemory[ 0x317 ] << 8 );
2950 j = pVideoMemory[ i-1 ] ;
2951 if ( j != 0xff )
2952 {
2953 k = 0;
2954 do
2955 {
2956 pVBInfo->XG21_LVDSCapList[k].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
2957 pVBInfo->XG21_LVDSCapList[k].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
2958 pVBInfo->XG21_LVDSCapList[k].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
2959 pVBInfo->XG21_LVDSCapList[k].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
2960 pVBInfo->XG21_LVDSCapList[k].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
2961 pVBInfo->XG21_LVDSCapList[k].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
2962 pVBInfo->XG21_LVDSCapList[k].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
2963 pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
2964 pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
2965 pVBInfo->XG21_LVDSCapList[k].VCLKData1 = pVideoMemory[ i + 18 ] ;
2966 pVBInfo->XG21_LVDSCapList[k].VCLKData2 = pVideoMemory[ i + 19 ] ;
2967 pVBInfo->XG21_LVDSCapList[k].PSC_S1 = pVideoMemory[ i + 20 ] ;
2968 pVBInfo->XG21_LVDSCapList[k].PSC_S2 = pVideoMemory[ i + 21 ] ;
2969 pVBInfo->XG21_LVDSCapList[k].PSC_S3 = pVideoMemory[ i + 22 ] ;
2970 pVBInfo->XG21_LVDSCapList[k].PSC_S4 = pVideoMemory[ i + 23 ] ;
2971 pVBInfo->XG21_LVDSCapList[k].PSC_S5 = pVideoMemory[ i + 24 ] ;
2972 i += 25;
2973 j--;
2974 k++;
2975 } while ( (j>0) && ( k < (sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct)) ) );
2976 }
2977 else
2978 {
2979 pVBInfo->XG21_LVDSCapList[0].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
2980 pVBInfo->XG21_LVDSCapList[0].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
2981 pVBInfo->XG21_LVDSCapList[0].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
2982 pVBInfo->XG21_LVDSCapList[0].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
2983 pVBInfo->XG21_LVDSCapList[0].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
2984 pVBInfo->XG21_LVDSCapList[0].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
2985 pVBInfo->XG21_LVDSCapList[0].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
2986 pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
2987 pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
2988 pVBInfo->XG21_LVDSCapList[0].VCLKData1 = pVideoMemory[ i + 18 ] ;
2989 pVBInfo->XG21_LVDSCapList[0].VCLKData2 = pVideoMemory[ i + 19 ] ;
2990 pVBInfo->XG21_LVDSCapList[0].PSC_S1 = pVideoMemory[ i + 20 ] ;
2991 pVBInfo->XG21_LVDSCapList[0].PSC_S2 = pVideoMemory[ i + 21 ] ;
2992 pVBInfo->XG21_LVDSCapList[0].PSC_S3 = pVideoMemory[ i + 22 ] ;
2993 pVBInfo->XG21_LVDSCapList[0].PSC_S4 = pVideoMemory[ i + 23 ] ;
2994 pVBInfo->XG21_LVDSCapList[0].PSC_S5 = pVideoMemory[ i + 24 ] ;
2995 }
2996 }
2997 }
2998}
2999
3000/* --------------------------------------------------------------------- */
3001/* Function : XGINew_DDR1x_MRS_XG20 */
3002/* Input : */
3003/* Output : */
3004/* Description : */
3005/* --------------------------------------------------------------------- */
3006void XGINew_DDR1x_MRS_XG20( ULONG P3c4 , PVB_DEVICE_INFO pVBInfo)
3007{
3008
3009 XGINew_SetReg1( P3c4 , 0x18 , 0x01 ) ;
3010 XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ;
3011 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
3012 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
3013 DelayUS( 60 ) ;
3014
3015 XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ;
3016 XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ;
3017 XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
3018 XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
3019 DelayUS( 60 ) ;
3020 XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
3021 /* XGINew_SetReg1( P3c4 , 0x18 , 0x31 ) ; */
3022 XGINew_SetReg1( P3c4 , 0x19 , 0x01 ) ;
3023 XGINew_SetReg1( P3c4 , 0x16 , 0x03 ) ;
3024 XGINew_SetReg1( P3c4 , 0x16 , 0x83 ) ;
3025 DelayUS( 1000 ) ;
3026 XGINew_SetReg1( P3c4 , 0x1B , 0x03 ) ;
3027 DelayUS( 500 ) ;
3028 /* XGINew_SetReg1( P3c4 , 0x18 , 0x31 ) ; */
3029 XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
3030 XGINew_SetReg1( P3c4 , 0x19 , 0x00 ) ;
3031 XGINew_SetReg1( P3c4 , 0x16 , 0x03 ) ;
3032 XGINew_SetReg1( P3c4 , 0x16 , 0x83 ) ;
3033 XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ;
3034}
3035
3036/* --------------------------------------------------------------------- */
3037/* Function : XGINew_SetDRAMModeRegister_XG20 */
3038/* Input : */
3039/* Output : */
3040/* Description : */
3041/* --------------------------------------------------------------------- */
3042void XGINew_SetDRAMModeRegister_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension )
3043{
3044 VB_DEVICE_INFO VBINF;
3045 PVB_DEVICE_INFO pVBInfo = &VBINF;
3046 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
3047 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
3048 pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
3049 pVBInfo->ISXPDOS = 0 ;
3050
3051 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
3052 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
3053 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
3054 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
3055 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
3056 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
3057 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
3058 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
3059 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
3060 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
3061 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
3062 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
3063 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
3064 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
3065 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
3066 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
3067 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
3068
3069 InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
3070
3071 ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
3072
3073 if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
3074 XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
3075 else
3076 XGINew_DDR2_MRS_XG20( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo ) ;
3077
3078 XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
3079}
3080
3081void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension )
3082{
3083 VB_DEVICE_INFO VBINF;
3084 PVB_DEVICE_INFO pVBInfo = &VBINF;
3085 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
3086 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
3087 pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
3088 pVBInfo->ISXPDOS = 0 ;
3089
3090 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
3091 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
3092 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
3093 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
3094 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
3095 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
3096 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
3097 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
3098 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
3099 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
3100 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
3101 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
3102 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
3103 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
3104 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
3105 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
3106 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
3107
3108 InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
3109
3110 ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
3111
3112 if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
3113 XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
3114 else
3115 //XGINew_DDR2_MRS_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo ) ;
3116 XGINew_DDRII_Bootup_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo) ;
3117
3118 //XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
3119 XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
3120
3121}
3122/*
3123void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension )
3124{
3125#ifndef LINUX_XF86
3126 UCHAR data ;
3127#endif
3128 VB_DEVICE_INFO VBINF;
3129 PVB_DEVICE_INFO pVBInfo = &VBINF;
3130 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
3131 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
3132 pVBInfo->BaseAddr = HwDeviceExtension->pjIOAddress ;
3133 pVBInfo->ISXPDOS = 0 ;
3134
3135 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
3136 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
3137 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
3138 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
3139 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
3140 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
3141 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
3142 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
3143 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
3144 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
3145 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
3146 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
3147 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
3148 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
3149 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
3150 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
3151 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
3152
3153 InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
3154
3155 ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
3156
3157 if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
3158 XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
3159 else
3160 XGINew_DDR2_MRS_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo ) ;
3161
3162 XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
3163}
3164*/
3165/* -------------------------------------------------------- */
3166/* Function : XGINew_ChkSenseStatus */
3167/* Input : */
3168/* Output : */
3169/* Description : */
3170/* -------------------------------------------------------- */
3171void XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
3172{
3173 USHORT tempbx=0 , temp , tempcx , CR3CData;
3174
3175 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x32 ) ;
3176
3177 if ( temp & Monitor1Sense )
3178 tempbx |= ActiveCRT1 ;
3179 if ( temp & LCDSense )
3180 tempbx |= ActiveLCD ;
3181 if ( temp & Monitor2Sense )
3182 tempbx |= ActiveCRT2 ;
3183 if ( temp & TVSense )
3184 {
3185 tempbx |= ActiveTV ;
3186 if ( temp & AVIDEOSense )
3187 tempbx |= ( ActiveAVideo << 8 );
3188 if ( temp & SVIDEOSense )
3189 tempbx |= ( ActiveSVideo << 8 );
3190 if ( temp & SCARTSense )
3191 tempbx |= ( ActiveSCART << 8 );
3192 if ( temp & HiTVSense )
3193 tempbx |= ( ActiveHiTV << 8 );
3194 if ( temp & YPbPrSense )
3195 tempbx |= ( ActiveYPbPr << 8 );
3196 }
3197
3198 tempcx = XGINew_GetReg1( pVBInfo->P3d4 , 0x3d ) ;
3199 tempcx |= ( XGINew_GetReg1( pVBInfo->P3d4 , 0x3e ) << 8 ) ;
3200
3201 if ( tempbx & tempcx )
3202 {
3203 CR3CData = XGINew_GetReg1( pVBInfo->P3d4 , 0x3c ) ;
3204 if ( !( CR3CData & DisplayDeviceFromCMOS ) )
3205 {
3206 tempcx = 0x1FF0 ;
3207 if ( *pVBInfo->pSoftSetting & ModeSoftSetting )
3208 {
3209 tempbx = 0x1FF0 ;
3210 }
3211 }
3212 }
3213 else
3214 {
3215 tempcx = 0x1FF0 ;
3216 if ( *pVBInfo->pSoftSetting & ModeSoftSetting )
3217 {
3218 tempbx = 0x1FF0 ;
3219 }
3220 }
3221
3222 tempbx &= tempcx ;
3223 XGINew_SetReg1( pVBInfo->P3d4, 0x3d , ( tempbx & 0x00FF ) ) ;
3224 XGINew_SetReg1( pVBInfo->P3d4, 0x3e , ( ( tempbx & 0xFF00 ) >> 8 )) ;
3225}
3226/* -------------------------------------------------------- */
3227/* Function : XGINew_SetModeScratch */
3228/* Input : */
3229/* Output : */
3230/* Description : */
3231/* -------------------------------------------------------- */
3232void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo )
3233{
3234 USHORT temp , tempcl = 0 , tempch = 0 , CR31Data , CR38Data;
3235
3236 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x3d ) ;
3237 temp |= XGINew_GetReg1( pVBInfo->P3d4 , 0x3e ) << 8 ;
3238 temp |= ( XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) & ( DriverMode >> 8) ) << 8 ;
3239
3240 if ( pVBInfo->IF_DEF_CRT2Monitor == 1)
3241 {
3242 if ( temp & ActiveCRT2 )
3243 tempcl = SetCRT2ToRAMDAC ;
3244 }
3245
3246 if ( temp & ActiveLCD )
3247 {
3248 tempcl |= SetCRT2ToLCD ;
3249 if ( temp & DriverMode )
3250 {
3251 if ( temp & ActiveTV )
3252 {
3253 tempch = SetToLCDA | EnableDualEdge ;
3254 temp ^= SetCRT2ToLCD ;
3255
3256 if ( ( temp >> 8 ) & ActiveAVideo )
3257 tempcl |= SetCRT2ToAVIDEO ;
3258 if ( ( temp >> 8 ) & ActiveSVideo )
3259 tempcl |= SetCRT2ToSVIDEO ;
3260 if ( ( temp >> 8 ) & ActiveSCART )
3261 tempcl |= SetCRT2ToSCART ;
3262
3263 if ( pVBInfo->IF_DEF_HiVision == 1 )
3264 {
3265 if ( ( temp >> 8 ) & ActiveHiTV )
3266 tempcl |= SetCRT2ToHiVisionTV ;
3267 }
3268
3269 if ( pVBInfo->IF_DEF_YPbPr == 1 )
3270 {
3271 if ( ( temp >> 8 ) & ActiveYPbPr )
3272 tempch |= SetYPbPr ;
3273 }
3274 }
3275 }
3276 }
3277 else
3278 {
3279 if ( ( temp >> 8 ) & ActiveAVideo )
3280 tempcl |= SetCRT2ToAVIDEO ;
3281 if ( ( temp >> 8 ) & ActiveSVideo )
3282 tempcl |= SetCRT2ToSVIDEO ;
3283 if ( ( temp >> 8 ) & ActiveSCART )
3284 tempcl |= SetCRT2ToSCART ;
3285
3286 if ( pVBInfo->IF_DEF_HiVision == 1 )
3287 {
3288 if ( ( temp >> 8 ) & ActiveHiTV )
3289 tempcl |= SetCRT2ToHiVisionTV ;
3290 }
3291
3292 if ( pVBInfo->IF_DEF_YPbPr == 1 )
3293 {
3294 if ( ( temp >> 8 ) & ActiveYPbPr )
3295 tempch |= SetYPbPr ;
3296 }
3297 }
3298
3299
3300 tempcl |= SetSimuScanMode ;
3301 if ( (!( temp & ActiveCRT1 )) && ( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
3302 tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
3303 if ( ( temp & ActiveLCD ) && ( temp & ActiveTV ) )
3304 tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
3305 XGINew_SetReg1( pVBInfo->P3d4, 0x30 , tempcl ) ;
3306
3307 CR31Data = XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) ;
3308 CR31Data &= ~( SetNotSimuMode >> 8 ) ;
3309 if ( !( temp & ActiveCRT1 ) )
3310 CR31Data |= ( SetNotSimuMode >> 8 ) ;
3311 CR31Data &= ~( DisableCRT2Display >> 8 ) ;
3312 if (!( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
3313 CR31Data |= ( DisableCRT2Display >> 8 ) ;
3314 XGINew_SetReg1( pVBInfo->P3d4, 0x31 , CR31Data ) ;
3315
3316 CR38Data = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
3317 CR38Data &= ~SetYPbPr ;
3318 CR38Data |= tempch ;
3319 XGINew_SetReg1( pVBInfo->P3d4, 0x38 , CR38Data ) ;
3320
3321}
3322
3323/* -------------------------------------------------------- */
3324/* Function : XGINew_GetXG21Sense */
3325/* Input : */
3326/* Output : */
3327/* Description : */
3328/* -------------------------------------------------------- */
3329void XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
3330{
3331 UCHAR Temp;
3332 PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
3333
3334 pVBInfo->IF_DEF_LVDS = 0 ;
3335
3336#ifdef WIN2000
3337 pVBInfo->IF_DEF_CH7007 = 0 ;
3338 if ( ( pVideoMemory[ 0x65 ] & 0x02 ) ) /* For XG21 CH7007 */
3339 {
3340 /* VideoDebugPrint((0, "ReadVBIOSTablData: pVideoMemory[ 0x65 ] =%x\n",pVideoMemory[ 0x65 ])); */
3341 pVBInfo->IF_DEF_CH7007 = 1 ; /* [Billy] 07/05/03 */
3342 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0x60 ) ; /* CH7007 on chip */
3343 }
3344 else
3345#endif
3346#if 1
3347 if (( pVideoMemory[ 0x65 ] & 0x01 ) ) /* For XG21 LVDS */
3348 {
3349 pVBInfo->IF_DEF_LVDS = 1 ;
3350 XGINew_SetRegOR( pVBInfo->P3d4 , 0x32 , LCDSense ) ;
3351 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xC0 ) ; /* LVDS on chip */
3352 }
3353 else
3354 {
3355#endif
3356 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* Enable GPIOA/B read */
3357 Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) & 0xC0;
3358 if ( Temp == 0xC0 )
3359 { /* DVI & DVO GPIOA/B pull high */
3360 XGINew_SenseLCD( HwDeviceExtension, pVBInfo ) ;
3361 XGINew_SetRegOR( pVBInfo->P3d4 , 0x32 , LCDSense ) ;
3362 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x20 , 0x20 ) ; /* Enable read GPIOF */
3363 Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) & 0x04 ;
3364 if ( !Temp )
3365 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0x80 ) ; /* TMDS on chip */
3366 else
3367 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xA0 ) ; /* Only DVO on chip */
3368 XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Disable read GPIOF */
3369 }
3370#if 1
3371 }
3372#endif
3373}
3374
3375/* -------------------------------------------------------- */
3376/* Function : XGINew_GetXG27Sense */
3377/* Input : */
3378/* Output : */
3379/* Description : */
3380/* -------------------------------------------------------- */
3381void XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
3382{
3383 UCHAR Temp,bCR4A;
3384
3385 pVBInfo->IF_DEF_LVDS = 0 ;
3386 bCR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
3387 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x07 , 0x07 ) ; /* Enable GPIOA/B/C read */
3388 Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) & 0x07;
3389 XGINew_SetReg1( pVBInfo->P3d4, 0x4A , bCR4A ) ;
3390
3391 if ( Temp <= 0x02 )
3392 {
3393 pVBInfo->IF_DEF_LVDS = 1 ;
3394 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xC0 ) ; /* LVDS setting */
3395 XGINew_SetReg1( pVBInfo->P3d4, 0x30 , 0x21 ) ;
3396 }
3397 else
3398 {
3399 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xA0 ) ; /* TMDS/DVO setting */
3400 }
3401 XGINew_SetRegOR( pVBInfo->P3d4 , 0x32 , LCDSense ) ;
3402
3403}
3404
3405UCHAR GetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
3406{
3407 UCHAR CR38,CR4A,temp;
3408
3409 CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
3410 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x10 , 0x10 ) ; /* enable GPIOE read */
3411 CR38 = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
3412 temp =0;
3413 if ( ( CR38 & 0xE0 ) > 0x80 )
3414 {
3415 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
3416 temp &= 0x08;
3417 temp >>= 3;
3418 }
3419
3420 XGINew_SetReg1( pVBInfo->P3d4, 0x4A , CR4A ) ;
3421
3422 return temp;
3423}
3424
3425UCHAR GetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
3426{
3427 UCHAR CR4A,temp;
3428
3429 CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
3430 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* enable GPIOA/B/C read */
3431 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
3432 if ( temp <= 2 )
3433 {
3434 temp &= 0x03;
3435 }
3436 else
3437 {
3438 temp = ((temp&0x04)>>1) || ((~temp)&0x01);
3439 }
3440 XGINew_SetReg1( pVBInfo->P3d4, 0x4A , CR4A ) ;
3441
3442 return temp;
3443}
3444
diff --git a/drivers/staging/xgifb/vb_init.h b/drivers/staging/xgifb/vb_init.h
new file mode 100644
index 000000000000..1f39d9c74cdd
--- /dev/null
+++ b/drivers/staging/xgifb/vb_init.h
@@ -0,0 +1,7 @@
1#ifndef _VBINIT_
2#define _VBINIT_
3extern BOOLEAN XGIInitNew( PXGI_HW_DEVICE_INFO HwDeviceExtension ) ;
4extern XGI21_LVDSCapStruct XGI21_LCDCapList[13];
5
6#endif
7
diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c
new file mode 100644
index 000000000000..bd7f73898644
--- /dev/null
+++ b/drivers/staging/xgifb/vb_setmode.c
@@ -0,0 +1,10736 @@
1#include "osdef.h"
2
3#ifdef TC
4#include <stdio.h>
5#include <string.h>
6#include <conio.h>
7#include <dos.h>
8#endif
9
10
11#ifdef LINUX_XF86
12#include "xf86.h"
13#include "xf86PciInfo.h"
14#include "xgi.h"
15#include "xgi_regs.h"
16#endif
17
18#ifdef LINUX_KERNEL
19#include <asm/io.h>
20#include <linux/types.h>
21#include <linux/version.h>
22#include "XGIfb.h"
23/*#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
24#include <video/XGIfb.h>
25#else
26#include <linux/XGIfb.h>
27#endif*/
28#endif
29
30#ifdef WIN2000
31#include <dderror.h>
32#include <devioctl.h>
33#include <miniport.h>
34#include <ntddvdeo.h>
35#include <video.h>
36
37#include "xgiv.h"
38#include "dd_i2c.h"
39#include "tools.h"
40#endif
41
42#include "vb_def.h"
43#include "vgatypes.h"
44#include "vb_struct.h"
45#include "vb_util.h"
46#include "vb_table.h"
47
48
49
50#define IndexMask 0xff
51#ifndef XGI_MASK_DUAL_CHIP
52#define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */
53#endif
54
55
56
57BOOLEAN XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo);
58BOOLEAN XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
59BOOLEAN XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo);
60
61BOOLEAN XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo);
62BOOLEAN XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo);
63BOOLEAN XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo);
64BOOLEAN XGI_AjustCRT2Rate(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT *i, PVB_DEVICE_INFO pVBInfo);
65BOOLEAN XGI_SearchModeID( USHORT ModeNo,USHORT *ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
66BOOLEAN XGI_GetLCDInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
67BOOLEAN XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo ) ;
68BOOLEAN XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo);
69UCHAR XGI_GetModePtr( USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
70USHORT XGI_GetOffset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
71USHORT XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo );
72USHORT XGI_GetResInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
73USHORT XGI_GetColorDepth(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
74USHORT XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo);
75USHORT XGI_GetVCLK2Ptr(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
76void XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo);
77void XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo);
78void XGI_GetCRT2Data(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
79void XGI_GetCRT2ResInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
80void XGI_PreSetGroup1(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
81void XGI_SetGroup1(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
82void XGI_SetLockRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
83void XGI_SetLCDRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
84void XGI_SetGroup2(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
85void XGI_SetGroup3(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
86void XGI_SetGroup4(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
87void XGI_SetGroup5(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
88void* XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
89void* XGI_GetTVPtr(USHORT BX, USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
90void XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo);
91void XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
92void XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
93void XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
94void XGI_SetPanelPower(USHORT tempah,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
95void XGI_EnablePWD( PVB_DEVICE_INFO pVBInfo);
96void XGI_DisablePWD( PVB_DEVICE_INFO pVBInfo);
97void XGI_AutoThreshold( PVB_DEVICE_INFO pVBInfo);
98void XGI_SetTap4Regs( PVB_DEVICE_INFO pVBInfo);
99
100void XGI_DisplayOn(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
101void XGI_DisplayOff( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo );
102void XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
103void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
104void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo);
105void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
106void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo);
107void XGI_UpdateXG21CRTC(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo, USHORT RefreshRateTableIndex);
108void XGI_WaitDisply(PVB_DEVICE_INFO pVBInfo);
109void XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo);
110void XGI_SetSeqRegs(USHORT ModeNo,USHORT StandTableIndex,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
111void XGI_SetMiscRegs(USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo);
112void XGI_SetCRTCRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo);
113void XGI_SetATTRegs(USHORT ModeNo,USHORT StandTableIndex,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo );
114void XGI_SetGRCRegs(USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo);
115void XGI_ClearExt1Regs(PVB_DEVICE_INFO pVBInfo);
116
117void XGI_SetSync(USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
118void XGI_SetCRT1CRTC(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo,PXGI_HW_DEVICE_INFO HwDeviceExtension);
119void XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,PXGI_HW_DEVICE_INFO HwDeviceExtension);
120void XGI_SetCRT1Timing_V(USHORT ModeIdIndex,USHORT ModeNo,PVB_DEVICE_INFO pVBInfo);
121void XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
122void XGI_SetCRT1VCLK(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
123void XGI_SetCRT1FIFO(USHORT ModeNo,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
124void XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
125void XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
126
127void XGI_LoadDAC(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
128void XGI_WriteDAC(USHORT dl, USHORT ah, USHORT al, USHORT dh, PVB_DEVICE_INFO pVBInfo);
129/*void XGI_ClearBuffer(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,PVB_DEVICE_INFO pVBInfo);*/
130void XGI_SetLCDAGroup(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
131void XGI_GetLVDSResInfo( USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
132void XGI_GetLVDSData(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
133void XGI_ModCRT1Regs(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
134void XGI_SetLVDSRegs(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
135void XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
136void XGI_GetVGAType(PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
137void XGI_GetVBType(PVB_DEVICE_INFO pVBInfo);
138void XGI_GetVBInfo(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
139void XGI_GetTVInfo(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo);
140void XGI_SetCRT2ECLK( USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo);
141void InitTo330Pointer(UCHAR,PVB_DEVICE_INFO pVBInfo);
142void XGI_GetLCDSync(USHORT* HSyncWidth, USHORT* VSyncWidth, PVB_DEVICE_INFO pVBInfo);
143void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
144void XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
145void XGI_SetCRT2VCLK(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
146void XGI_OEM310Setting(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
147void XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo);
148void XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo);
149void XGI_SetLCDCap_A(USHORT tempcx,PVB_DEVICE_INFO pVBInfo);
150void XGI_SetLCDCap_B(USHORT tempcx,PVB_DEVICE_INFO pVBInfo);
151void SetSpectrum(PVB_DEVICE_INFO pVBInfo);
152void XGI_SetAntiFlicker(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
153void XGI_SetEdgeEnhance(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
154void XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo);
155void XGI_SetYFilter(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
156void XGI_GetTVPtrIndex2(USHORT* tempbx,UCHAR* tempcl,UCHAR* tempch, PVB_DEVICE_INFO pVBInfo);
157USHORT XGI_GetTVPtrIndex( PVB_DEVICE_INFO pVBInfo );
158void XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo );
159void XGI_CloseCRTC(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
160void XGI_OpenCRTC(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
161void XGI_GetRAMDAC2DATA(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
162void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
163void XGI_LockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
164void XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo);
165void XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo);
166void XGI_LongWait(PVB_DEVICE_INFO pVBInfo);
167void XGI_SetCRT1Offset( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo );
168void XGI_GetLCDVCLKPtr(UCHAR* di_0,UCHAR *di_1, PVB_DEVICE_INFO pVBInfo);
169UCHAR XGI_GetVCLKPtr(USHORT RefreshRateTableIndex,USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
170void XGI_GetVCLKLen(UCHAR tempal,UCHAR* di_0,UCHAR* di_1, PVB_DEVICE_INFO pVBInfo);
171USHORT XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo);
172USHORT XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo);
173XGI301C_Tap4TimingStruct* XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
174void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
175void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
176UCHAR XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo);
177UCHAR XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo);
178void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
179void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
180void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
181BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
182void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
183void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
184UCHAR XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo );
185
186extern void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo);
187#ifdef WIN2000
188/* [Billy] 2007/05/17 For CH7007 */
189extern UCHAR CH7007TVReg_UNTSC[][8],CH7007TVReg_ONTSC[][8],CH7007TVReg_UPAL[][8],CH7007TVReg_OPAL[][8];
190extern UCHAR CH7007TVCRT1UNTSC_H[][10],CH7007TVCRT1ONTSC_H[][10],CH7007TVCRT1UPAL_H[][10],CH7007TVCRT1OPAL_H[][10] ;
191extern UCHAR CH7007TVCRT1UNTSC_V[][10],CH7007TVCRT1ONTSC_V[][10],CH7007TVCRT1UPAL_V[][10],CH7007TVCRT1OPAL_V[][10] ;
192extern UCHAR XGI7007_CHTVVCLKUNTSC[],XGI7007_CHTVVCLKONTSC[],XGI7007_CHTVVCLKUPAL[],XGI7007_CHTVVCLKOPAL[];
193
194extern BOOLEAN XGI_XG21CheckCH7007TVMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo ) ;
195extern void SetCH7007Regs(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo ) ;
196extern VP_STATUS TurnOnCH7007(PHW_DEVICE_EXTENSION pHWDE) ;
197extern VP_STATUS TurnOffCH7007(PHW_DEVICE_EXTENSION pHWDE) ;
198extern BOOLEAN IsCH7007TVMode(PVB_DEVICE_INFO pVBInfo) ;
199#endif
200
201/* USHORT XGINew_flag_clearbuffer; 0: no clear frame buffer 1:clear frame buffer */
202
203
204
205
206
207USHORT XGINew_MDA_DAC[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
208 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
209 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
210 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
211 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
212 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
213 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
214 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F};
215
216USHORT XGINew_CGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
217 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
218 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
219 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
220 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
221 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
222 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
223 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F};
224
225USHORT XGINew_EGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
226 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
227 0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D,
228 0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D,
229 0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17,
230 0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37,
231 0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F,
232 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F};
233
234USHORT XGINew_VGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
235 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
236 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18,
237 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F,
238
239 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F,
240 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00,
241 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18,
242 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04,
243 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10,
244 0x0B,0x0C,0x0D,0x0F,0x10};
245
246
247/* --------------------------------------------------------------------- */
248/* Function : InitTo330Pointer */
249/* Input : */
250/* Output : */
251/* Description : */
252/* --------------------------------------------------------------------- */
253void InitTo330Pointer( UCHAR ChipType ,PVB_DEVICE_INFO pVBInfo)
254{
255 pVBInfo->SModeIDTable = (XGI_StStruct *) XGI330_SModeIDTable ;
256 pVBInfo->StandTable = (XGI_StandTableStruct *) XGI330_StandTable ;
257 pVBInfo->EModeIDTable = (XGI_ExtStruct *) XGI330_EModeIDTable ;
258 pVBInfo->RefIndex = (XGI_Ext2Struct *) XGI330_RefIndex ;
259 pVBInfo->XGINEWUB_CRT1Table = (XGI_CRT1TableStruct *) XGI_CRT1Table ;
260
261 /* add for new UNIVGABIOS */
262 /* XGINew_UBLCDDataTable = (XGI_LCDDataTablStruct *) XGI_LCDDataTable ; */
263 /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable ; */
264
265
266 if ( ChipType >= XG40 )
267 {
268 pVBInfo->MCLKData = (XGI_MCLKDataStruct *) XGI340New_MCLKData ;
269 pVBInfo->ECLKData = (XGI_ECLKDataStruct *) XGI340_ECLKData ;
270 }
271 else
272 {
273 pVBInfo->MCLKData = (XGI_MCLKDataStruct *) XGI330New_MCLKData ;
274 pVBInfo->ECLKData = (XGI_ECLKDataStruct *) XGI330_ECLKData ;
275 }
276
277 pVBInfo->VCLKData = (XGI_VCLKDataStruct *) XGI_VCLKData ;
278 pVBInfo->VBVCLKData = (XGI_VBVCLKDataStruct *) XGI_VBVCLKData ;
279 pVBInfo->ScreenOffset = XGI330_ScreenOffset ;
280 pVBInfo->StResInfo = (XGI_StResInfoStruct *) XGI330_StResInfo ;
281 pVBInfo->ModeResInfo = (XGI_ModeResInfoStruct *) XGI330_ModeResInfo ;
282
283 pVBInfo->pOutputSelect = &XGI330_OutputSelect ;
284 pVBInfo->pSoftSetting = &XGI330_SoftSetting ;
285 pVBInfo->pSR07 = &XGI330_SR07 ;
286 pVBInfo->LCDResInfo = 0 ;
287 pVBInfo->LCDTypeInfo = 0 ;
288 pVBInfo->LCDInfo = 0 ;
289 pVBInfo->VBInfo = 0 ;
290 pVBInfo->TVInfo = 0;
291
292
293 pVBInfo->SR15 = XGI340_SR13 ;
294 pVBInfo->CR40 = XGI340_cr41 ;
295 pVBInfo->SR25 = XGI330_sr25 ;
296 pVBInfo->pSR31 = &XGI330_sr31 ;
297 pVBInfo->pSR32 = &XGI330_sr32 ;
298 pVBInfo->CR6B = XGI340_CR6B ;
299 pVBInfo->CR6E = XGI340_CR6E ;
300 pVBInfo->CR6F = XGI340_CR6F ;
301 pVBInfo->CR89 = XGI340_CR89 ;
302 pVBInfo->AGPReg = XGI340_AGPReg ;
303 pVBInfo->SR16 = XGI340_SR16 ;
304 pVBInfo->pCRCF = &XG40_CRCF ;
305 pVBInfo->pXGINew_DRAMTypeDefinition = &XG40_DRAMTypeDefinition ;
306
307
308 pVBInfo->CR49 = XGI330_CR49 ;
309 pVBInfo->pSR1F = &XGI330_SR1F ;
310 pVBInfo->pSR21 = &XGI330_SR21 ;
311 pVBInfo->pSR22 = &XGI330_SR22 ;
312 pVBInfo->pSR23 = &XGI330_SR23 ;
313 pVBInfo->pSR24 = &XGI330_SR24 ;
314 pVBInfo->pSR33 = &XGI330_SR33 ;
315
316
317
318 pVBInfo->pCRT2Data_1_2 = &XGI330_CRT2Data_1_2 ;
319 pVBInfo->pCRT2Data_4_D = &XGI330_CRT2Data_4_D ;
320 pVBInfo->pCRT2Data_4_E = &XGI330_CRT2Data_4_E ;
321 pVBInfo->pCRT2Data_4_10 = &XGI330_CRT2Data_4_10 ;
322 pVBInfo->pRGBSenseData = &XGI330_RGBSenseData ;
323 pVBInfo->pVideoSenseData = &XGI330_VideoSenseData ;
324 pVBInfo->pYCSenseData = &XGI330_YCSenseData ;
325 pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2 ;
326 pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2 ;
327 pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2 ;
328
329 pVBInfo->NTSCTiming = XGI330_NTSCTiming ;
330 pVBInfo->PALTiming = XGI330_PALTiming ;
331 pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming ;
332 pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing ;
333 pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing ;
334 pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming ;
335 pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming ;
336 pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming ;
337 pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming ;
338 pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data ;
339 pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu ;
340 pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text ;
341 pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3 ;
342 pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3 ;
343
344
345 pVBInfo->TimingH = (XGI_TimingHStruct *) XGI_TimingH ;
346 pVBInfo->TimingV = (XGI_TimingVStruct *) XGI_TimingV ;
347 pVBInfo->UpdateCRT1 = (XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table ;
348
349 pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC ;
350 pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC ;
351 pVBInfo->CHTVVCLKUPAL = XGI330_CHTVVCLKUPAL ;
352 pVBInfo->CHTVVCLKOPAL = XGI330_CHTVVCLKOPAL ;
353
354 /* 310 customization related */
355 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
356 pVBInfo->LCDCapList = XGI_LCDDLCapList ;
357 else
358 pVBInfo->LCDCapList = XGI_LCDCapList ;
359
360 if ( ( ChipType == XG21 ) || ( ChipType == XG27 ) )
361 pVBInfo->XG21_LVDSCapList = XGI21_LCDCapList ;
362
363 pVBInfo->XGI_TVDelayList = XGI301TVDelayList ;
364 pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2 ;
365
366
367 pVBInfo->pXGINew_I2CDefinition = &XG40_I2CDefinition ;
368
369 if ( ChipType >= XG20 )
370 pVBInfo->pXGINew_CR97 = &XG20_CR97 ;
371
372 if ( ChipType == XG27 )
373 {
374 pVBInfo->MCLKData = (XGI_MCLKDataStruct *) XGI27New_MCLKData ;
375 pVBInfo->CR40 = XGI27_cr41 ;
376 pVBInfo->pXGINew_CR97 = &XG27_CR97 ;
377 pVBInfo->pSR36 = &XG27_SR36 ;
378 pVBInfo->pCR8F = &XG27_CR8F ;
379 pVBInfo->pCRD0 = XG27_CRD0 ;
380 pVBInfo->pCRDE = XG27_CRDE ;
381 pVBInfo->pSR40 = &XG27_SR40 ;
382 pVBInfo->pSR41 = &XG27_SR41 ;
383
384 }
385
386 if ( ChipType >= XG20 )
387 {
388 pVBInfo->pDVOSetting = &XG21_DVOSetting ;
389 pVBInfo->pCR2E = &XG21_CR2E ;
390 pVBInfo->pCR2F = &XG21_CR2F ;
391 pVBInfo->pCR46 = &XG21_CR46 ;
392 pVBInfo->pCR47 = &XG21_CR47 ;
393 }
394
395}
396
397
398
399
400
401
402/* --------------------------------------------------------------------- */
403/* Function : XGISetModeNew */
404/* Input : */
405/* Output : */
406/* Description : */
407/* --------------------------------------------------------------------- */
408BOOLEAN XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo )
409{
410 USHORT ModeIdIndex ;
411 /* PUCHAR pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ; */
412 VB_DEVICE_INFO VBINF;
413 PVB_DEVICE_INFO pVBInfo = &VBINF;
414 pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
415 pVBInfo->BaseAddr = (ULONG)HwDeviceExtension->pjIOAddress ;
416 pVBInfo->IF_DEF_LVDS = 0 ;
417 pVBInfo->IF_DEF_CH7005 = 0 ;
418 pVBInfo->IF_DEF_LCDA = 1 ;
419 pVBInfo->IF_DEF_CH7017 = 0 ;
420 pVBInfo->IF_DEF_CH7007 = 0 ; /* [Billy] 2007/05/14 */
421 pVBInfo->IF_DEF_VideoCapture = 0 ;
422 pVBInfo->IF_DEF_ScaleLCD = 0 ;
423 pVBInfo->IF_DEF_OEMUtil = 0 ;
424 pVBInfo->IF_DEF_PWD = 0 ;
425
426
427 if ( HwDeviceExtension->jChipType >= XG20 ) /* kuku 2004/06/25 */
428 {
429 pVBInfo->IF_DEF_YPbPr = 0 ;
430 pVBInfo->IF_DEF_HiVision = 0 ;
431 pVBInfo->IF_DEF_CRT2Monitor = 0 ;
432 pVBInfo->VBType = 0 ; /*set VBType default 0*/
433 }
434 else if ( HwDeviceExtension->jChipType >= XG40 )
435 {
436 pVBInfo->IF_DEF_YPbPr = 1 ;
437 pVBInfo->IF_DEF_HiVision = 1 ;
438 pVBInfo->IF_DEF_CRT2Monitor = 1 ;
439 }
440 else
441 {
442 pVBInfo->IF_DEF_YPbPr = 1 ;
443 pVBInfo->IF_DEF_HiVision = 1 ;
444 pVBInfo->IF_DEF_CRT2Monitor = 0 ;
445 }
446
447 pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
448 pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
449 pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
450 pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
451 pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
452 pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C ;
453 pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
454 pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
455 pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
456 pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
457 pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
458 pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
459 pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
460 pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
461 pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
462 pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
463 pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
464 pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
465
466 if ( HwDeviceExtension->jChipType == XG21 ) /* for x86 Linux, XG21 LVDS */
467 {
468 if ( ( XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) & 0xE0 ) == 0xC0 )
469 {
470 pVBInfo->IF_DEF_LVDS = 1 ;
471 }
472 }
473 if ( HwDeviceExtension->jChipType == XG27 )
474 {
475 if ( ( XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) & 0xE0 ) == 0xC0 )
476 {
477 if ( XGINew_GetReg1( pVBInfo->P3d4 , 0x30 ) & 0x20 )
478 {
479 pVBInfo->IF_DEF_LVDS = 1 ;
480 }
481 }
482 }
483
484 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
485 XGI_GetVBType( pVBInfo ) ;
486
487 InitTo330Pointer( HwDeviceExtension->jChipType, pVBInfo ) ;
488#ifdef WIN2000
489 ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
490#endif
491 if ( ModeNo & 0x80 )
492 {
493 ModeNo = ModeNo & 0x7F ;
494/* XGINew_flag_clearbuffer = 0 ; */
495 }
496/* else
497 {
498 XGINew_flag_clearbuffer = 1 ;
499 }
500*/
501 XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
502
503 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 1.Openkey */
504 XGI_UnLockCRT2( HwDeviceExtension , pVBInfo ) ;
505
506 XGI_SearchModeID( ModeNo , &ModeIdIndex, pVBInfo ) ;
507
508 XGI_GetVGAType(HwDeviceExtension, pVBInfo) ;
509
510 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
511 {
512 XGI_GetVBInfo(ModeNo , ModeIdIndex , HwDeviceExtension, pVBInfo ) ;
513 XGI_GetTVInfo(ModeNo , ModeIdIndex, pVBInfo ) ;
514 XGI_GetLCDInfo(ModeNo , ModeIdIndex, pVBInfo ) ;
515 XGI_DisableBridge( HwDeviceExtension,pVBInfo ) ;
516/* XGI_OpenCRTC( HwDeviceExtension, pVBInfo ) ; */
517
518 if ( pVBInfo->VBInfo & ( SetSimuScanMode | SetCRT2ToLCDA ) )
519 {
520 XGI_SetCRT1Group(HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
521
522 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
523 {
524 XGI_SetLCDAGroup(ModeNo , ModeIdIndex , HwDeviceExtension, pVBInfo ) ;
525 }
526 }
527 else
528 {
529 if ( !( pVBInfo->VBInfo & SwitchToCRT2) )
530 {
531 XGI_SetCRT1Group( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
532 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
533 {
534 XGI_SetLCDAGroup( ModeNo , ModeIdIndex , HwDeviceExtension, pVBInfo ) ;
535 }
536 }
537 }
538
539 if ( pVBInfo->VBInfo & ( SetSimuScanMode | SwitchToCRT2 ) )
540 {
541 switch( HwDeviceExtension->ujVBChipID )
542 {
543 case VB_CHIP_301:
544 XGI_SetCRT2Group301( ModeNo , HwDeviceExtension, pVBInfo ) ; /*add for CRT2 */
545 break ;
546
547 case VB_CHIP_302:
548 XGI_SetCRT2Group301(ModeNo , HwDeviceExtension, pVBInfo ) ; /*add for CRT2 */
549 break ;
550
551 default:
552 break ;
553 }
554 }
555
556 XGI_SetCRT2ModeRegs( ModeNo, HwDeviceExtension,pVBInfo ) ;
557 XGI_OEM310Setting( ModeNo, ModeIdIndex,pVBInfo ) ; /*0212*/
558 XGI_CloseCRTC( HwDeviceExtension, pVBInfo ) ;
559 XGI_EnableBridge( HwDeviceExtension ,pVBInfo) ;
560 } /* !XG20 */
561 else
562 {
563#ifdef WIN2000
564 if ( pVBInfo->IF_DEF_CH7007 == 1 )
565 {
566
567 VideoDebugPrint((0, "XGISetModeNew: pVBIfo->IF_DEF_CH7007==1\n"));
568 pVBInfo->VBType = VB_CH7007 ;
569 XGI_GetVBInfo(ModeNo , ModeIdIndex , HwDeviceExtension, pVBInfo ) ;
570 XGI_GetTVInfo(ModeNo , ModeIdIndex, pVBInfo ) ;
571 XGI_GetLCDInfo(ModeNo , ModeIdIndex, pVBInfo ) ;
572 if( !(XGI_XG21CheckCH7007TVMode(ModeNo, ModeIdIndex, pVBInfo )) )
573 {
574 return FALSE;
575 }
576 }
577#endif
578
579
580 if ( pVBInfo->IF_DEF_LVDS == 1 )
581 {
582 if ( !XGI_XG21CheckLVDSMode(ModeNo , ModeIdIndex, pVBInfo) )
583 {
584 return FALSE;
585 }
586 }
587
588 if ( ModeNo <= 0x13 )
589 {
590 pVBInfo->ModeType = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag & ModeInfoFlag;
591 }
592 else
593 {
594 pVBInfo->ModeType = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag & ModeInfoFlag;
595 }
596
597 pVBInfo->SetFlag = 0 ;
598 if ( pVBInfo->IF_DEF_CH7007 != 1 )
599 {
600 pVBInfo->VBInfo = DisableCRT2Display ;
601 }
602
603
604 XGI_DisplayOff(HwDeviceExtension, pVBInfo) ;
605
606 XGI_SetCRT1Group(HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
607
608 XGI_DisplayOn( HwDeviceExtension, pVBInfo ) ;
609 /*
610 if( HwDeviceExtension->jChipType == XG21 )
611 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0x80 , 0x80 ) ;
612 */
613 }
614
615
616/*
617 if ( ModeNo <= 0x13 )
618 {
619 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
620 }
621 else
622 {
623 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
624 }
625 pVBInfo->ModeType = modeflag&ModeInfoFlag ;
626 pVBInfo->SetFlag = 0x00 ;
627 pVBInfo->VBInfo = DisableCRT2Display ;
628 temp = XGINew_CheckMemorySize( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
629
630 if ( temp == 0 )
631 return( 0 ) ;
632
633 XGI_DisplayOff( HwDeviceExtension, pVBInfo) ;
634 XGI_SetCRT1Group( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
635 XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
636*/
637
638 XGI_UpdateModeInfo( HwDeviceExtension, pVBInfo ) ;
639
640 if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
641{
642 XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
643}
644
645 return( TRUE ) ;
646}
647
648
649/* --------------------------------------------------------------------- */
650/* Function : XGI_SetCRT1Group */
651/* Input : */
652/* Output : */
653/* Description : */
654/* --------------------------------------------------------------------- */
655void XGI_SetCRT1Group( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
656{
657 USHORT StandTableIndex ,
658 RefreshRateTableIndex ,
659 b3CC ,
660 temp ;
661
662 USHORT XGINew_P3cc = pVBInfo->P3cc;
663
664 /* XGINew_CRT1Mode = ModeNo ; // SaveModeID */
665 StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
666 /* XGI_SetBIOSData(ModeNo , ModeIdIndex ) ; */
667 /* XGI_ClearBankRegs( ModeNo , ModeIdIndex ) ; */
668 XGI_SetSeqRegs( ModeNo , StandTableIndex , ModeIdIndex, pVBInfo ) ;
669 XGI_SetMiscRegs( StandTableIndex, pVBInfo ) ;
670 XGI_SetCRTCRegs( HwDeviceExtension , StandTableIndex, pVBInfo) ;
671 XGI_SetATTRegs( ModeNo , StandTableIndex , ModeIdIndex, pVBInfo ) ;
672 XGI_SetGRCRegs( StandTableIndex, pVBInfo ) ;
673 XGI_ClearExt1Regs(pVBInfo) ;
674
675/* if ( pVBInfo->IF_DEF_ExpLink ) */
676 if ( HwDeviceExtension->jChipType == XG27 )
677 {
678 if ( pVBInfo->IF_DEF_LVDS == 0 )
679 {
680 XGI_SetDefaultVCLK( pVBInfo ) ;
681 }
682 }
683
684 temp = ~ProgrammingCRT2 ;
685 pVBInfo->SetFlag &= temp ;
686 pVBInfo->SelectCRT2Rate = 0 ;
687
688 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
689 {
690 if ( pVBInfo->VBInfo & ( SetSimuScanMode | SetCRT2ToLCDA | SetInSlaveMode ) )
691 {
692 pVBInfo->SetFlag |= ProgrammingCRT2 ;
693 }
694 }
695
696 RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, pVBInfo ) ;
697 if ( RefreshRateTableIndex != 0xFFFF )
698 {
699 XGI_SetSync( RefreshRateTableIndex, pVBInfo ) ;
700 XGI_SetCRT1CRTC( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo, HwDeviceExtension ) ;
701 XGI_SetCRT1DE( HwDeviceExtension , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
702 XGI_SetCRT1Offset( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
703 XGI_SetCRT1VCLK( ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
704 }
705
706 if ( ( HwDeviceExtension->jChipType >= XG20 )&&
707 ( HwDeviceExtension->jChipType < XG27 ) ) /* fix H/W DCLK/2 bug */
708 {
709 if ( ( ModeNo == 0x00 ) | (ModeNo == 0x01) )
710 {
711 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x4E) ;
712 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , 0xE9) ;
713 b3CC =(UCHAR) XGINew_GetReg2(XGINew_P3cc) ;
714 XGINew_SetReg3(XGINew_P3cc , (b3CC |= 0x0C) ) ;
715 }
716 else if ( ( ModeNo == 0x04) | ( ModeNo == 0x05) | ( ModeNo == 0x0D) )
717 {
718 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x1B) ;
719 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , 0xE3) ;
720 b3CC = (UCHAR)XGINew_GetReg2(XGINew_P3cc) ;
721 XGINew_SetReg3(XGINew_P3cc , (b3CC |= 0x0C) ) ;
722 }
723 }
724
725 if ( HwDeviceExtension->jChipType >= XG21 )
726 {
727 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
728 if ( temp & 0xA0 )
729 {
730
731 /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ;*/ /* Enable write GPIOF */
732 /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x48 , ~0x20 ) ;*/ /* P. DWN */
733 /* XG21 CRT1 Timing */
734 if ( HwDeviceExtension->jChipType == XG27 )
735 XGI_SetXG27CRTC( ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo );
736 else
737 XGI_SetXG21CRTC( ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo );
738
739 XGI_UpdateXG21CRTC( ModeNo , pVBInfo , RefreshRateTableIndex) ;
740
741 if ( HwDeviceExtension->jChipType == XG27 )
742 XGI_SetXG27LCD( pVBInfo , RefreshRateTableIndex , ModeNo );
743 else
744 XGI_SetXG21LCD( pVBInfo , RefreshRateTableIndex , ModeNo );
745
746 if ( pVBInfo->IF_DEF_LVDS == 1 )
747 {
748 if ( HwDeviceExtension->jChipType == XG27 )
749 XGI_SetXG27LVDSPara(ModeNo,ModeIdIndex, pVBInfo );
750 else
751 XGI_SetXG21LVDSPara(ModeNo,ModeIdIndex, pVBInfo );
752 }
753 /*XGINew_SetRegOR( pVBInfo->P3d4 , 0x48 , 0x20 ) ;*/ /* P. ON */
754 }
755 }
756
757 pVBInfo->SetFlag &= ( ~ProgrammingCRT2 ) ;
758 XGI_SetCRT1FIFO( ModeNo , HwDeviceExtension, pVBInfo ) ;
759 XGI_SetCRT1ModeRegs( HwDeviceExtension , ModeNo , ModeIdIndex , RefreshRateTableIndex , pVBInfo) ;
760
761
762 /* XGI_LoadCharacter(); //dif ifdef TVFont */
763
764 XGI_LoadDAC( ModeNo , ModeIdIndex, pVBInfo ) ;
765 /* XGI_ClearBuffer( HwDeviceExtension , ModeNo, pVBInfo ) ; */
766#ifdef WIN2000
767 if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 2007/05/14 */
768 {
769 VideoDebugPrint((0, "XGI_SetCRT1Group: VBInfo->IF_DEF_CH7007==1\n"));
770 SetCH7007Regs(HwDeviceExtension, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo ) ; /* 07/05/28 */
771 }
772#endif
773}
774
775
776/* --------------------------------------------------------------------- */
777/* Function : XGI_GetModePtr */
778/* Input : */
779/* Output : */
780/* Description : */
781/* --------------------------------------------------------------------- */
782UCHAR XGI_GetModePtr( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
783{
784 UCHAR index ;
785
786 if ( ModeNo <= 0x13 )
787 index = pVBInfo->SModeIDTable[ ModeIdIndex ].St_StTableIndex ;
788 else
789 {
790 if ( pVBInfo->ModeType <= 0x02 )
791 index = 0x1B ; /* 02 -> ModeEGA */
792 else
793 index = 0x0F ;
794 }
795 return( index ) ; /* Get pVBInfo->StandTable index */
796}
797
798
799/* --------------------------------------------------------------------- */
800/* Function : XGI_SetBIOSData */
801/* Input : */
802/* Output : */
803/* Description : */
804/* --------------------------------------------------------------------- */
805/*UCHAR XGI_SetBIOSData( USHORT ModeNo , USHORT ModeIdIndex )
806{
807 return( 0 ) ;
808}
809*/
810
811/* --------------------------------------------------------------------- */
812/* Function : XGI_ClearBankRegs */
813/* Input : */
814/* Output : */
815/* Description : */
816/* --------------------------------------------------------------------- */
817/*UCHAR XGI_ClearBankRegs( USHORT ModeNo , USHORT ModeIdIndex )
818{
819 return( 0 ) ;
820}
821*/
822
823/* --------------------------------------------------------------------- */
824/* Function : XGI_SetSeqRegs */
825/* Input : */
826/* Output : */
827/* Description : */
828/* --------------------------------------------------------------------- */
829void XGI_SetSeqRegs( USHORT ModeNo , USHORT StandTableIndex , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
830{
831 UCHAR tempah ,
832 SRdata ;
833
834 USHORT i ,
835 modeflag ;
836
837 if ( ModeNo <= 0x13 )
838 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
839 else
840 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
841
842 XGINew_SetReg1( pVBInfo->P3c4 , 0x00 , 0x03 ) ; /* Set SR0 */
843 tempah=pVBInfo->StandTable[ StandTableIndex ].SR[ 0 ] ;
844
845 i = SetCRT2ToLCDA ;
846 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
847 {
848 tempah |= 0x01 ;
849 }
850 else
851 {
852 if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToLCD ) )
853 {
854 if ( pVBInfo->VBInfo & SetInSlaveMode )
855 tempah |= 0x01 ;
856 }
857 }
858
859 tempah |= 0x20 ; /* screen off */
860 XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , tempah ) ; /* Set SR1 */
861
862 for( i = 02 ; i <= 04 ; i++ )
863 {
864 SRdata = pVBInfo->StandTable[ StandTableIndex ].SR[ i - 1 ] ; /* Get SR2,3,4 from file */
865 XGINew_SetReg1( pVBInfo->P3c4 , i , SRdata ) ; /* Set SR2 3 4 */
866 }
867}
868
869
870/* --------------------------------------------------------------------- */
871/* Function : XGI_SetMiscRegs */
872/* Input : */
873/* Output : */
874/* Description : */
875/* --------------------------------------------------------------------- */
876void XGI_SetMiscRegs( USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
877{
878 UCHAR Miscdata ;
879
880 Miscdata = pVBInfo->StandTable[ StandTableIndex ].MISC ; /* Get Misc from file */
881/*
882 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
883 {
884 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
885 {
886 Miscdata |= 0x0C ;
887 }
888 }
889*/
890
891 XGINew_SetReg3( pVBInfo->P3c2 , Miscdata ) ; /* Set Misc(3c2) */
892}
893
894
895/* --------------------------------------------------------------------- */
896/* Function : XGI_SetCRTCRegs */
897/* Input : */
898/* Output : */
899/* Description : */
900/* --------------------------------------------------------------------- */
901void XGI_SetCRTCRegs( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
902{
903 UCHAR CRTCdata ;
904 USHORT i ;
905
906 CRTCdata = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
907 CRTCdata &= 0x7f ;
908 XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , CRTCdata ) ; /* Unlock CRTC */
909
910 for( i = 0 ; i <= 0x18 ; i++ )
911 {
912 CRTCdata = pVBInfo->StandTable[ StandTableIndex ].CRTC[ i ] ; /* Get CRTC from file */
913 XGINew_SetReg1( pVBInfo->P3d4 , i , CRTCdata ) ; /* Set CRTC( 3d4 ) */
914 }
915/*
916 if ( ( HwDeviceExtension->jChipType == XGI_630 )&& ( HwDeviceExtension->jChipRevision == 0x30 ) )
917 {
918 if ( pVBInfo->VBInfo & SetInSlaveMode )
919 {
920 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV ) )
921 {
922 XGINew_SetReg1( pVBInfo->P3d4 , 0x18 , 0xFE ) ;
923 }
924 }
925 }
926*/
927}
928
929
930/* --------------------------------------------------------------------- */
931/* Function : */
932/* Input : */
933/* Output : */
934/* Description : */
935/* --------------------------------------------------------------------- */
936void XGI_SetATTRegs( USHORT ModeNo , USHORT StandTableIndex , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
937{
938 UCHAR ARdata ;
939 USHORT i ,
940 modeflag ;
941
942 if ( ModeNo <= 0x13 )
943 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
944 else
945 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
946
947 for( i = 0 ; i <= 0x13 ; i++ )
948 {
949 ARdata = pVBInfo->StandTable[ StandTableIndex ].ATTR[ i ] ;
950 if ( modeflag & Charx8Dot ) /* ifndef Dot9 */
951 {
952 if ( i == 0x13 )
953 {
954 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
955 ARdata = 0 ;
956 else
957 {
958 if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToLCD ) )
959 {
960 if ( pVBInfo->VBInfo & SetInSlaveMode )
961 ARdata = 0 ;
962 }
963 }
964 }
965 }
966
967 XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
968 XGINew_SetReg3( pVBInfo->P3c0 , i ) ; /* set index */
969 XGINew_SetReg3( pVBInfo->P3c0 , ARdata ) ; /* set data */
970 }
971
972 XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
973 XGINew_SetReg3( pVBInfo->P3c0 , 0x14 ) ; /* set index */
974 XGINew_SetReg3( pVBInfo->P3c0 , 0x00 ) ; /* set data */
975 XGINew_GetReg2( pVBInfo->P3da ) ; /* Enable Attribute */
976 XGINew_SetReg3( pVBInfo->P3c0 , 0x20 ) ;
977}
978
979
980/* --------------------------------------------------------------------- */
981/* Function : XGI_SetGRCRegs */
982/* Input : */
983/* Output : */
984/* Description : */
985/* --------------------------------------------------------------------- */
986void XGI_SetGRCRegs( USHORT StandTableIndex, PVB_DEVICE_INFO pVBInfo )
987{
988 UCHAR GRdata ;
989 USHORT i ;
990
991 for( i = 0 ; i <= 0x08 ; i++ )
992 {
993 GRdata = pVBInfo->StandTable[ StandTableIndex ].GRC[ i ] ; /* Get GR from file */
994 XGINew_SetReg1( pVBInfo->P3ce , i , GRdata ) ; /* Set GR(3ce) */
995 }
996
997 if ( pVBInfo->ModeType > ModeVGA )
998 {
999 GRdata = ( UCHAR )XGINew_GetReg1( pVBInfo->P3ce , 0x05 ) ;
1000 GRdata &= 0xBF ; /* 256 color disable */
1001 XGINew_SetReg1( pVBInfo->P3ce , 0x05 , GRdata ) ;
1002 }
1003}
1004
1005
1006/* --------------------------------------------------------------------- */
1007/* Function : XGI_ClearExt1Regs */
1008/* Input : */
1009/* Output : */
1010/* Description : */
1011/* --------------------------------------------------------------------- */
1012void XGI_ClearExt1Regs(PVB_DEVICE_INFO pVBInfo)
1013{
1014 USHORT i ;
1015
1016 for( i = 0x0A ; i <= 0x0E ; i++ )
1017 XGINew_SetReg1( pVBInfo->P3c4 , i , 0x00 ) ; /* Clear SR0A-SR0E */
1018}
1019
1020
1021/* --------------------------------------------------------------------- */
1022/* Function : XGI_SetDefaultVCLK */
1023/* Input : */
1024/* Output : */
1025/* Description : */
1026/* --------------------------------------------------------------------- */
1027UCHAR XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo )
1028{
1029
1030 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , 0x20 ) ;
1031 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ 0 ].SR2B ) ;
1032 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ 0 ].SR2C ) ;
1033
1034 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , 0x10 ) ;
1035 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ 1 ].SR2B ) ;
1036 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ 1 ].SR2C ) ;
1037
1038 XGINew_SetRegAND( pVBInfo->P3c4 , 0x31 , ~0x30 ) ;
1039 return( 0 ) ;
1040}
1041
1042
1043/* --------------------------------------------------------------------- */
1044/* Function : XGI_GetRatePtrCRT2 */
1045/* Input : */
1046/* Output : */
1047/* Description : */
1048/* --------------------------------------------------------------------- */
1049USHORT XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
1050{
1051 SHORT LCDRefreshIndex[] = { 0x00 , 0x00 , 0x03 , 0x01 } ,
1052 LCDARefreshIndex[] = { 0x00 , 0x00 , 0x03 , 0x01 , 0x01 , 0x01 , 0x01 } ;
1053
1054 USHORT RefreshRateTableIndex , i ,
1055 modeflag , index , temp ;
1056
1057 if ( ModeNo <= 0x13 )
1058 {
1059 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
1060 }
1061 else
1062 {
1063 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
1064 }
1065
1066 if ( pVBInfo->IF_DEF_CH7005 == 1 )
1067 {
1068 if ( pVBInfo->VBInfo & SetCRT2ToTV )
1069 {
1070 if ( modeflag & HalfDCLK )
1071 return( 0 ) ;
1072 }
1073 }
1074
1075 if ( ModeNo < 0x14 )
1076 return( 0xFFFF ) ;
1077
1078 index = XGINew_GetReg1( pVBInfo->P3d4 , 0x33 ) ;
1079 index = index >> pVBInfo->SelectCRT2Rate ;
1080 index &= 0x0F ;
1081
1082 if ( pVBInfo->LCDInfo & LCDNonExpanding )
1083 index = 0 ;
1084
1085 if ( index > 0 )
1086 index-- ;
1087
1088 if ( pVBInfo->SetFlag & ProgrammingCRT2 )
1089 {
1090 if ( pVBInfo->IF_DEF_CH7005 == 1 )
1091 {
1092 if ( pVBInfo->VBInfo & SetCRT2ToTV )
1093 {
1094 index = 0 ;
1095 }
1096 }
1097
1098 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
1099 {
1100 if( pVBInfo->IF_DEF_LVDS == 0 )
1101 {
1102 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
1103 temp = LCDARefreshIndex[ pVBInfo->LCDResInfo & 0x0F ] ; /* 301b */
1104 else
1105 temp = LCDRefreshIndex[ pVBInfo->LCDResInfo & 0x0F ] ;
1106
1107 if ( index > temp )
1108 {
1109 index = temp ;
1110 }
1111 }
1112 else
1113 {
1114 index = 0 ;
1115 }
1116 }
1117 }
1118
1119 RefreshRateTableIndex = pVBInfo->EModeIDTable[ ModeIdIndex ].REFindex ;
1120 ModeNo = pVBInfo->RefIndex[ RefreshRateTableIndex ].ModeID ;
1121 if ( pXGIHWDE->jChipType >= XG20 ) /* for XG20, XG21, XG27 */
1122 {
1123 /*
1124 if ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag & XG2xNotSupport )
1125 {
1126 index++;
1127 }
1128 */
1129 if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 800 ) &&
1130 ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 600 ) )
1131 {
1132 index++;
1133 }
1134/* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */
1135 if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1024 ) &&
1136 ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 768 ) )
1137 {
1138 index++;
1139 }
1140 if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1280 ) &&
1141 ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 1024 ) )
1142 {
1143 index++;
1144 }
1145 }
1146
1147 i = 0 ;
1148 do
1149 {
1150 if ( pVBInfo->RefIndex[ RefreshRateTableIndex + i ].ModeID != ModeNo )
1151 break ;
1152 temp = pVBInfo->RefIndex[ RefreshRateTableIndex + i ].Ext_InfoFlag ;
1153 temp &= ModeInfoFlag ;
1154 if ( temp < pVBInfo->ModeType )
1155 break ;
1156 i++ ;
1157 index-- ;
1158
1159 } while( index != 0xFFFF ) ;
1160 if ( !( pVBInfo->VBInfo & SetCRT2ToRAMDAC ) )
1161 {
1162 if ( pVBInfo->VBInfo & SetInSlaveMode )
1163 {
1164 temp = pVBInfo->RefIndex[ RefreshRateTableIndex + i - 1 ].Ext_InfoFlag ;
1165 if ( temp & InterlaceMode )
1166 {
1167 i++ ;
1168 }
1169 }
1170 }
1171 i-- ;
1172 if ( ( pVBInfo->SetFlag & ProgrammingCRT2 ) )
1173 {
1174 temp = XGI_AjustCRT2Rate( ModeNo , ModeIdIndex , RefreshRateTableIndex , &i, pVBInfo) ;
1175 }
1176 return( RefreshRateTableIndex + i ) ; /*return(0x01|(temp1<<1)); */
1177}
1178
1179
1180/* --------------------------------------------------------------------- */
1181/* Function : XGI_AjustCRT2Rate */
1182/* Input : */
1183/* Output : */
1184/* Description : */
1185/* --------------------------------------------------------------------- */
1186BOOLEAN XGI_AjustCRT2Rate( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex , USHORT *i, PVB_DEVICE_INFO pVBInfo )
1187{
1188 USHORT tempax ,
1189 tempbx ,
1190 resinfo ,
1191 modeflag ,
1192 infoflag ;
1193
1194 if ( ModeNo <= 0x13 )
1195 {
1196 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ModeFlag */
1197 }
1198 else
1199 {
1200 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
1201 }
1202
1203 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
1204 tempbx = pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].ModeID ;
1205 tempax = 0 ;
1206
1207 if ( pVBInfo->IF_DEF_LVDS == 0 )
1208 {
1209 if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
1210 {
1211 tempax |= SupportRAMDAC2 ;
1212
1213 if ( pVBInfo->VBType & VB_XGI301C )
1214 tempax |= SupportCRT2in301C ;
1215 }
1216
1217 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) /* 301b */
1218 {
1219 tempax |= SupportLCD ;
1220
1221 if ( pVBInfo->LCDResInfo != Panel1280x1024 )
1222 {
1223 if ( pVBInfo->LCDResInfo != Panel1280x960 )
1224 {
1225 if ( pVBInfo->LCDInfo & LCDNonExpanding )
1226 {
1227 if ( resinfo >= 9 )
1228 {
1229 tempax = 0 ;
1230 return( 0 ) ;
1231 }
1232 }
1233 }
1234 }
1235 }
1236
1237 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) /* for HiTV */
1238 {
1239 if ( ( pVBInfo->VBType & VB_XGI301LV ) && ( pVBInfo->VBExtInfo == VB_YPbPr1080i ) )
1240 {
1241 tempax |= SupportYPbPr ;
1242 if ( pVBInfo->VBInfo & SetInSlaveMode )
1243 {
1244 if ( resinfo == 4 )
1245 return( 0 ) ;
1246
1247 if ( resinfo == 3 )
1248 return( 0 ) ;
1249
1250 if ( resinfo > 7 )
1251 return( 0 ) ;
1252 }
1253 }
1254 else
1255 {
1256 tempax |= SupportHiVisionTV ;
1257 if ( pVBInfo->VBInfo & SetInSlaveMode )
1258 {
1259 if ( resinfo == 4 )
1260 return( 0 ) ;
1261
1262 if ( resinfo == 3 )
1263 {
1264 if ( pVBInfo->SetFlag & TVSimuMode )
1265 return( 0 ) ;
1266 }
1267
1268 if ( resinfo > 7 )
1269 return( 0 ) ;
1270 }
1271 }
1272 }
1273 else
1274 {
1275 if ( pVBInfo->VBInfo & ( SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr | SetCRT2ToHiVisionTV ) )
1276 {
1277 tempax |= SupportTV ;
1278
1279 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
1280 {
1281 tempax |= SupportTV1024 ;
1282 }
1283
1284 if ( !( pVBInfo->VBInfo & SetPALTV ) )
1285 {
1286 if ( modeflag & NoSupportSimuTV )
1287 {
1288 if ( pVBInfo->VBInfo & SetInSlaveMode )
1289 {
1290 if ( !( pVBInfo->VBInfo & SetNotSimuMode ) )
1291 {
1292 return( 0 ) ;
1293 }
1294 }
1295 }
1296 }
1297 }
1298 }
1299 }
1300 else /* for LVDS */
1301 {
1302 if ( pVBInfo->IF_DEF_CH7005 == 1 )
1303 {
1304 if ( pVBInfo->VBInfo & SetCRT2ToTV )
1305 {
1306 tempax |= SupportCHTV ;
1307 }
1308 }
1309
1310 if ( pVBInfo->VBInfo & SetCRT2ToLCD )
1311 {
1312 tempax |= SupportLCD ;
1313
1314 if ( resinfo > 0x08 )
1315 return( 0 ) ; /* 1024x768 */
1316
1317 if ( pVBInfo->LCDResInfo < Panel1024x768 )
1318 {
1319 if ( resinfo > 0x07 )
1320 return( 0 ) ; /* 800x600 */
1321
1322 if ( resinfo == 0x04 )
1323 return( 0 ) ; /* 512x384 */
1324 }
1325 }
1326 }
1327
1328 for( ; pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].ModeID == tempbx ; ( *i )-- )
1329 {
1330 infoflag = pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].Ext_InfoFlag ;
1331 if ( infoflag & tempax )
1332 {
1333 return( 1 ) ;
1334 }
1335 if ( ( *i ) == 0 )
1336 break ;
1337 }
1338
1339 for( ( *i ) = 0 ; ; ( *i )++ )
1340 {
1341 infoflag = pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].Ext_InfoFlag ;
1342 if ( pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].ModeID != tempbx )
1343 {
1344 return( 0 ) ;
1345 }
1346
1347 if ( infoflag & tempax )
1348 {
1349 return( 1 ) ;
1350 }
1351 }
1352 return( 1 ) ;
1353}
1354
1355
1356/* --------------------------------------------------------------------- */
1357/* Function : XGI_SetSync */
1358/* Input : */
1359/* Output : */
1360/* Description : */
1361/* --------------------------------------------------------------------- */
1362void XGI_SetSync(USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
1363{
1364 USHORT sync ,
1365 temp ;
1366
1367 sync = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag >> 8 ; /* di+0x00 */
1368 sync &= 0xC0 ;
1369 temp = 0x2F ;
1370 temp |= sync ;
1371 XGINew_SetReg3( pVBInfo->P3c2 , temp ) ; /* Set Misc(3c2) */
1372}
1373
1374
1375/* --------------------------------------------------------------------- */
1376/* Function : XGI_SetCRT1CRTC */
1377/* Input : */
1378/* Output : */
1379/* Description : */
1380/* --------------------------------------------------------------------- */
1381void XGI_SetCRT1CRTC( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo, PXGI_HW_DEVICE_INFO HwDeviceExtension )
1382{
1383 UCHAR index ,
1384 data ;
1385
1386 USHORT i ;
1387
1388 index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ; /* Get index */
1389 index = index&IndexMask ;
1390
1391 data =( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
1392 data &= 0x7F ;
1393 XGINew_SetReg1(pVBInfo->P3d4,0x11,data); /* Unlock CRTC */
1394
1395 for( i = 0 ; i < 8 ; i++ )
1396 pVBInfo->TimingH[ 0 ].data[ i ] = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ i ] ;
1397
1398 for( i = 0 ; i < 7 ; i++ )
1399 pVBInfo->TimingV[ 0 ].data[ i ] = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ i + 8 ] ;
1400
1401 XGI_SetCRT1Timing_H( pVBInfo, HwDeviceExtension ) ;
1402
1403
1404
1405 XGI_SetCRT1Timing_V( ModeIdIndex , ModeNo, pVBInfo ) ;
1406
1407
1408 if( pVBInfo->ModeType > 0x03 )
1409 XGINew_SetReg1( pVBInfo->P3d4 , 0x14 , 0x4F ) ;
1410}
1411
1412
1413/* --------------------------------------------------------------------- */
1414/* Function : XGI_SetCRT1Timing_H */
1415/* Input : */
1416/* Output : */
1417/* Description : */
1418/* --------------------------------------------------------------------- */
1419void XGI_SetCRT1Timing_H( PVB_DEVICE_INFO pVBInfo, PXGI_HW_DEVICE_INFO HwDeviceExtension )
1420{
1421 UCHAR data , data1, pushax;
1422 USHORT i , j ;
1423
1424 /* XGINew_SetReg1( pVBInfo->P3d4 , 0x51 , 0 ) ; */
1425 /* XGINew_SetReg1( pVBInfo->P3d4 , 0x56 , 0 ) ; */
1426 /* XGINew_SetRegANDOR( pVBInfo->P3d4 ,0x11 , 0x7f , 0x00 ) ; */
1427
1428 data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ; /* unlock cr0-7 */
1429 data &= 0x7F ;
1430 XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , data ) ;
1431
1432 data = pVBInfo->TimingH[ 0 ].data[ 0 ] ;
1433 XGINew_SetReg1( pVBInfo->P3d4 , 0 , data ) ;
1434
1435 for( i = 0x01 ; i <= 0x04 ; i++ )
1436 {
1437 data = pVBInfo->TimingH[ 0 ].data[ i ] ;
1438 XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 1 ) , data ) ;
1439 }
1440
1441 for( i = 0x05 ; i <= 0x06 ; i++ )
1442 {
1443 data = pVBInfo->TimingH[ 0 ].data[ i ];
1444 XGINew_SetReg1( pVBInfo->P3c4 ,( USHORT )( i + 6 ) , data ) ;
1445 }
1446
1447 j = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x0e ) ;
1448 j &= 0x1F ;
1449 data = pVBInfo->TimingH[ 0 ].data[ 7 ] ;
1450 data &= 0xE0 ;
1451 data |= j ;
1452 XGINew_SetReg1( pVBInfo->P3c4 , 0x0e , data ) ;
1453
1454 if ( HwDeviceExtension->jChipType >= XG20 )
1455 {
1456 data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x04 ) ;
1457 data = data - 1 ;
1458 XGINew_SetReg1( pVBInfo->P3d4 , 0x04 , data ) ;
1459 data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x05 ) ;
1460 data1 = data ;
1461 data1 &= 0xE0 ;
1462 data &= 0x1F ;
1463 if ( data == 0 )
1464 {
1465 pushax = data ;
1466 data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x0c ) ;
1467 data &= 0xFB ;
1468 XGINew_SetReg1( pVBInfo->P3c4 , 0x0c , data ) ;
1469 data = pushax ;
1470 }
1471 data = data - 1 ;
1472 data |= data1 ;
1473 XGINew_SetReg1( pVBInfo->P3d4 , 0x05 , data ) ;
1474 data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x0e ) ;
1475 data = data >> 5 ;
1476 data = data + 3 ;
1477 if ( data > 7 )
1478 data = data - 7 ;
1479 data = data << 5 ;
1480 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0e , ~0xE0 , data ) ;
1481 }
1482}
1483
1484
1485/* --------------------------------------------------------------------- */
1486/* Function : XGI_SetCRT1Timing_V */
1487/* Input : */
1488/* Output : */
1489/* Description : */
1490/* --------------------------------------------------------------------- */
1491void XGI_SetCRT1Timing_V( USHORT ModeIdIndex , USHORT ModeNo,PVB_DEVICE_INFO pVBInfo )
1492{
1493 UCHAR data ;
1494 USHORT i , j ;
1495
1496 /* XGINew_SetReg1( pVBInfo->P3d4 , 0x51 , 0 ) ; */
1497 /* XGINew_SetReg1( pVBInfo->P3d4 , 0x56 , 0 ) ; */
1498 /* XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x11 , 0x7f , 0x00 ) ; */
1499
1500 for( i = 0x00 ; i <= 0x01 ; i++ )
1501 {
1502 data = pVBInfo->TimingV[ 0 ].data[ i ] ;
1503 XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 6 ) , data ) ;
1504 }
1505
1506 for( i = 0x02 ; i <= 0x03 ; i++ )
1507 {
1508 data = pVBInfo->TimingV[ 0 ].data[ i ] ;
1509 XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 0x0e ) , data ) ;
1510 }
1511
1512 for( i = 0x04 ; i <= 0x05 ; i++ )
1513 {
1514 data = pVBInfo->TimingV[ 0 ].data[ i ] ;
1515 XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 0x11 ) , data ) ;
1516 }
1517
1518 j = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x0a ) ;
1519 j &= 0xC0 ;
1520 data = pVBInfo->TimingV[ 0 ].data[ 6 ] ;
1521 data &= 0x3F ;
1522 data |= j ;
1523 XGINew_SetReg1( pVBInfo->P3c4 , 0x0a , data ) ;
1524
1525 data = pVBInfo->TimingV[ 0 ].data[ 6 ] ;
1526 data &= 0x80 ;
1527 data = data >> 2 ;
1528
1529 if ( ModeNo <= 0x13 )
1530 i = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
1531 else
1532 i = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
1533
1534 i &= DoubleScanMode ;
1535 if ( i )
1536 data |= 0x80 ;
1537
1538 j = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x09 ) ;
1539 j &= 0x5F ;
1540 data |= j ;
1541 XGINew_SetReg1( pVBInfo->P3d4 , 0x09 , data ) ;
1542}
1543
1544
1545/* --------------------------------------------------------------------- */
1546/* Function : XGI_SetXG21CRTC */
1547/* Input : Stand or enhance CRTC table */
1548/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
1549/* Description : Set LCD timing */
1550/* --------------------------------------------------------------------- */
1551void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
1552{
1553 UCHAR StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx ;
1554 USHORT Temp1, Temp2, Temp3 ;
1555
1556 if ( ModeNo <= 0x13 )
1557 {
1558 StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
1559 Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 4 ] ; /* CR04 HRS */
1560 XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E [7:0]->HRS */
1561 Tempbx = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 5 ] ; /* Tempbx: CR05 HRE */
1562 Tempbx &= 0x1F ; /* Tempbx: HRE[4:0] */
1563 Tempcx = Tempax ;
1564 Tempcx &= 0xE0 ; /* Tempcx: HRS[7:5] */
1565 Tempdx = Tempcx | Tempbx ; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
1566 if ( Tempbx < ( Tempax & 0x1F ) ) /* IF HRE < HRS */
1567 Tempdx |= 0x20 ; /* Tempdx: HRE = HRE + 0x20 */
1568 Tempdx <<= 2 ; /* Tempdx << 2 */
1569 XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , Tempdx ) ; /* SR2F [7:2]->HRE */
1570 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
1571
1572 Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 16 ] ; /* Tempax: CR16 VRS */
1573 Tempbx = Tempax ; /* Tempbx=Tempax */
1574 Tempax &= 0x01 ; /* Tempax: VRS[0] */
1575 XGINew_SetRegOR( pVBInfo->P3c4 , 0x33 , Tempax ) ; /* SR33[0]->VRS */
1576 Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ; /* Tempax: CR7 VRS */
1577 Tempdx = Tempbx >> 1 ; /* Tempdx: VRS[7:1] */
1578 Tempcx = Tempax & 0x04 ; /* Tempcx: CR7[2] */
1579 Tempcx <<= 5 ; /* Tempcx[7]: VRS[8] */
1580 Tempdx |= Tempcx ; /* Tempdx: VRS[8:1] */
1581 XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempdx ) ; /* SR34[7:0]: VRS[8:1] */
1582
1583 Temp1 = Tempcx << 1 ; /* Temp1[8]: VRS[8] UCHAR -> USHORT */
1584 Temp1 |= Tempbx ; /* Temp1[8:0]: VRS[8:0] */
1585 Tempax &= 0x80 ; /* Tempax[7]: CR7[7] */
1586 Temp2 = Tempax << 2 ; /* Temp2[9]: VRS[9] */
1587 Temp1 |= Temp2 ; /* Temp1[9:0]: VRS[9:0] */
1588
1589 Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 17 ] ; /* CR16 VRE */
1590 Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
1591 Temp2 = Temp1 & 0x3F0 ; /* Temp2[9:4]: VRS[9:4] */
1592 Temp2 |= Tempax ; /* Temp2[9:0]: VRE[9:0] */
1593 Temp3 = Temp1 & 0x0F ; /* Temp3[3:0]: VRS[3:0] */
1594 if ( Tempax < Temp3 ) /* VRE[3:0]<VRS[3:0] */
1595 Temp2 |= 0x10 ; /* Temp2: VRE + 0x10 */
1596 Temp2 &= 0xFF ; /* Temp2[7:0]: VRE[7:0] */
1597 Tempax = (UCHAR)Temp2 ; /* Tempax[7:0]: VRE[7:0] */
1598 Tempax <<= 2 ; /* Tempax << 2: VRE[5:0] */
1599 Temp1 &= 0x600 ; /* Temp1[10:9]: VRS[10:9] */
1600 Temp1 >>= 9 ; /* [10:9]->[1:0] */
1601 Tempbx = (UCHAR)Temp1 ; /* Tempbx[1:0]: VRS[10:9] */
1602 Tempax |= Tempbx ; /* VRE[5:0]VRS[10:9] */
1603 Tempax &= 0x7F ;
1604 XGINew_SetReg1( pVBInfo->P3c4 , 0x3F , Tempax ) ; /* SR3F D[7:2]->VRE D[1:0]->VRS */
1605 }
1606 else
1607 {
1608 index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
1609 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
1610 Tempcx = Tempax ; /* Tempcx: HRS */
1611 XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E[7:0]->HRS */
1612
1613 Tempdx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SRB */
1614 Tempdx &= 0xC0 ; /* Tempdx[7:6]: SRB[7:6] */
1615 Temp1 = Tempdx ; /* Temp1[7:6]: HRS[9:8] */
1616 Temp1 <<= 2 ; /* Temp1[9:8]: HRS[9:8] */
1617 Temp1 |= Tempax ; /* Temp1[9:0]: HRS[9:0] */
1618
1619 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 4 ] ; /* CR5 HRE */
1620 Tempax &= 0x1F ; /* Tempax[4:0]: HRE[4:0] */
1621
1622 Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 6 ] ; /* SRC */
1623 Tempbx &= 0x04 ; /* Tempbx[2]: HRE[5] */
1624 Tempbx <<= 3 ; /* Tempbx[5]: HRE[5] */
1625 Tempax |= Tempbx ; /* Tempax[5:0]: HRE[5:0] */
1626
1627 Temp2 = Temp1 & 0x3C0 ; /* Temp2[9:6]: HRS[9:6] */
1628 Temp2 |= Tempax ; /* Temp2[9:0]: HRE[9:0] */
1629
1630 Tempcx &= 0x3F ; /* Tempcx[5:0]: HRS[5:0] */
1631 if( Tempax < Tempcx ) /* HRE < HRS */
1632 Temp2 |= 0x40 ; /* Temp2 + 0x40 */
1633
1634 Temp2 &= 0xFF ;
1635 Tempax = (UCHAR)Temp2 ; /* Tempax: HRE[7:0] */
1636 Tempax <<= 2 ; /* Tempax[7:2]: HRE[5:0] */
1637 Tempdx >>= 6 ; /* Tempdx[7:6]->[1:0] HRS[9:8] */
1638 Tempax |= Tempdx ; /* HRE[5:0]HRS[9:8] */
1639 XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , Tempax ) ; /* SR2F D[7:2]->HRE, D[1:0]->HRS */
1640 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
1641
1642 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 10 ] ; /* CR10 VRS */
1643 Tempbx = Tempax ; /* Tempbx: VRS */
1644 Tempax &= 0x01 ; /* Tempax[0]: VRS[0] */
1645 XGINew_SetRegOR( pVBInfo->P3c4 , 0x33 , Tempax ) ; /* SR33[0]->VRS[0] */
1646 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 9 ] ; /* CR7[2][7] VRE */
1647 Tempcx = Tempbx >> 1 ; /* Tempcx[6:0]: VRS[7:1] */
1648 Tempdx = Tempax & 0x04 ; /* Tempdx[2]: CR7[2] */
1649 Tempdx <<= 5 ; /* Tempdx[7]: VRS[8] */
1650 Tempcx |= Tempdx ; /* Tempcx[7:0]: VRS[8:1] */
1651 XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempcx ) ; /* SR34[8:1]->VRS */
1652
1653 Temp1 = Tempdx ; /* Temp1[7]: Tempdx[7] */
1654 Temp1 <<= 1 ; /* Temp1[8]: VRS[8] */
1655 Temp1 |= Tempbx ; /* Temp1[8:0]: VRS[8:0] */
1656 Tempax &= 0x80 ;
1657 Temp2 = Tempax << 2 ; /* Temp2[9]: VRS[9] */
1658 Temp1 |= Temp2 ; /* Temp1[9:0]: VRS[9:0] */
1659 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempax: SRA */
1660 Tempax &= 0x08 ; /* Tempax[3]: VRS[3] */
1661 Temp2 = Tempax ;
1662 Temp2 <<= 7 ; /* Temp2[10]: VRS[10] */
1663 Temp1 |= Temp2 ; /* Temp1[10:0]: VRS[10:0] */
1664
1665 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 11 ] ; /* Tempax: CR11 VRE */
1666 Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
1667 Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempbx: SRA */
1668 Tempbx &= 0x20 ; /* Tempbx[5]: VRE[5] */
1669 Tempbx >>= 1 ; /* Tempbx[4]: VRE[4] */
1670 Tempax |= Tempbx ; /* Tempax[4:0]: VRE[4:0] */
1671 Temp2 = Temp1 & 0x7E0 ; /* Temp2[10:5]: VRS[10:5] */
1672 Temp2 |= Tempax ; /* Temp2[10:5]: VRE[10:5] */
1673
1674 Temp3 = Temp1 & 0x1F ; /* Temp3[4:0]: VRS[4:0] */
1675 if ( Tempax < Temp3 ) /* VRE < VRS */
1676 Temp2 |= 0x20 ; /* VRE + 0x20 */
1677
1678 Temp2 &= 0xFF ;
1679 Tempax = (UCHAR)Temp2 ; /* Tempax: VRE[7:0] */
1680 Tempax <<= 2 ; /* Tempax[7:0]; VRE[5:0]00 */
1681 Temp1 &= 0x600 ; /* Temp1[10:9]: VRS[10:9] */
1682 Temp1 >>= 9 ; /* Temp1[1:0]: VRS[10:9] */
1683 Tempbx = (UCHAR)Temp1 ;
1684 Tempax |= Tempbx ; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
1685 Tempax &= 0x7F ;
1686 XGINew_SetReg1( pVBInfo->P3c4 , 0x3F , Tempax ) ; /* SR3F D[7:2]->VRE D[1:0]->VRS */
1687 }
1688}
1689
1690void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
1691{
1692 USHORT StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx ;
1693
1694 if ( ModeNo <= 0x13 )
1695 {
1696 StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
1697 Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 4 ] ; /* CR04 HRS */
1698 XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E [7:0]->HRS */
1699 Tempbx = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 5 ] ; /* Tempbx: CR05 HRE */
1700 Tempbx &= 0x1F ; /* Tempbx: HRE[4:0] */
1701 Tempcx = Tempax ;
1702 Tempcx &= 0xE0 ; /* Tempcx: HRS[7:5] */
1703 Tempdx = Tempcx | Tempbx ; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
1704 if ( Tempbx < ( Tempax & 0x1F ) ) /* IF HRE < HRS */
1705 Tempdx |= 0x20 ; /* Tempdx: HRE = HRE + 0x20 */
1706 Tempdx <<= 2 ; /* Tempdx << 2 */
1707 XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , Tempdx ) ; /* SR2F [7:2]->HRE */
1708 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
1709
1710 Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 16 ] ; /* Tempax: CR10 VRS */
1711 XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempax ) ; /* SR34[7:0]->VRS */
1712 Tempcx = Tempax ; /* Tempcx=Tempax=VRS[7:0] */
1713 Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
1714 Tempbx = Tempax ; /* Tempbx=CR07 */
1715 Tempax &= 0x04 ; /* Tempax[2]: CR07[2] VRS[8] */
1716 Tempax >>= 2;
1717 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x01, Tempax ) ; /* SR35 D[0]->VRS D[8] */
1718 Tempcx |= (Tempax << 8) ; /* Tempcx[8] |= VRS[8] */
1719 Tempcx |= (Tempbx & 0x80)<<2; /* Tempcx[9] |= VRS[9] */
1720
1721
1722 Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 17 ] ; /* CR11 VRE */
1723 Tempax &= 0x0F ; /* Tempax: VRE[3:0] */
1724 Tempbx = Tempcx ; /* Tempbx=Tempcx=VRS[9:0] */
1725 Tempbx &= 0x3F0 ; /* Tempbx[9:4]: VRS[9:4] */
1726 Tempbx |= Tempax ; /* Tempbx[9:0]: VRE[9:0] */
1727 if ( Tempax <= (Tempcx & 0x0F) ) /* VRE[3:0]<=VRS[3:0] */
1728 Tempbx |= 0x10 ; /* Tempbx: VRE + 0x10 */
1729 Tempax = (UCHAR)Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
1730 Tempax <<= 2 ; /* Tempax << 2: VRE[5:0] */
1731 Tempcx = (Tempcx&0x600)>>8; /* Tempcx VRS[10:9] */
1732 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC, Tempax ) ; /* SR3F D[7:2]->VRE D[5:0] */
1733 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x06, Tempcx ) ; /* SR35 D[2:1]->VRS[10:9] */
1734 }
1735 else
1736 {
1737 index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
1738 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
1739 Tempbx = Tempax ; /* Tempbx: HRS[7:0] */
1740 XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E[7:0]->HRS */
1741
1742 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SR0B */
1743 Tempax &= 0xC0 ; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
1744 Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
1745
1746 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 4 ] ; /* CR5 HRE */
1747 Tempax &= 0x1F ; /* Tempax[4:0]: HRE[4:0] */
1748 Tempcx = Tempax ; /* Tempcx: HRE[4:0] */
1749
1750 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 6 ] ; /* SRC */
1751 Tempax &= 0x04 ; /* Tempax[2]: HRE[5] */
1752 Tempax <<= 3 ; /* Tempax[5]: HRE[5] */
1753 Tempcx |= Tempax ; /* Tempcx[5:0]: HRE[5:0] */
1754
1755 Tempbx = Tempbx & 0x3C0 ; /* Tempbx[9:6]: HRS[9:6] */
1756 Tempbx |= Tempcx ; /* Tempbx: HRS[9:6]HRE[5:0] */
1757
1758 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
1759 Tempax &= 0x3F ; /* Tempax: HRS[5:0] */
1760 if( Tempcx <= Tempax ) /* HRE[5:0] < HRS[5:0] */
1761 Tempbx += 0x40 ; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
1762
1763 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SR0B */
1764 Tempax &= 0xC0 ; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
1765 Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
1766 Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
1767 XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , Tempax ) ; /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
1768 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
1769
1770 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 10 ] ; /* CR10 VRS */
1771 XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempax ) ; /* SR34[7:0]->VRS[7:0] */
1772
1773 Tempcx = Tempax ; /* Tempcx <= VRS[7:0] */
1774 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 9 ] ; /* CR7[7][2] VRS[9][8] */
1775 Tempbx = Tempax ; /* Tempbx <= CR07[7:0] */
1776 Tempax = Tempax & 0x04 ; /* Tempax[2]: CR7[2]: VRS[8] */
1777 Tempax >>= 2 ; /* Tempax[0]: VRS[8] */
1778 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x01 , Tempax ) ; /* SR35[0]: VRS[8] */
1779 Tempcx |= (Tempax<<8) ; /* Tempcx <= VRS[8:0] */
1780 Tempcx |= ((Tempbx&0x80)<<2) ; /* Tempcx <= VRS[9:0] */
1781 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempax: SR0A */
1782 Tempax &= 0x08; /* SR0A[3] VRS[10] */
1783 Tempcx |= (Tempax<<7) ; /* Tempcx <= VRS[10:0] */
1784
1785
1786 Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 11 ] ; /* Tempax: CR11 VRE */
1787 Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
1788 Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempbx: SR0A */
1789 Tempbx &= 0x20 ; /* Tempbx[5]: SR0A[5]: VRE[4] */
1790 Tempbx >>= 1 ; /* Tempbx[4]: VRE[4] */
1791 Tempax |= Tempbx ; /* Tempax[4:0]: VRE[4:0] */
1792 Tempbx = Tempcx ; /* Tempbx: VRS[10:0] */
1793 Tempbx &= 0x7E0 ; /* Tempbx[10:5]: VRS[10:5] */
1794 Tempbx |= Tempax ; /* Tempbx: VRS[10:5]VRE[4:0] */
1795
1796 if ( Tempbx <= Tempcx ) /* VRE <= VRS */
1797 Tempbx |= 0x20 ; /* VRE + 0x20 */
1798
1799 Tempax = (Tempbx<<2) & 0xFF ; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
1800 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC , Tempax ) ; /* SR3F[7:2]:VRE[5:0] */
1801 Tempax = Tempcx >> 8;
1802 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x07 , Tempax ) ; /* SR35[2:0]:VRS[10:8] */
1803 }
1804}
1805
1806
1807/* --------------------------------------------------------------------- */
1808/* Function : XGI_SetXG21LCD */
1809/* Input : */
1810/* Output : FCLK duty cycle, FCLK delay compensation */
1811/* Description : All values set zero */
1812/* --------------------------------------------------------------------- */
1813void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo)
1814{
1815 USHORT Data , Temp , b3CC ;
1816 USHORT XGI_P3cc ;
1817
1818 XGI_P3cc = pVBInfo->P3cc ;
1819
1820 XGINew_SetReg1( pVBInfo->P3d4 , 0x2E , 0x00 ) ;
1821 XGINew_SetReg1( pVBInfo->P3d4 , 0x2F , 0x00 ) ;
1822 XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , 0x00 ) ;
1823 XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , 0x00 ) ;
1824 if ( ((*pVBInfo->pDVOSetting)&0xC0) == 0xC0 )
1825 {
1826 XGINew_SetReg1( pVBInfo->P3d4 , 0x2E , *pVBInfo->pCR2E ) ;
1827 XGINew_SetReg1( pVBInfo->P3d4 , 0x2F , *pVBInfo->pCR2F ) ;
1828 XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , *pVBInfo->pCR46 ) ;
1829 XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , *pVBInfo->pCR47 ) ;
1830 }
1831
1832 Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
1833
1834 if ( Temp & 0x01 )
1835 {
1836 XGINew_SetRegOR( pVBInfo->P3c4 , 0x06 , 0x40 ) ; /* 18 bits FP */
1837 XGINew_SetRegOR( pVBInfo->P3c4 , 0x09 , 0x40 ) ;
1838 }
1839
1840 XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x01 ) ; /* Negative blank polarity */
1841
1842 XGINew_SetRegAND( pVBInfo->P3c4 , 0x30 , ~0x20 ) ;
1843 XGINew_SetRegAND( pVBInfo->P3c4 , 0x35 , ~0x80 ) ;
1844
1845 if ( ModeNo <= 0x13 )
1846 {
1847 b3CC = (UCHAR) XGINew_GetReg2( XGI_P3cc ) ;
1848 if ( b3CC & 0x40 )
1849 XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
1850 if ( b3CC & 0x80 )
1851 XGINew_SetRegOR( pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
1852 }
1853 else
1854 {
1855 Data = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
1856 if ( Data & 0x4000 )
1857 XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
1858 if ( Data & 0x8000 )
1859 XGINew_SetRegOR( pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
1860 }
1861}
1862
1863void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo)
1864{
1865 USHORT Data , Temp , b3CC ;
1866 USHORT XGI_P3cc ;
1867
1868 XGI_P3cc = pVBInfo->P3cc ;
1869
1870 XGINew_SetReg1( pVBInfo->P3d4 , 0x2E , 0x00 ) ;
1871 XGINew_SetReg1( pVBInfo->P3d4 , 0x2F , 0x00 ) ;
1872 XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , 0x00 ) ;
1873 XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , 0x00 ) ;
1874
1875 Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
1876 if ( ( Temp & 0x03 ) == 0 ) /* dual 12 */
1877 {
1878 XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , 0x13 ) ;
1879 XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , 0x13 ) ;
1880 }
1881
1882 if ( ((*pVBInfo->pDVOSetting)&0xC0) == 0xC0 )
1883 {
1884 XGINew_SetReg1( pVBInfo->P3d4 , 0x2E , *pVBInfo->pCR2E ) ;
1885 XGINew_SetReg1( pVBInfo->P3d4 , 0x2F , *pVBInfo->pCR2F ) ;
1886 XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , *pVBInfo->pCR46 ) ;
1887 XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , *pVBInfo->pCR47 ) ;
1888 }
1889
1890 XGI_SetXG27FPBits(pVBInfo);
1891
1892 XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x01 ) ; /* Negative blank polarity */
1893
1894 XGINew_SetRegAND( pVBInfo->P3c4 , 0x30 , ~0x20 ) ; /* Hsync polarity */
1895 XGINew_SetRegAND( pVBInfo->P3c4 , 0x35 , ~0x80 ) ; /* Vsync polarity */
1896
1897 if ( ModeNo <= 0x13 )
1898 {
1899 b3CC = (UCHAR) XGINew_GetReg2( XGI_P3cc ) ;
1900 if ( b3CC & 0x40 )
1901 XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
1902 if ( b3CC & 0x80 )
1903 XGINew_SetRegOR( pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
1904 }
1905 else
1906 {
1907 Data = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
1908 if ( Data & 0x4000 )
1909 XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
1910 if ( Data & 0x8000 )
1911 XGINew_SetRegOR( pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
1912 }
1913}
1914
1915/* --------------------------------------------------------------------- */
1916/* Function : XGI_UpdateXG21CRTC */
1917/* Input : */
1918/* Output : CRT1 CRTC */
1919/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
1920/* --------------------------------------------------------------------- */
1921void XGI_UpdateXG21CRTC( USHORT ModeNo , PVB_DEVICE_INFO pVBInfo , USHORT RefreshRateTableIndex )
1922{
1923 int i , index = -1;
1924
1925 XGINew_SetRegAND( pVBInfo->P3d4 , 0x11 , 0x7F ) ; /* Unlock CR0~7 */
1926 if ( ModeNo <= 0x13 )
1927 {
1928 for( i = 0 ; i < 12 ; i++ )
1929 {
1930 if ( ModeNo == pVBInfo->UpdateCRT1[ i ].ModeID )
1931 index = i ;
1932 }
1933 }
1934 else
1935 {
1936 if ( ModeNo == 0x2E && ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC == RES640x480x60 ) )
1937 index = 12 ;
1938 else if ( ModeNo == 0x2E && ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC == RES640x480x72 ) )
1939 index = 13 ;
1940 else if ( ModeNo == 0x2F )
1941 index = 14 ;
1942 else if ( ModeNo == 0x50 )
1943 index = 15 ;
1944 else if ( ModeNo == 0x59 )
1945 index = 16 ;
1946 }
1947
1948 if( index != -1 )
1949 {
1950 XGINew_SetReg1( pVBInfo->P3d4 , 0x02 , pVBInfo->UpdateCRT1[ index ].CR02 ) ;
1951 XGINew_SetReg1( pVBInfo->P3d4 , 0x03 , pVBInfo->UpdateCRT1[ index ].CR03 ) ;
1952 XGINew_SetReg1( pVBInfo->P3d4 , 0x15 , pVBInfo->UpdateCRT1[ index ].CR15 ) ;
1953 XGINew_SetReg1( pVBInfo->P3d4 , 0x16 , pVBInfo->UpdateCRT1[ index ].CR16 ) ;
1954 }
1955}
1956
1957
1958/* --------------------------------------------------------------------- */
1959/* Function : XGI_SetCRT1DE */
1960/* Input : */
1961/* Output : */
1962/* Description : */
1963/* --------------------------------------------------------------------- */
1964void XGI_SetCRT1DE( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo,USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
1965{
1966 USHORT resindex ,
1967 tempax ,
1968 tempbx ,
1969 tempcx ,
1970 temp ,
1971 modeflag ;
1972
1973 UCHAR data ;
1974
1975 resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
1976
1977 if ( ModeNo <= 0x13 )
1978 {
1979 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
1980 tempax = pVBInfo->StResInfo[ resindex ].HTotal ;
1981 tempbx = pVBInfo->StResInfo[ resindex ].VTotal ;
1982 }
1983 else
1984 {
1985 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
1986 tempax = pVBInfo->ModeResInfo[ resindex ].HTotal ;
1987 tempbx = pVBInfo->ModeResInfo[ resindex ].VTotal ;
1988 }
1989
1990 if ( modeflag & HalfDCLK )
1991 tempax = tempax >> 1 ;
1992
1993 if ( ModeNo > 0x13 )
1994 {
1995 if ( modeflag & HalfDCLK )
1996 tempax = tempax << 1 ;
1997
1998 temp = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
1999
2000 if ( temp & InterlaceMode )
2001 tempbx = tempbx >> 1 ;
2002
2003 if ( modeflag & DoubleScanMode )
2004 tempbx = tempbx << 1 ;
2005 }
2006
2007 tempcx = 8 ;
2008
2009 /* if ( !( modeflag & Charx8Dot ) ) */
2010 /* tempcx = 9 ; */
2011
2012 tempax /= tempcx ;
2013 tempax -= 1 ;
2014 tempbx -= 1 ;
2015 tempcx = tempax ;
2016 temp = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
2017 data = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
2018 data &= 0x7F ;
2019 XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , data ) ; /* Unlock CRTC */
2020 XGINew_SetReg1( pVBInfo->P3d4 , 0x01 , ( USHORT )( tempcx & 0xff ) ) ;
2021 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x0b , ~0x0c , ( USHORT )( ( tempcx & 0x0ff00 ) >> 10 ) ) ;
2022 XGINew_SetReg1( pVBInfo->P3d4 , 0x12 , ( USHORT )( tempbx & 0xff ) ) ;
2023 tempax = 0 ;
2024 tempbx = tempbx >> 8 ;
2025
2026 if ( tempbx & 0x01 )
2027 tempax |= 0x02 ;
2028
2029 if ( tempbx & 0x02 )
2030 tempax |= 0x40 ;
2031
2032 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x42 , tempax ) ;
2033 data =( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x07 ) ;
2034 data &= 0xFF ;
2035 tempax = 0 ;
2036
2037 if ( tempbx & 0x04 )
2038 tempax |= 0x02 ;
2039
2040 XGINew_SetRegANDOR( pVBInfo->P3d4 ,0x0a , ~0x02 , tempax ) ;
2041 XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , temp ) ;
2042}
2043
2044
2045/* --------------------------------------------------------------------- */
2046/* Function : XGI_GetResInfo */
2047/* Input : */
2048/* Output : */
2049/* Description : */
2050/* --------------------------------------------------------------------- */
2051USHORT XGI_GetResInfo(USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
2052{
2053 USHORT resindex ;
2054
2055 if ( ModeNo <= 0x13 )
2056 {
2057 resindex = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ; /* si+St_ResInfo */
2058 }
2059 else
2060 {
2061 resindex = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo */
2062 }
2063 return( resindex ) ;
2064}
2065
2066
2067/* --------------------------------------------------------------------- */
2068/* Function : XGI_SetCRT1Offset */
2069/* Input : */
2070/* Output : */
2071/* Description : */
2072/* --------------------------------------------------------------------- */
2073void XGI_SetCRT1Offset( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
2074{
2075 USHORT temp ,
2076 ah ,
2077 al ,
2078 temp2 ,
2079 i ,
2080 DisplayUnit ;
2081
2082 /* GetOffset */
2083 temp = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeInfo ;
2084 temp = temp >> 8 ;
2085 temp = pVBInfo->ScreenOffset[ temp ] ;
2086
2087 temp2 = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
2088 temp2 &= InterlaceMode ;
2089
2090 if ( temp2 )
2091 temp = temp << 1;
2092
2093 temp2 = pVBInfo->ModeType - ModeEGA ;
2094
2095 switch( temp2 )
2096 {
2097 case 0:
2098 temp2 = 1 ;
2099 break ;
2100 case 1:
2101 temp2 = 2 ;
2102 break ;
2103 case 2:
2104 temp2 = 4 ;
2105 break ;
2106 case 3:
2107 temp2 = 4 ;
2108 break ;
2109 case 4:
2110 temp2 = 6 ;
2111 break;
2112 case 5:
2113 temp2 = 8 ;
2114 break ;
2115 default:
2116 break ;
2117 }
2118
2119 if ( ( ModeNo >= 0x26 ) && ( ModeNo <= 0x28 ) )
2120 temp = temp * temp2 + temp2 / 2 ;
2121 else
2122 temp *= temp2 ;
2123
2124 /* SetOffset */
2125 DisplayUnit = temp ;
2126 temp2 = temp ;
2127 temp = temp >> 8 ; /* ah */
2128 temp &= 0x0F ;
2129 i = XGINew_GetReg1( pVBInfo->P3c4 , 0x0E ) ;
2130 i &= 0xF0 ;
2131 i |= temp ;
2132 XGINew_SetReg1( pVBInfo->P3c4 , 0x0E , i ) ;
2133
2134 temp =( UCHAR )temp2 ;
2135 temp &= 0xFF ; /* al */
2136 XGINew_SetReg1( pVBInfo->P3d4 , 0x13 , temp ) ;
2137
2138 /* SetDisplayUnit */
2139 temp2 = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
2140 temp2 &= InterlaceMode ;
2141 if ( temp2 )
2142 DisplayUnit >>= 1 ;
2143
2144 DisplayUnit = DisplayUnit << 5 ;
2145 ah = ( DisplayUnit & 0xff00 ) >> 8 ;
2146 al = DisplayUnit & 0x00ff ;
2147 if ( al == 0 )
2148 ah += 1 ;
2149 else
2150 ah += 2 ;
2151
2152 if ( HwDeviceExtension->jChipType >= XG20 )
2153 if ( ( ModeNo == 0x4A ) | (ModeNo == 0x49 ) )
2154 ah -= 1 ;
2155
2156 XGINew_SetReg1( pVBInfo->P3c4 , 0x10 , ah ) ;
2157}
2158
2159
2160/* --------------------------------------------------------------------- */
2161/* Function : XGI_SetCRT1VCLK */
2162/* Input : */
2163/* Output : */
2164/* Description : */
2165/* --------------------------------------------------------------------- */
2166void XGI_SetCRT1VCLK( USHORT ModeNo , USHORT ModeIdIndex ,
2167 PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
2168{
2169 UCHAR index , data ;
2170 USHORT vclkindex ;
2171
2172 if ( pVBInfo->IF_DEF_LVDS == 1 )
2173 {
2174 index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
2175 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x31 ) & 0xCF ;
2176 XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , data ) ;
2177 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ index ].SR2B ) ;
2178 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ index ].SR2C ) ;
2179 XGINew_SetReg1( pVBInfo->P3c4 , 0x2D , 0x01 ) ;
2180 }
2181 else if ( ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) ) && ( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
2182 {
2183 vclkindex = XGI_GetVCLK2Ptr( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
2184 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x31 ) & 0xCF ;
2185 XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , data ) ;
2186 data = pVBInfo->VBVCLKData[ vclkindex ].Part4_A ;
2187 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , data ) ;
2188 data = pVBInfo->VBVCLKData[ vclkindex ].Part4_B ;
2189 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , data ) ;
2190 XGINew_SetReg1( pVBInfo->P3c4 , 0x2D , 0x01 ) ;
2191 }
2192 else
2193 {
2194 index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
2195 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x31 ) & 0xCF ;
2196 XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , data ) ;
2197 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ index ].SR2B ) ;
2198 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ index ].SR2C ) ;
2199 XGINew_SetReg1( pVBInfo->P3c4 , 0x2D , 0x01 ) ;
2200 }
2201
2202 if ( HwDeviceExtension->jChipType >= XG20 )
2203 {
2204 if ( pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag & HalfDCLK )
2205 {
2206 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x2B ) ;
2207 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , data ) ;
2208 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x2C ) ;
2209 index = data ;
2210 index &= 0xE0 ;
2211 data &= 0x1F ;
2212 data = data << 1 ;
2213 data += 1 ;
2214 data |= index ;
2215 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , data ) ;
2216 }
2217 }
2218}
2219
2220
2221/* --------------------------------------------------------------------- */
2222/* Function : XGI_SetCRT1FIFO */
2223/* Input : */
2224/* Output : */
2225/* Description : */
2226/* --------------------------------------------------------------------- */
2227void XGI_SetCRT1FIFO( USHORT ModeNo , PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo )
2228{
2229 USHORT data ;
2230
2231 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x3D ) ;
2232 data &= 0xfe ;
2233 XGINew_SetReg1( pVBInfo->P3c4 , 0x3D , data ) ; /* diable auto-threshold */
2234
2235 if ( ModeNo > 0x13 )
2236 {
2237 XGINew_SetReg1( pVBInfo->P3c4 , 0x08 , 0x34 ) ;
2238 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x09 ) ;
2239 data &= 0xC0 ;
2240 XGINew_SetReg1( pVBInfo->P3c4 , 0x09 , data | 0x30) ;
2241 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x3D ) ;
2242 data |= 0x01 ;
2243 XGINew_SetReg1( pVBInfo->P3c4 , 0x3D , data ) ;
2244 }
2245 else
2246 {
2247 if (HwDeviceExtension->jChipType == XG27)
2248 {
2249 XGINew_SetReg1( pVBInfo->P3c4 , 0x08 , 0x0E ) ;
2250 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x09 ) ;
2251 data &= 0xC0 ;
2252 XGINew_SetReg1( pVBInfo->P3c4 , 0x09 , data | 0x20 ) ;
2253 }
2254 else
2255 {
2256 XGINew_SetReg1( pVBInfo->P3c4 , 0x08 , 0xAE ) ;
2257 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x09 ) ;
2258 data &= 0xF0 ;
2259 XGINew_SetReg1( pVBInfo->P3c4 , 0x09 , data ) ;
2260 }
2261 }
2262
2263 if (HwDeviceExtension->jChipType == XG21)
2264 {
2265 XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
2266 }
2267}
2268
2269
2270/* --------------------------------------------------------------------- */
2271/* Function : XGI_SetCRT1ModeRegs */
2272/* Input : */
2273/* Output : */
2274/* Description : */
2275/* --------------------------------------------------------------------- */
2276void XGI_SetCRT1ModeRegs( PXGI_HW_DEVICE_INFO HwDeviceExtension ,
2277 USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo )
2278{
2279 USHORT data ,
2280 data2 ,
2281 data3 ,
2282 infoflag = 0 ,
2283 modeflag ,
2284 resindex ,
2285 xres ;
2286
2287 if ( ModeNo > 0x13 )
2288 {
2289 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
2290 infoflag = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
2291 }
2292 else
2293 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ModeFlag */
2294
2295 if ( XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) & 0x01 )
2296 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1F , 0x3F , 0x00 ) ;
2297
2298 if ( ModeNo > 0x13 )
2299 data = infoflag ;
2300 else
2301 data = 0 ;
2302
2303 data2 = 0 ;
2304
2305 if ( ModeNo > 0x13 )
2306 {
2307 if ( pVBInfo->ModeType > 0x02 )
2308 {
2309 data2 |= 0x02 ;
2310 data3 = pVBInfo->ModeType - ModeVGA ;
2311 data3 = data3 << 2 ;
2312 data2 |= data3 ;
2313 }
2314 }
2315
2316 data &= InterlaceMode ;
2317
2318 if ( data )
2319 data2 |= 0x20 ;
2320
2321 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x06 , ~0x3F , data2 ) ;
2322 /* XGINew_SetReg1(pVBInfo->P3c4,0x06,data2); */
2323 resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
2324 if ( ModeNo <= 0x13 )
2325 xres = pVBInfo->StResInfo[ resindex ].HTotal ;
2326 else
2327 xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
2328
2329 data = 0x0000 ;
2330 if ( infoflag & InterlaceMode )
2331 {
2332 if ( xres == 1024 )
2333 data = 0x0035 ;
2334 else if ( xres == 1280 )
2335 data = 0x0048 ;
2336 }
2337
2338 data2 = data & 0x00FF ;
2339 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x19 , 0xFF , data2 ) ;
2340 data2 = ( data & 0xFF00 ) >> 8 ;
2341 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x19 , 0xFC , data2 ) ;
2342
2343 if( modeflag & HalfDCLK )
2344 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xF7 , 0x08 ) ;
2345
2346 data2 = 0 ;
2347
2348 if ( modeflag & LineCompareOff )
2349 data2 |= 0x08 ;
2350
2351 if ( ModeNo > 0x13 )
2352 {
2353 if ( pVBInfo->ModeType == ModeEGA )
2354 data2 |= 0x40 ;
2355 }
2356
2357 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0F , ~0x48 , data2 ) ;
2358 data = 0x60 ;
2359 if ( pVBInfo->ModeType != ModeText )
2360 {
2361 data = data ^ 0x60 ;
2362 if ( pVBInfo->ModeType != ModeEGA )
2363 {
2364 data = data ^ 0xA0 ;
2365 }
2366 }
2367 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x21 , 0x1F , data ) ;
2368
2369 XGI_SetVCLKState( HwDeviceExtension , ModeNo , RefreshRateTableIndex, pVBInfo) ;
2370
2371 /* if(modeflag&HalfDCLK)//030305 fix lowresolution bug */
2372 /* if(XGINew_IF_DEF_NEW_LOWRES) */
2373 /* XGI_VesaLowResolution(ModeNo,ModeIdIndex);//030305 fix lowresolution bug */
2374
2375 data=XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) ;
2376
2377 if (HwDeviceExtension->jChipType == XG27 )
2378 {
2379 if ( data & 0x40 )
2380 data = 0x2c ;
2381 else
2382 data = 0x6c ;
2383 XGINew_SetReg1( pVBInfo->P3d4 , 0x52 , data ) ;
2384 XGINew_SetRegOR( pVBInfo->P3d4 , 0x51 , 0x10 ) ;
2385 }
2386 else
2387 if (HwDeviceExtension->jChipType >= XG20 )
2388 {
2389 if ( data & 0x40 )
2390 data = 0x33 ;
2391 else
2392 data = 0x73 ;
2393 XGINew_SetReg1( pVBInfo->P3d4 , 0x52 , data ) ;
2394 XGINew_SetReg1( pVBInfo->P3d4 , 0x51 , 0x02 ) ;
2395 }
2396 else
2397 {
2398 if ( data & 0x40 )
2399 data = 0x2c ;
2400 else
2401 data = 0x6c ;
2402 XGINew_SetReg1( pVBInfo->P3d4 , 0x52 , data ) ;
2403 }
2404
2405}
2406
2407
2408/* --------------------------------------------------------------------- */
2409/* Function : XGI_SetVCLKState */
2410/* Input : */
2411/* Output : */
2412/* Description : */
2413/* --------------------------------------------------------------------- */
2414void XGI_SetVCLKState( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo , USHORT RefreshRateTableIndex,PVB_DEVICE_INFO pVBInfo )
2415{
2416 USHORT data ,
2417 data2 = 0 ;
2418 SHORT VCLK ;
2419
2420 UCHAR index ;
2421
2422 if ( ModeNo <= 0x13 )
2423 VCLK = 0 ;
2424 else
2425 {
2426 index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
2427 index &= IndexMask ;
2428 VCLK = pVBInfo->VCLKData[ index ].CLOCK ;
2429 }
2430
2431 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x32 ) ;
2432 data &= 0xf3 ;
2433 if ( VCLK >= 200 )
2434 data |= 0x0c ; /* VCLK > 200 */
2435
2436 if ( HwDeviceExtension->jChipType >= XG20 )
2437 data &= ~0x04 ; /* 2 pixel mode */
2438
2439 XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , data ) ;
2440
2441 if ( HwDeviceExtension->jChipType < XG20 )
2442 {
2443 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1F ) ;
2444 data &= 0xE7 ;
2445 if ( VCLK < 200 )
2446 data |= 0x10 ;
2447 XGINew_SetReg1( pVBInfo->P3c4 , 0x1F , data ) ;
2448 }
2449
2450/* Jong for Adavantech LCD ripple issue
2451 if ( ( VCLK >= 0 ) && ( VCLK < 135 ) )
2452 data2 = 0x03 ;
2453 else if ( ( VCLK >= 135 ) && ( VCLK < 160 ) )
2454 data2 = 0x02 ;
2455 else if ( ( VCLK >= 160 ) && ( VCLK < 260 ) )
2456 data2 = 0x01 ;
2457 else if ( VCLK > 260 )
2458 data2 = 0x00 ;
2459*/
2460 data2 = 0x00 ;
2461
2462 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x07 , 0xFC , data2 ) ;
2463 if (HwDeviceExtension->jChipType >= XG27 )
2464 {
2465 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x40 , 0xFC , data2&0x03 ) ;
2466 }
2467
2468
2469}
2470
2471
2472/* --------------------------------------------------------------------- */
2473/* Function : XGI_VesaLowResolution */
2474/* Input : */
2475/* Output : */
2476/* Description : */
2477/* --------------------------------------------------------------------- */
2478/*void XGI_VesaLowResolution( USHORT ModeNo , USHORT ModeIdIndex ,PVB_DEVICE_INFO pVBInfo)
2479{
2480 USHORT modeflag;
2481
2482 if ( ModeNo > 0x13 )
2483 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
2484 else
2485 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
2486
2487 if ( ModeNo > 0x13 )
2488 {
2489 if ( modeflag & DoubleScanMode )
2490 {
2491 if ( modeflag & HalfDCLK )
2492 {
2493 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
2494 {
2495 if ( !( pVBInfo->VBInfo & SetCRT2ToRAMDAC ) )
2496 {
2497 if ( pVBInfo->VBInfo & SetInSlaveMode )
2498 {
2499 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xf7 , 0x00 ) ;
2500 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0f , 0x7f , 0x00 ) ;
2501 return ;
2502 }
2503 }
2504 }
2505 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0f , 0xff , 0x80 ) ;
2506 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xf7 , 0x00 ) ;
2507 return ;
2508 }
2509 }
2510 }
2511 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0f , 0x7f , 0x00 ) ;
2512}
2513*/
2514
2515/* --------------------------------------------------------------------- */
2516/* Function : XGI_LoadDAC */
2517/* Input : */
2518/* Output : */
2519/* Description : */
2520/* --------------------------------------------------------------------- */
2521void XGI_LoadDAC( USHORT ModeNo , USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo )
2522{
2523 USHORT data , data2 , time ,
2524 i , j , k , m , n , o ,
2525 si , di , bx , dl , al , ah , dh ,
2526 *table = NULL ;
2527
2528 if ( ModeNo <= 0x13 )
2529 data = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
2530 else
2531 data = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
2532
2533 data &= DACInfoFlag ;
2534 time = 64 ;
2535
2536 if ( data == 0x00 )
2537 table = XGINew_MDA_DAC ;
2538 else if ( data == 0x08 )
2539 table = XGINew_CGA_DAC ;
2540 else if ( data == 0x10 )
2541 table = XGINew_EGA_DAC ;
2542 else if ( data == 0x18 )
2543 {
2544 time = 256 ;
2545 table = XGINew_VGA_DAC ;
2546 }
2547
2548 if ( time == 256 )
2549 j = 16 ;
2550 else
2551 j = time ;
2552
2553 XGINew_SetReg3( pVBInfo->P3c6 , 0xFF ) ;
2554 XGINew_SetReg3( pVBInfo->P3c8 , 0x00 ) ;
2555
2556 for( i = 0 ; i < j ; i++ )
2557 {
2558 data = table[ i ] ;
2559
2560 for( k = 0 ; k < 3 ; k++ )
2561 {
2562 data2 = 0 ;
2563
2564 if ( data & 0x01 )
2565 data2 = 0x2A ;
2566
2567 if ( data & 0x02 )
2568 data2 += 0x15 ;
2569
2570 XGINew_SetReg3( pVBInfo->P3c9 , data2 ) ;
2571 data = data >> 2 ;
2572 }
2573 }
2574
2575 if ( time == 256 )
2576 {
2577 for( i = 16 ; i < 32 ; i++ )
2578 {
2579 data = table[ i ] ;
2580
2581 for( k = 0 ; k < 3 ; k++ )
2582 XGINew_SetReg3( pVBInfo->P3c9 , data ) ;
2583 }
2584
2585 si = 32 ;
2586
2587 for( m = 0 ; m < 9 ; m++ )
2588 {
2589 di = si ;
2590 bx = si + 0x04 ;
2591 dl = 0 ;
2592
2593 for( n = 0 ; n < 3 ; n++ )
2594 {
2595 for( o = 0 ; o < 5 ; o++ )
2596 {
2597 dh = table[ si ] ;
2598 ah = table[ di ] ;
2599 al = table[ bx ] ;
2600 si++ ;
2601 XGI_WriteDAC( dl , ah , al , dh, pVBInfo ) ;
2602 }
2603
2604 si -= 2 ;
2605
2606 for( o = 0 ; o < 3 ; o++ )
2607 {
2608 dh = table[ bx ] ;
2609 ah = table[ di ] ;
2610 al = table[ si ] ;
2611 si-- ;
2612 XGI_WriteDAC( dl , ah , al , dh, pVBInfo ) ;
2613 }
2614
2615 dl++ ;
2616 }
2617
2618 si += 5 ;
2619 }
2620 }
2621}
2622
2623
2624/* --------------------------------------------------------------------- */
2625/* Function : XGI_WriteDAC */
2626/* Input : */
2627/* Output : */
2628/* Description : */
2629/* --------------------------------------------------------------------- */
2630void XGI_WriteDAC( USHORT dl , USHORT ah , USHORT al , USHORT dh,PVB_DEVICE_INFO pVBInfo )
2631{
2632 USHORT temp , bh , bl ;
2633
2634 bh = ah ;
2635 bl = al ;
2636
2637 if ( dl != 0 )
2638 {
2639 temp = bh ;
2640 bh = dh ;
2641 dh = temp ;
2642 if ( dl == 1 )
2643 {
2644 temp = bl ;
2645 bl = dh ;
2646 dh = temp ;
2647 }
2648 else
2649 {
2650 temp = bl ;
2651 bl = bh ;
2652 bh = temp ;
2653 }
2654 }
2655 XGINew_SetReg3( pVBInfo->P3c9 , ( USHORT )dh ) ;
2656 XGINew_SetReg3( pVBInfo->P3c9 , ( USHORT )bh ) ;
2657 XGINew_SetReg3( pVBInfo->P3c9 , ( USHORT )bl ) ;
2658}
2659
2660#if 0
2661/* --------------------------------------------------------------------- */
2662/* Function : XGI_ClearBuffer */
2663/* Input : */
2664/* Output : */
2665/* Description : */
2666/* --------------------------------------------------------------------- */
2667void XGI_ClearBuffer( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo, PVB_DEVICE_INFO pVBInfo)
2668{
2669 PVOID VideoMemoryAddress = ( PVOID )HwDeviceExtension->pjVideoMemoryAddress ;
2670 ULONG AdapterMemorySize = ( ULONG )HwDeviceExtension->ulVideoMemorySize ;
2671 PUSHORT pBuffer ;
2672#ifndef LINUX_XF86
2673 int i ;
2674#endif
2675
2676 if ( pVBInfo->ModeType >= ModeEGA )
2677 {
2678 if ( ModeNo > 0x13 )
2679 {
2680 AdapterMemorySize = 0x40000 ; /* clear 256k */
2681 /* GetDRAMSize( HwDeviceExtension ) ; */
2682 XGI_SetMemory( VideoMemoryAddress , AdapterMemorySize , 0 ) ;
2683 }
2684 else
2685 {
2686/*
2687 pBuffer = VideoMemoryAddress ;
2688 for( i = 0 ; i < 0x4000 ; i++ )
2689 pBuffer[ i ] = 0x0000 ;
2690*/
2691 }
2692 }
2693 else
2694 {
2695 pBuffer = VideoMemoryAddress ;
2696 if ( pVBInfo->ModeType < ModeCGA )
2697 {
2698/*
2699 for ( i = 0 ; i < 0x4000 ; i++ )
2700 pBuffer[ i ] = 0x0720 ;
2701*/
2702 }
2703 else
2704 XGI_SetMemory( VideoMemoryAddress , 0x8000 , 0 ) ;
2705 }
2706}
2707
2708#endif
2709/* --------------------------------------------------------------------- */
2710/* Function : XGI_SetLCDAGroup */
2711/* Input : */
2712/* Output : */
2713/* Description : */
2714/* --------------------------------------------------------------------- */
2715void XGI_SetLCDAGroup( USHORT ModeNo , USHORT ModeIdIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
2716{
2717 USHORT RefreshRateTableIndex ;
2718 /* USHORT temp ; */
2719
2720 /* pVBInfo->SelectCRT2Rate = 0 ; */
2721
2722 pVBInfo->SetFlag |= ProgrammingCRT2 ;
2723 RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, pVBInfo ) ;
2724 XGI_GetLVDSResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
2725 XGI_GetLVDSData( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo);
2726 XGI_ModCRT1Regs( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
2727 XGI_SetLVDSRegs( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2728 XGI_SetCRT2ECLK( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2729}
2730
2731
2732/* --------------------------------------------------------------------- */
2733/* Function : XGI_GetLVDSResInfo */
2734/* Input : */
2735/* Output : */
2736/* Description : */
2737/* --------------------------------------------------------------------- */
2738void XGI_GetLVDSResInfo( USHORT ModeNo , USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo )
2739{
2740 USHORT resindex , xres , yres , modeflag ;
2741
2742 if ( ModeNo <= 0x13 )
2743 {
2744 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ; /* si+St_ResInfo */
2745 }
2746 else
2747 {
2748 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo */
2749 }
2750
2751
2752 /* if ( ModeNo > 0x13 ) */
2753 /* modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; */
2754 /* else */
2755 /* modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; */
2756
2757 if ( ModeNo <= 0x13 )
2758 {
2759 resindex = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ; /* si+St_ResInfo */
2760 }
2761 else
2762 {
2763 resindex = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo */
2764 }
2765
2766 /* resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ; */
2767
2768 if ( ModeNo <= 0x13 )
2769 {
2770 xres = pVBInfo->StResInfo[ resindex ].HTotal ;
2771 yres = pVBInfo->StResInfo[ resindex ].VTotal ;
2772 }
2773 else
2774 {
2775 xres = pVBInfo->ModeResInfo[ resindex ].HTotal ;
2776 yres = pVBInfo->ModeResInfo[ resindex ].VTotal ;
2777 }
2778 if ( ModeNo > 0x13 )
2779 {
2780 if ( modeflag & HalfDCLK )
2781 xres = xres << 1 ;
2782
2783 if ( modeflag & DoubleScanMode )
2784 yres = yres << 1 ;
2785 }
2786 /* if ( modeflag & Charx8Dot ) */
2787 /* { */
2788
2789 if ( xres == 720 )
2790 xres = 640 ;
2791
2792 /* } */
2793 pVBInfo->VGAHDE = xres ;
2794 pVBInfo->HDE = xres ;
2795 pVBInfo->VGAVDE = yres ;
2796 pVBInfo->VDE = yres ;
2797}
2798
2799
2800/* --------------------------------------------------------------------- */
2801/* Function : XGI_GetLVDSData */
2802/* Input : */
2803/* Output : */
2804/* Description : */
2805/* --------------------------------------------------------------------- */
2806void XGI_GetLVDSData( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
2807{
2808 USHORT tempbx ;
2809 XGI330_LVDSDataStruct *LCDPtr = NULL ;
2810 XGI330_CHTVDataStruct *TVPtr = NULL ;
2811
2812 tempbx = 2 ;
2813
2814 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
2815 {
2816 LCDPtr = ( XGI330_LVDSDataStruct * )XGI_GetLcdPtr( tempbx, ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo) ;
2817 pVBInfo->VGAHT = LCDPtr->VGAHT ;
2818 pVBInfo->VGAVT = LCDPtr->VGAVT ;
2819 pVBInfo->HT = LCDPtr->LCDHT ;
2820 pVBInfo->VT = LCDPtr->LCDVT ;
2821 }
2822 if ( pVBInfo->IF_DEF_CH7017 == 1 )
2823 {
2824 if ( pVBInfo->VBInfo & SetCRT2ToTV )
2825 {
2826 TVPtr = ( XGI330_CHTVDataStruct * )XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2827 pVBInfo->VGAHT = TVPtr->VGAHT ;
2828 pVBInfo->VGAVT = TVPtr->VGAVT ;
2829 pVBInfo->HT = TVPtr->LCDHT ;
2830 pVBInfo->VT = TVPtr->LCDVT ;
2831 }
2832 }
2833
2834 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
2835 {
2836 if ( !( pVBInfo->LCDInfo & ( SetLCDtoNonExpanding | EnableScalingLCD ) ) )
2837 {
2838 if ( ( pVBInfo->LCDResInfo == Panel1024x768 ) || ( pVBInfo->LCDResInfo == Panel1024x768x75 ) )
2839 {
2840 pVBInfo->HDE = 1024 ;
2841 pVBInfo->VDE = 768 ;
2842 }
2843 else if ( ( pVBInfo->LCDResInfo == Panel1280x1024 ) || ( pVBInfo->LCDResInfo == Panel1280x1024x75 ) )
2844 {
2845 pVBInfo->HDE = 1280 ;
2846 pVBInfo->VDE = 1024 ;
2847 }
2848 else if ( pVBInfo->LCDResInfo == Panel1400x1050 )
2849 {
2850 pVBInfo->HDE = 1400 ;
2851 pVBInfo->VDE = 1050 ;
2852 }
2853 else
2854 {
2855 pVBInfo->HDE = 1600 ;
2856 pVBInfo->VDE = 1200 ;
2857 }
2858 }
2859 }
2860}
2861
2862
2863/* --------------------------------------------------------------------- */
2864/* Function : XGI_ModCRT1Regs */
2865/* Input : */
2866/* Output : */
2867/* Description : */
2868/* --------------------------------------------------------------------- */
2869void XGI_ModCRT1Regs( USHORT ModeNo , USHORT ModeIdIndex ,
2870 USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo )
2871{
2872 UCHAR index ;
2873 USHORT tempbx , i ;
2874 XGI_LVDSCRT1HDataStruct *LCDPtr = NULL ;
2875 XGI_LVDSCRT1VDataStruct *LCDPtr1 =NULL ;
2876 /* XGI330_CHTVDataStruct *TVPtr = NULL ; */
2877 XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL;
2878 XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL;
2879
2880 if( ModeNo <= 0x13 )
2881 index = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
2882 else
2883 index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2884
2885 index= index & IndexMask ;
2886
2887 if ( ( pVBInfo->IF_DEF_ScaleLCD == 0 ) || ( ( pVBInfo->IF_DEF_ScaleLCD == 1 ) && ( !( pVBInfo->LCDInfo & EnableScalingLCD ) ) ) )
2888 {
2889 tempbx = 0 ;
2890
2891 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
2892 {
2893 LCDPtr = ( XGI_LVDSCRT1HDataStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2894
2895 for( i = 0 ; i < 8 ; i++ )
2896 pVBInfo->TimingH[ 0 ].data[ i ] = LCDPtr[ 0 ].Reg[ i ] ;
2897 }
2898
2899 if ( pVBInfo->IF_DEF_CH7007 == 1 )
2900 {
2901 if ( pVBInfo->VBInfo & SetCRT2ToTV )
2902 {
2903 CH7007TV_TimingHPtr = ( XGI_CH7007TV_TimingHStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2904
2905 for( i = 0 ; i < 8 ; i++ )
2906 pVBInfo->TimingH[ 0 ].data[ i ] = CH7007TV_TimingHPtr[ 0 ].data[ i ] ;
2907 }
2908 }
2909
2910 /* if ( pVBInfo->IF_DEF_CH7017 == 1 )
2911 {
2912 if ( pVBInfo->VBInfo & SetCRT2ToTV )
2913 TVPtr = ( XGI330_CHTVDataStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2914 } */
2915
2916 XGI_SetCRT1Timing_H(pVBInfo,HwDeviceExtension) ;
2917
2918 if ( pVBInfo->IF_DEF_CH7007 == 1 )
2919 {
2920 XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , CH7007TV_TimingHPtr[ 0 ].data[ 8 ] ) ;
2921 XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , CH7007TV_TimingHPtr[ 0 ].data[ 9 ] ) ;
2922 }
2923
2924 tempbx = 1 ;
2925
2926 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
2927 {
2928 LCDPtr1 = ( XGI_LVDSCRT1VDataStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2929 for( i = 0 ; i < 7 ; i++ )
2930 pVBInfo->TimingV[ 0 ].data[ i ] = LCDPtr1[ 0 ].Reg[ i ] ;
2931 }
2932
2933 if ( pVBInfo->IF_DEF_CH7007 == 1 )
2934 {
2935 if ( pVBInfo->VBInfo & SetCRT2ToTV )
2936 {
2937 CH7007TV_TimingVPtr = ( XGI_CH7007TV_TimingVStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2938
2939 for( i = 0 ; i < 7 ; i++ )
2940 pVBInfo->TimingV[ 0 ].data[ i ] = CH7007TV_TimingVPtr[ 0 ].data[ i ] ;
2941 }
2942 }
2943 /* if ( pVBInfo->IF_DEF_CH7017 == 1 )
2944 {
2945 if ( pVBInfo->VBInfo & SetCRT2ToTV )
2946 TVPtr = ( XGI330_CHTVDataStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2947 } */
2948
2949 XGI_SetCRT1Timing_V( ModeIdIndex , ModeNo , pVBInfo) ;
2950
2951 if ( pVBInfo->IF_DEF_CH7007 == 1 )
2952 {
2953 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x33 , ~0x01 , CH7007TV_TimingVPtr[ 0 ].data[ 7 ]&0x01 ) ;
2954 XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , CH7007TV_TimingVPtr[ 0 ].data[8 ] ) ;
2955 XGINew_SetReg1( pVBInfo->P3c4 , 0x3F , CH7007TV_TimingVPtr[ 0 ].data[9 ] ) ;
2956
2957 }
2958 }
2959}
2960
2961
2962
2963/* --------------------------------------------------------------------- */
2964/* Function : XGI_SetLVDSRegs */
2965/* Input : */
2966/* Output : */
2967/* Description : */
2968/* --------------------------------------------------------------------- */
2969void XGI_SetLVDSRegs( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
2970{
2971 USHORT tempbx , tempax , tempcx , tempdx , push1 , push2 , modeflag ;
2972 unsigned long temp , temp1 , temp2 , temp3 , push3 ;
2973 XGI330_LCDDataDesStruct *LCDPtr = NULL ;
2974 XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL ;
2975
2976 if ( ModeNo > 0x13 )
2977 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
2978 else
2979 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
2980
2981 if ( !( pVBInfo->SetFlag & Win9xDOSMode ) )
2982 {
2983 if ( ( pVBInfo->IF_DEF_CH7017 == 0 ) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) )
2984 {
2985 if ( pVBInfo->IF_DEF_OEMUtil == 1 )
2986 {
2987 tempbx = 8 ;
2988 LCDPtr = ( XGI330_LCDDataDesStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2989 }
2990
2991 if ( ( pVBInfo->IF_DEF_OEMUtil == 0 ) || ( LCDPtr == 0 ) )
2992 {
2993 tempbx = 3 ;
2994 if ( pVBInfo->LCDInfo & EnableScalingLCD )
2995 LCDPtr1 = ( XGI330_LCDDataDesStruct2 * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2996 else
2997 LCDPtr = ( XGI330_LCDDataDesStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
2998 }
2999
3000 XGI_GetLCDSync( &tempax , &tempbx ,pVBInfo) ;
3001 push1 = tempbx ;
3002 push2 = tempax ;
3003
3004 /* GetLCDResInfo */
3005 if ( ( pVBInfo->LCDResInfo == Panel1024x768 ) || ( pVBInfo->LCDResInfo == Panel1024x768x75 ) )
3006 {
3007 tempax = 1024 ;
3008 tempbx = 768 ;
3009 }
3010 else if ( ( pVBInfo->LCDResInfo == Panel1280x1024 ) || ( pVBInfo->LCDResInfo == Panel1280x1024x75 ) )
3011 {
3012 tempax = 1280 ;
3013 tempbx = 1024 ;
3014 }
3015 else if ( pVBInfo->LCDResInfo == Panel1400x1050 )
3016 {
3017 tempax = 1400 ;
3018 tempbx = 1050 ;
3019 }
3020 else
3021 {
3022 tempax = 1600 ;
3023 tempbx = 1200 ;
3024 }
3025
3026 if ( pVBInfo->LCDInfo & SetLCDtoNonExpanding )
3027 {
3028 pVBInfo->HDE=tempax;
3029 pVBInfo->VDE=tempbx;
3030 pVBInfo->VGAHDE=tempax;
3031 pVBInfo->VGAVDE=tempbx;
3032 }
3033
3034 if ( ( pVBInfo->IF_DEF_ScaleLCD == 1 ) && ( pVBInfo->LCDInfo & EnableScalingLCD ) )
3035 {
3036 tempax=pVBInfo->HDE;
3037 tempbx=pVBInfo->VDE;
3038 }
3039
3040 tempax = pVBInfo->HT ;
3041
3042 if ( pVBInfo->LCDInfo & EnableScalingLCD )
3043 tempbx = LCDPtr1->LCDHDES ;
3044 else
3045 tempbx = LCDPtr->LCDHDES ;
3046
3047 tempcx = pVBInfo->HDE ;
3048 tempbx = tempbx & 0x0fff ;
3049 tempcx += tempbx ;
3050
3051 if ( tempcx >= tempax )
3052 tempcx -= tempax ;
3053
3054 XGINew_SetReg1( pVBInfo->Part1Port , 0x1A , tempbx & 0x07 ) ;
3055
3056 tempcx = tempcx >> 3 ;
3057 tempbx = tempbx >> 3 ;
3058
3059 XGINew_SetReg1( pVBInfo->Part1Port , 0x16 , ( USHORT )( tempbx & 0xff ) ) ;
3060 XGINew_SetReg1( pVBInfo->Part1Port , 0x17 , ( USHORT )( tempcx & 0xff ) ) ;
3061
3062 tempax = pVBInfo->HT ;
3063
3064 if ( pVBInfo->LCDInfo & EnableScalingLCD )
3065 tempbx = LCDPtr1->LCDHRS ;
3066 else
3067 tempbx = LCDPtr->LCDHRS ;
3068
3069 tempcx = push2 ;
3070
3071 if ( pVBInfo->LCDInfo & EnableScalingLCD )
3072 tempcx = LCDPtr1->LCDHSync ;
3073
3074 tempcx += tempbx ;
3075
3076 if ( tempcx >= tempax )
3077 tempcx -= tempax ;
3078
3079 tempax = tempbx & 0x07 ;
3080 tempax = tempax >> 5 ;
3081 tempcx = tempcx >> 3 ;
3082 tempbx = tempbx >> 3 ;
3083
3084 tempcx &= 0x1f ;
3085 tempax |= tempcx ;
3086
3087 XGINew_SetReg1( pVBInfo->Part1Port , 0x15 , tempax ) ;
3088 XGINew_SetReg1( pVBInfo->Part1Port , 0x14 , ( USHORT )( tempbx & 0xff ) ) ;
3089
3090 tempax = pVBInfo->VT ;
3091 if ( pVBInfo->LCDInfo & EnableScalingLCD )
3092 tempbx = LCDPtr1->LCDVDES ;
3093 else
3094 tempbx = LCDPtr->LCDVDES ;
3095 tempcx = pVBInfo->VDE ;
3096
3097 tempbx = tempbx & 0x0fff ;
3098 tempcx += tempbx ;
3099 if ( tempcx >= tempax )
3100 tempcx -= tempax ;
3101
3102 XGINew_SetReg1( pVBInfo->Part1Port , 0x1b , ( USHORT )( tempbx & 0xff ) ) ;
3103 XGINew_SetReg1( pVBInfo->Part1Port , 0x1c , ( USHORT )( tempcx & 0xff ) ) ;
3104
3105 tempbx = ( tempbx >> 8 ) & 0x07 ;
3106 tempcx = ( tempcx >> 8 ) & 0x07 ;
3107
3108 XGINew_SetReg1( pVBInfo->Part1Port , 0x1d , ( USHORT )( ( tempcx << 3 ) | tempbx ) ) ;
3109
3110 tempax = pVBInfo->VT ;
3111 if ( pVBInfo->LCDInfo & EnableScalingLCD )
3112 tempbx = LCDPtr1->LCDVRS ;
3113 else
3114 tempbx = LCDPtr->LCDVRS ;
3115
3116 /* tempbx = tempbx >> 4 ; */
3117 tempcx = push1 ;
3118
3119 if ( pVBInfo->LCDInfo & EnableScalingLCD )
3120 tempcx = LCDPtr1->LCDVSync ;
3121
3122 tempcx += tempbx ;
3123 if ( tempcx >= tempax )
3124 tempcx -= tempax ;
3125
3126 XGINew_SetReg1( pVBInfo->Part1Port , 0x18 , ( USHORT )( tempbx & 0xff ) ) ;
3127 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x19 , ~0x0f , ( USHORT )( tempcx & 0x0f ) ) ;
3128
3129 tempax = ( ( tempbx >> 8 ) & 0x07 ) << 3 ;
3130
3131 tempbx = pVBInfo->VGAVDE ;
3132 if ( tempbx != pVBInfo->VDE )
3133 tempax |= 0x40 ;
3134
3135 if ( pVBInfo->LCDInfo & EnableLVDSDDA )
3136 tempax |= 0x40 ;
3137
3138 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x1a , 0x07 , tempax ) ;
3139
3140 tempcx = pVBInfo->VGAVT ;
3141 tempbx = pVBInfo->VDE ;
3142 tempax = pVBInfo->VGAVDE ;
3143 tempcx -= tempax ;
3144
3145 temp = tempax ; /* 0430 ylshieh */
3146 temp1 = ( temp << 18 ) / tempbx ;
3147
3148 tempdx = ( USHORT )( ( temp << 18 ) % tempbx ) ;
3149
3150 if ( tempdx != 0 )
3151 temp1 += 1 ;
3152
3153 temp2 = temp1 ;
3154 push3 = temp2 ;
3155
3156 XGINew_SetReg1( pVBInfo->Part1Port , 0x37 , ( USHORT )( temp2 & 0xff ) ) ;
3157 XGINew_SetReg1( pVBInfo->Part1Port , 0x36 , ( USHORT )( ( temp2 >> 8 ) & 0xff ) ) ;
3158
3159 tempbx = ( USHORT )( temp2 >> 16 ) ;
3160 tempax = tempbx & 0x03 ;
3161
3162 tempbx = pVBInfo->VGAVDE ;
3163 if ( tempbx == pVBInfo->VDE )
3164 tempax |= 0x04 ;
3165
3166 XGINew_SetReg1( pVBInfo->Part1Port , 0x35 , tempax ) ;
3167
3168 if ( pVBInfo->VBType & VB_XGI301C )
3169 {
3170 temp2 = push3 ;
3171 XGINew_SetReg1( pVBInfo->Part4Port , 0x3c , ( USHORT )( temp2 & 0xff ) ) ;
3172 XGINew_SetReg1( pVBInfo->Part4Port , 0x3b , ( USHORT )( ( temp2 >> 8 ) & 0xff ) ) ;
3173 tempbx = ( USHORT )( temp2 >> 16 ) ;
3174 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x3a , ~0xc0 , ( USHORT )( ( tempbx & 0xff ) << 6 ) ) ;
3175
3176 tempcx = pVBInfo->VGAVDE ;
3177 if ( tempcx == pVBInfo->VDE )
3178 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x30 , ~0x0c , 0x00 ) ;
3179 else
3180 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x30 , ~0x0c , 0x08 ) ;
3181 }
3182
3183 tempcx = pVBInfo->VGAHDE ;
3184 tempbx = pVBInfo->HDE ;
3185
3186 temp1 = tempcx << 16 ;
3187
3188 tempax = ( USHORT )( temp1 / tempbx ) ;
3189
3190 if ( ( tempbx & 0xffff ) == ( tempcx & 0xffff ) )
3191 tempax = 65535 ;
3192
3193 temp3 = tempax ;
3194 temp1 = pVBInfo->VGAHDE << 16 ;
3195
3196 temp1 /= temp3 ;
3197 temp3 = temp3 << 16 ;
3198 temp1 -= 1 ;
3199
3200 temp3 = ( temp3 & 0xffff0000 ) + ( temp1 & 0xffff ) ;
3201
3202 tempax = ( USHORT )( temp3 & 0xff ) ;
3203 XGINew_SetReg1( pVBInfo->Part1Port , 0x1f , tempax ) ;
3204
3205 temp1 = pVBInfo->VGAVDE << 18 ;
3206 temp1 = temp1 / push3 ;
3207 tempbx = ( USHORT )( temp1 & 0xffff ) ;
3208
3209 if ( pVBInfo->LCDResInfo == Panel1024x768 )
3210 tempbx -= 1 ;
3211
3212 tempax = ( ( tempbx >> 8 ) & 0xff ) << 3 ;
3213 tempax |= ( USHORT )( ( temp3 >> 8 ) & 0x07 ) ;
3214 XGINew_SetReg1( pVBInfo->Part1Port , 0x20 , ( USHORT )( tempax & 0xff ) ) ;
3215 XGINew_SetReg1( pVBInfo->Part1Port , 0x21 , ( USHORT )( tempbx & 0xff ) ) ;
3216
3217 temp3 = temp3 >> 16 ;
3218
3219 if ( modeflag & HalfDCLK )
3220 temp3 = temp3 >> 1 ;
3221
3222 XGINew_SetReg1(pVBInfo->Part1Port , 0x22 , ( USHORT )( ( temp3 >> 8 ) & 0xff ) ) ;
3223 XGINew_SetReg1(pVBInfo->Part1Port , 0x23 , ( USHORT )( temp3 & 0xff ) ) ;
3224 }
3225 }
3226}
3227
3228
3229/* --------------------------------------------------------------------- */
3230/* Function : XGI_SetCRT2ECLK */
3231/* Input : */
3232/* Output : */
3233/* Description : */
3234/* --------------------------------------------------------------------- */
3235void XGI_SetCRT2ECLK( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
3236{
3237 UCHAR di_0 , di_1 , tempal ;
3238 int i ;
3239
3240 tempal = XGI_GetVCLKPtr( RefreshRateTableIndex , ModeNo , ModeIdIndex, pVBInfo ) ;
3241 XGI_GetVCLKLen( tempal , &di_0 , &di_1, pVBInfo ) ;
3242 XGI_GetLCDVCLKPtr( &di_0 , &di_1, pVBInfo ) ;
3243
3244 for( i = 0 ; i < 4 ; i++ )
3245 {
3246 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x31 , ~0x30 , ( USHORT )( 0x10 * i ) ) ;
3247 if ( pVBInfo->IF_DEF_CH7007 == 1 )
3248 {
3249 XGINew_SetReg1( pVBInfo->P3c4 , 0x2b , di_0 ) ;
3250 XGINew_SetReg1( pVBInfo->P3c4 , 0x2c , di_1 ) ;
3251 }
3252 else if ( ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) && ( !( pVBInfo->VBInfo & SetInSlaveMode ) ) )
3253 {
3254 XGINew_SetReg1( pVBInfo->P3c4 , 0x2e , di_0 ) ;
3255 XGINew_SetReg1( pVBInfo->P3c4 , 0x2f , di_1 ) ;
3256 }
3257 else
3258 {
3259 XGINew_SetReg1( pVBInfo->P3c4 , 0x2b , di_0 ) ;
3260 XGINew_SetReg1( pVBInfo->P3c4 , 0x2c , di_1 ) ;
3261 }
3262 }
3263}
3264
3265
3266/* --------------------------------------------------------------------- */
3267/* Function : XGI_UpdateModeInfo */
3268/* Input : */
3269/* Output : */
3270/* Description : */
3271/* --------------------------------------------------------------------- */
3272void XGI_UpdateModeInfo( PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo )
3273{
3274 USHORT tempcl ,
3275 tempch ,
3276 temp ,
3277 tempbl ,
3278 tempax ;
3279
3280 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
3281 {
3282 tempcl = 0 ;
3283 tempch = 0 ;
3284 temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x01 ) ;
3285
3286 if ( !( temp & 0x20 ) )
3287 {
3288 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x17 ) ;
3289 if ( temp & 0x80 )
3290 {
3291 if ( ( HwDeviceExtension->jChipType >= XG20 ) || ( HwDeviceExtension->jChipType >= XG40 ) )
3292 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x53 ) ;
3293 else
3294 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x63 ) ;
3295
3296 if ( !( temp & 0x40 ) )
3297 tempcl |= ActiveCRT1 ;
3298 }
3299 }
3300
3301 temp = XGINew_GetReg1( pVBInfo->Part1Port , 0x2e ) ;
3302 temp &= 0x0f ;
3303
3304 if ( !( temp == 0x08 ) )
3305 {
3306 tempax = XGINew_GetReg1( pVBInfo->Part1Port , 0x13 ) ; /* Check ChannelA by Part1_13 [2003/10/03] */
3307 if ( tempax & 0x04 )
3308 tempcl = tempcl | ActiveLCD ;
3309
3310 temp &= 0x05 ;
3311
3312 if ( !( tempcl & ActiveLCD ) )
3313 if ( temp == 0x01 )
3314 tempcl |= ActiveCRT2 ;
3315
3316 if ( temp == 0x04 )
3317 tempcl |= ActiveLCD ;
3318
3319 if ( temp == 0x05 )
3320 {
3321 temp = XGINew_GetReg1( pVBInfo->Part2Port , 0x00 ) ;
3322
3323 if( !( temp & 0x08 ) )
3324 tempch |= ActiveAVideo ;
3325
3326 if ( !( temp & 0x04 ) )
3327 tempch |= ActiveSVideo ;
3328
3329 if ( temp & 0x02 )
3330 tempch |= ActiveSCART ;
3331
3332 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
3333 {
3334 if ( temp & 0x01 )
3335 tempch |= ActiveHiTV ;
3336 }
3337
3338 if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
3339 {
3340 temp = XGINew_GetReg1( pVBInfo->Part2Port , 0x4d ) ;
3341
3342 if ( temp & 0x10 )
3343 tempch |= ActiveYPbPr ;
3344 }
3345
3346 if ( tempch != 0 )
3347 tempcl |= ActiveTV ;
3348 }
3349 }
3350
3351 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x3d ) ;
3352 if ( tempcl & ActiveLCD )
3353 {
3354 if ( ( pVBInfo->SetFlag & ReserveTVOption ) )
3355 {
3356 if ( temp & ActiveTV )
3357 tempcl |= ActiveTV ;
3358 }
3359 }
3360 temp = tempcl ;
3361 tempbl = ~ModeSwitchStatus ;
3362 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x3d , tempbl , temp ) ;
3363
3364 if ( !( pVBInfo->SetFlag & ReserveTVOption ) )
3365 XGINew_SetReg1( pVBInfo->P3d4 , 0x3e , tempch ) ;
3366 }
3367 else
3368 {
3369 return ;
3370 }
3371}
3372
3373
3374/* --------------------------------------------------------------------- */
3375/* Function : XGI_GetVGAType */
3376/* Input : */
3377/* Output : */
3378/* Description : */
3379/* --------------------------------------------------------------------- */
3380void XGI_GetVGAType( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
3381{
3382 /*
3383 if ( HwDeviceExtension->jChipType >= XG20 )
3384 {
3385 pVBInfo->Set_VGAType = XG20;
3386 }
3387 else if ( HwDeviceExtension->jChipType >= XG40 )
3388 {
3389 pVBInfo->Set_VGAType = VGA_XGI340 ;
3390 }
3391 */
3392 pVBInfo->Set_VGAType = HwDeviceExtension->jChipType;
3393}
3394
3395
3396/* --------------------------------------------------------------------- */
3397/* Function : XGI_GetVBType */
3398/* Input : */
3399/* Output : */
3400/* Description : */
3401/* --------------------------------------------------------------------- */
3402void XGI_GetVBType(PVB_DEVICE_INFO pVBInfo)
3403{
3404 USHORT flag , tempbx , tempah ;
3405
3406 if ( pVBInfo->IF_DEF_CH7007 == 1 )
3407 {
3408 pVBInfo->VBType = VB_CH7007 ;
3409 return;
3410 }
3411 if ( pVBInfo->IF_DEF_LVDS == 0 )
3412 {
3413 tempbx = VB_XGI302B ;
3414 flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x00 ) ;
3415 if ( flag != 0x02 )
3416 {
3417 tempbx = VB_XGI301 ;
3418 flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) ;
3419 if ( flag >= 0xB0 )
3420 {
3421 tempbx = VB_XGI301B ;
3422 if ( flag >= 0xC0 )
3423 {
3424 tempbx = VB_XGI301C ;
3425 if ( flag >= 0xD0 )
3426 {
3427 tempbx = VB_XGI301LV ;
3428 if ( flag >= 0xE0 )
3429 {
3430 tempbx = VB_XGI302LV ;
3431 tempah = XGINew_GetReg1( pVBInfo->Part4Port , 0x39 ) ;
3432 if ( tempah != 0xFF )
3433 tempbx = VB_XGI301C ;
3434 }
3435 }
3436 }
3437
3438 if ( tempbx & ( VB_XGI301B | VB_XGI302B ) )
3439 {
3440 flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x23 ) ;
3441
3442 if ( !( flag & 0x02 ) )
3443 tempbx = tempbx | VB_NoLCD ;
3444 }
3445 }
3446 }
3447 pVBInfo->VBType = tempbx ;
3448 }
3449/*
3450 else if ( pVBInfo->IF_DEF_CH7017 == 1 )
3451 pVBInfo->VBType = VB_CH7017 ;
3452 else //LVDS
3453 pVBInfo->VBType = VB_LVDS_NS ;
3454*/
3455
3456}
3457
3458
3459/* --------------------------------------------------------------------- */
3460/* Function : XGI_GetVBInfo */
3461/* Input : */
3462/* Output : */
3463/* Description : */
3464/* --------------------------------------------------------------------- */
3465void XGI_GetVBInfo( USHORT ModeNo , USHORT ModeIdIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
3466{
3467 USHORT tempax ,
3468 push ,
3469 tempbx ,
3470 temp ,
3471 modeflag ;
3472
3473 if ( ModeNo <= 0x13 )
3474 {
3475 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
3476 }
3477 else
3478 {
3479 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
3480 }
3481
3482 pVBInfo->SetFlag = 0 ;
3483 pVBInfo->ModeType = modeflag & ModeInfoFlag ;
3484 tempbx = 0 ;
3485
3486 if ( pVBInfo->VBType & 0xFFFF )
3487 {
3488 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x30 ) ; /* Check Display Device */
3489 tempbx = tempbx | temp ;
3490 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) ;
3491 push = temp ;
3492 push = push << 8 ;
3493 tempax = temp << 8 ;
3494 tempbx = tempbx | tempax ;
3495 temp = ( SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA | SetInSlaveMode | DisableCRT2Display ) ;
3496 temp = 0xFFFF ^ temp ;
3497 tempbx &= temp ;
3498
3499 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
3500
3501 if ( pVBInfo->IF_DEF_LCDA == 1 )
3502 {
3503
3504 if ( ( pVBInfo->Set_VGAType >= XG20 ) || ( pVBInfo->Set_VGAType >= XG40 ))
3505 {
3506 if ( pVBInfo->IF_DEF_LVDS == 0 )
3507 {
3508 /* if ( ( pVBInfo->VBType & VB_XGI302B ) || ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) */
3509 if ( pVBInfo->VBType & ( VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
3510 {
3511 if ( temp & EnableDualEdge )
3512 {
3513 tempbx |= SetCRT2ToDualEdge ;
3514
3515 if ( temp & SetToLCDA )
3516 tempbx |= SetCRT2ToLCDA ;
3517 }
3518 }
3519 }
3520 else if ( pVBInfo->IF_DEF_CH7017 == 1 )
3521 {
3522 if ( pVBInfo->VBType & VB_CH7017 )
3523 {
3524 if ( temp & EnableDualEdge )
3525 {
3526 tempbx |= SetCRT2ToDualEdge ;
3527
3528 if ( temp & SetToLCDA )
3529 tempbx |= SetCRT2ToLCDA ;
3530 }
3531 }
3532 }
3533 }
3534 }
3535
3536 if ( pVBInfo->IF_DEF_YPbPr == 1 )
3537 {
3538 if ( ( ( pVBInfo->IF_DEF_LVDS == 0 ) && ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) )
3539 || ( ( pVBInfo->IF_DEF_CH7017 == 1 ) && ( pVBInfo->VBType&VB_CH7017 ) ) || ( (pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType&VB_CH7007) ) ) /* [Billy] 07/05/04 */
3540 {
3541 if ( temp & SetYPbPr ) /* temp = CR38 */
3542 {
3543 if ( pVBInfo->IF_DEF_HiVision == 1 )
3544 {
3545 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ; /* shampoo add for new scratch */
3546 temp &= YPbPrMode ;
3547 tempbx |= SetCRT2ToHiVisionTV ;
3548
3549 if ( temp != YPbPrMode1080i ) {
3550 tempbx &= ( ~SetCRT2ToHiVisionTV ) ;
3551 tempbx |= SetCRT2ToYPbPr ; }
3552 }
3553
3554 /* tempbx |= SetCRT2ToYPbPr ; */
3555 }
3556 }
3557 }
3558
3559 tempax = push ; /* restore CR31 */
3560
3561 if ( pVBInfo->IF_DEF_LVDS == 0 )
3562 {
3563 if ( pVBInfo->IF_DEF_YPbPr == 1 )
3564 {
3565 if ( pVBInfo->IF_DEF_HiVision == 1 )
3566 temp = 0x09FC ;
3567 else
3568 temp = 0x097C ;
3569 }
3570 else
3571 {
3572 if ( pVBInfo->IF_DEF_HiVision == 1 )
3573 temp = 0x01FC ;
3574 else
3575 temp = 0x017C ;
3576 }
3577 }
3578 else /* 3nd party chip */
3579 {
3580 if ( pVBInfo->IF_DEF_CH7017 == 1 )
3581 temp = ( SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) ;
3582 else if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 07/05/03 */
3583 {
3584 temp = SetCRT2ToTV ;
3585 }
3586 else
3587 temp = SetCRT2ToLCD ;
3588 }
3589
3590 if ( !( tempbx & temp ) )
3591 {
3592 tempax |= DisableCRT2Display ;
3593 tempbx = 0 ;
3594 }
3595
3596 if ( pVBInfo->IF_DEF_LCDA == 1 ) /* Select Display Device */
3597 {
3598 if ( !( pVBInfo->VBType & VB_NoLCD ) )
3599 {
3600 if ( tempbx & SetCRT2ToLCDA )
3601 {
3602 if ( tempbx & SetSimuScanMode )
3603 tempbx &= ( ~( SetCRT2ToLCD | SetCRT2ToRAMDAC | SwitchToCRT2 ) ) ;
3604 else
3605 tempbx &= ( ~( SetCRT2ToLCD | SetCRT2ToRAMDAC | SetCRT2ToTV | SwitchToCRT2 ) ) ;
3606 }
3607 }
3608 }
3609
3610 /* shampoo add */
3611 if ( !( tempbx & ( SwitchToCRT2 | SetSimuScanMode ) ) ) /* for driver abnormal */
3612 {
3613 if ( pVBInfo->IF_DEF_CRT2Monitor == 1 )
3614 {
3615 if ( tempbx & SetCRT2ToRAMDAC )
3616 {
3617 tempbx &= ( 0xFF00 | SetCRT2ToRAMDAC | SwitchToCRT2 | SetSimuScanMode ) ;
3618 tempbx &= ( 0x00FF | ( ~SetCRT2ToYPbPr ) ) ;
3619 }
3620 }
3621 else
3622 tempbx &= ( ~( SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV ) ) ;
3623 }
3624
3625 if ( !( pVBInfo->VBType & VB_NoLCD ) )
3626 {
3627 if ( tempbx & SetCRT2ToLCD )
3628 {
3629 tempbx &= ( 0xFF00 | SetCRT2ToLCD | SwitchToCRT2 | SetSimuScanMode ) ;
3630 tempbx &= ( 0x00FF | ( ~SetCRT2ToYPbPr ) ) ;
3631 }
3632 }
3633
3634 if ( tempbx & SetCRT2ToSCART )
3635 {
3636 tempbx &= ( 0xFF00 | SetCRT2ToSCART | SwitchToCRT2 | SetSimuScanMode ) ;
3637 tempbx &= ( 0x00FF | ( ~SetCRT2ToYPbPr ) ) ;
3638 }
3639
3640 if ( pVBInfo->IF_DEF_YPbPr == 1 )
3641 {
3642 if ( tempbx & SetCRT2ToYPbPr )
3643 tempbx &= ( 0xFF00 | SwitchToCRT2 | SetSimuScanMode ) ;
3644 }
3645
3646 if ( pVBInfo->IF_DEF_HiVision == 1 )
3647 {
3648 if ( tempbx & SetCRT2ToHiVisionTV )
3649 tempbx &= ( 0xFF00 | SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode ) ;
3650 }
3651
3652 if ( tempax & DisableCRT2Display ) /* Set Display Device Info */
3653 {
3654 if ( !( tempbx & ( SwitchToCRT2 | SetSimuScanMode ) ) )
3655 tempbx = DisableCRT2Display ;
3656 }
3657
3658 if ( !( tempbx & DisableCRT2Display ) )
3659 {
3660 if ( ( !( tempbx & DriverMode ) ) || ( !( modeflag & CRT2Mode ) ) )
3661 {
3662 if ( pVBInfo->IF_DEF_LCDA == 1 )
3663 {
3664 if ( !( tempbx & SetCRT2ToLCDA ) )
3665 tempbx |= ( SetInSlaveMode | SetSimuScanMode ) ;
3666 }
3667
3668 if ( pVBInfo->IF_DEF_VideoCapture == 1 )
3669 {
3670 if ( ( ( HwDeviceExtension->jChipType == XG40 ) && ( pVBInfo->Set_VGAType == XG40 ) )
3671 || ( ( HwDeviceExtension->jChipType == XG41 ) && ( pVBInfo->Set_VGAType == XG41 ) )
3672 || ( ( HwDeviceExtension->jChipType == XG42 ) && ( pVBInfo->Set_VGAType == XG42 ) )
3673 || ( ( HwDeviceExtension->jChipType == XG45 ) && ( pVBInfo->Set_VGAType == XG45 ) ) )
3674 {
3675 if ( ModeNo <= 13 )
3676 {
3677 if ( !( tempbx & SetCRT2ToRAMDAC ) ) /*CRT2 not need to support*/
3678 {
3679 tempbx &= ( 0x00FF | ( ~SetInSlaveMode ) ) ;
3680 pVBInfo->SetFlag |= EnableVCMode ;
3681 }
3682 }
3683 }
3684 }
3685 }
3686
3687 /*LCD+TV can't support in slave mode (Force LCDA+TV->LCDB)*/
3688 if ( ( tempbx & SetInSlaveMode ) && ( tempbx & SetCRT2ToLCDA ) )
3689 {
3690 tempbx ^= ( SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToDualEdge ) ;
3691 pVBInfo->SetFlag |= ReserveTVOption ;
3692 }
3693 }
3694 }
3695
3696 pVBInfo->VBInfo = tempbx ;
3697}
3698
3699
3700/* --------------------------------------------------------------------- */
3701/* Function : XGI_GetTVInfo */
3702/* Input : */
3703/* Output : */
3704/* Description : */
3705/* --------------------------------------------------------------------- */
3706void XGI_GetTVInfo( USHORT ModeNo , USHORT ModeIdIndex ,PVB_DEVICE_INFO pVBInfo )
3707{
3708 USHORT temp ,
3709 tempbx = 0 ,
3710 resinfo = 0 ,
3711 modeflag ,
3712 index1 ;
3713
3714 tempbx = 0 ;
3715 resinfo = 0 ;
3716
3717 if ( pVBInfo->VBInfo & SetCRT2ToTV )
3718 {
3719 if ( ModeNo <= 0x13 )
3720 {
3721 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ModeFlag */
3722 resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ; /* si+St_ResInfo */
3723 }
3724 else
3725 {
3726 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
3727 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo */
3728 }
3729
3730 if ( pVBInfo->VBInfo & SetCRT2ToTV )
3731 {
3732 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ;
3733 tempbx = temp;
3734 if ( tempbx & SetPALTV )
3735 {
3736 tempbx &= ( SetCHTVOverScan | SetPALMTV | SetPALNTV | SetPALTV ) ;
3737 if ( tempbx & SetPALMTV )
3738 tempbx &= ~SetPALTV ; /* set to NTSC if PAL-M */
3739 }
3740 else
3741 tempbx &= ( SetCHTVOverScan | SetNTSCJ | SetPALTV ) ;
3742/*
3743 if ( pVBInfo->IF_DEF_LVDS == 0 )
3744 {
3745 index1 = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ; //PAL-M/PAL-N Info
3746 temp2 = ( index1 & 0xC0 ) >> 5 ; //00:PAL, 01:PAL-M, 10:PAL-N
3747 tempbx |= temp2 ;
3748 if ( temp2 & 0x02 ) //PAL-M
3749 tempbx &= ( ~SetPALTV ) ;
3750 }
3751*/
3752 }
3753
3754 if ( pVBInfo->IF_DEF_CH7017 == 1 )
3755 {
3756 tempbx = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ;
3757
3758 if ( tempbx & TVOverScan )
3759 tempbx |= SetCHTVOverScan ;
3760 }
3761
3762 if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 07/05/04 */
3763 {
3764 tempbx = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ;
3765
3766 if ( tempbx & TVOverScan )
3767 {
3768 tempbx |= SetCHTVOverScan ;
3769 }
3770 }
3771
3772
3773 if ( pVBInfo->IF_DEF_LVDS == 0 )
3774 {
3775 if ( pVBInfo->VBInfo & SetCRT2ToSCART )
3776 tempbx |= SetPALTV ;
3777 }
3778
3779 if ( pVBInfo->IF_DEF_YPbPr == 1 )
3780 {
3781 if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
3782 {
3783 index1 = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ;
3784 index1 &= YPbPrMode ;
3785
3786 if ( index1 == YPbPrMode525i )
3787 tempbx |= SetYPbPrMode525i ;
3788
3789 if ( index1 == YPbPrMode525p )
3790 tempbx = tempbx | SetYPbPrMode525p;
3791 if ( index1 == YPbPrMode750p)
3792 tempbx = tempbx | SetYPbPrMode750p;
3793 }
3794 }
3795
3796 if ( pVBInfo->IF_DEF_HiVision == 1 )
3797 {
3798 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
3799 {
3800 tempbx = tempbx | SetYPbPrMode1080i | SetPALTV ;
3801 }
3802 }
3803
3804 if ( pVBInfo->IF_DEF_LVDS == 0 )
3805 { /* shampoo */
3806 if ( ( pVBInfo->VBInfo & SetInSlaveMode ) && ( !( pVBInfo->VBInfo & SetNotSimuMode ) ) )
3807 tempbx |= TVSimuMode ;
3808
3809 if ( !( tempbx & SetPALTV ) && ( modeflag > 13 ) && ( resinfo == 8 ) ) /* NTSC 1024x768, */
3810 tempbx |= NTSC1024x768 ;
3811
3812 tempbx |= RPLLDIV2XO ;
3813
3814 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
3815 {
3816 if ( pVBInfo->VBInfo & SetInSlaveMode )
3817 tempbx &=( ~RPLLDIV2XO ) ;
3818 }
3819 else
3820 {
3821 if ( tempbx & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
3822 tempbx &= ( ~RPLLDIV2XO ) ;
3823 else if ( !( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) ) )
3824 {
3825 if ( tempbx & TVSimuMode )
3826 tempbx &= ( ~RPLLDIV2XO ) ;
3827 }
3828 }
3829 }
3830 }
3831 pVBInfo->TVInfo = tempbx ;
3832}
3833
3834
3835/* --------------------------------------------------------------------- */
3836/* Function : XGI_GetLCDInfo */
3837/* Input : */
3838/* Output : */
3839/* Description : */
3840/* --------------------------------------------------------------------- */
3841BOOLEAN XGI_GetLCDInfo( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
3842{
3843 USHORT temp ,
3844 tempax ,
3845 tempbx ,
3846 modeflag ,
3847 resinfo = 0 ,
3848 LCDIdIndex ;
3849
3850 pVBInfo->LCDResInfo = 0 ;
3851 pVBInfo->LCDTypeInfo = 0 ;
3852 pVBInfo->LCDInfo = 0 ;
3853
3854 if ( ModeNo <= 0x13 )
3855 {
3856 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ModeFlag // */
3857 }
3858 else
3859 {
3860 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
3861 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo// */
3862 }
3863
3864 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ; /* Get LCD Res.Info */
3865 tempbx = temp & 0x0F ;
3866
3867 if ( tempbx == 0 )
3868 tempbx = Panel1024x768 ; /* default */
3869
3870 /* LCD75 [2003/8/22] Vicent */
3871 if ( ( tempbx == Panel1024x768 ) || ( tempbx == Panel1280x1024 ) )
3872 {
3873 if ( pVBInfo->VBInfo & DriverMode )
3874 {
3875 tempax = XGINew_GetReg1( pVBInfo->P3d4 , 0x33 ) ;
3876 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
3877 tempax &= 0x0F ;
3878 else
3879 tempax = tempax >> 4 ;
3880
3881 if ( ( resinfo == 6 ) || ( resinfo == 9 ) )
3882 {
3883 if ( tempax >= 3 )
3884 tempbx |= PanelRef75Hz ;
3885 }
3886 else if ( ( resinfo == 7 ) || ( resinfo == 8 ) )
3887 {
3888 if ( tempax >= 4 )
3889 tempbx |= PanelRef75Hz ;
3890 }
3891 }
3892 }
3893
3894 pVBInfo->LCDResInfo = tempbx ;
3895
3896 /* End of LCD75 */
3897
3898 if( pVBInfo->IF_DEF_OEMUtil == 1 )
3899 {
3900 pVBInfo->LCDTypeInfo = ( temp & 0xf0 ) >> 4 ;
3901 }
3902
3903 if ( !( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) )
3904 {
3905 return 0;
3906 }
3907
3908 tempbx = 0 ;
3909
3910 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
3911
3912 temp &= ( ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable ) ;
3913
3914 if ( ( pVBInfo->IF_DEF_ScaleLCD == 1 ) && ( temp & LCDNonExpanding ) )
3915 temp &= ~EnableScalingLCD ;
3916
3917 tempbx |= temp ;
3918
3919 LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo) ;
3920
3921 tempax = pVBInfo->LCDCapList[ LCDIdIndex ].LCD_Capability ;
3922
3923 if ( pVBInfo->IF_DEF_LVDS == 0 ) /* shampoo */
3924 {
3925 if ( ( ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) && ( tempax & LCDDualLink ) )
3926 {
3927 tempbx |= SetLCDDualLink ;
3928 }
3929 }
3930
3931 if ( pVBInfo->IF_DEF_CH7017 == 1 )
3932 {
3933 if ( tempax & LCDDualLink )
3934 {
3935 tempbx |= SetLCDDualLink ;
3936 }
3937 }
3938
3939 if ( pVBInfo->IF_DEF_LVDS == 0 )
3940 {
3941 if ( ( pVBInfo->LCDResInfo == Panel1400x1050 ) && ( pVBInfo->VBInfo & SetCRT2ToLCD ) && ( ModeNo > 0x13 ) && ( resinfo == 9 ) && ( !( tempbx & EnableScalingLCD ) ) )
3942 tempbx |= SetLCDtoNonExpanding ; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
3943 }
3944
3945/*
3946 if ( tempax & LCDBToA )
3947 {
3948 tempbx |= SetLCDBToA ;
3949 }
3950*/
3951
3952 if ( pVBInfo->IF_DEF_ExpLink == 1 )
3953 {
3954 if ( modeflag & HalfDCLK )
3955 {
3956 /* if ( !( pVBInfo->LCDInfo&LCDNonExpanding ) ) */
3957 if ( !( tempbx & SetLCDtoNonExpanding ) )
3958 {
3959 tempbx |= EnableLVDSDDA ;
3960 }
3961 else
3962 {
3963 if ( ModeNo > 0x13 )
3964 {
3965 if ( pVBInfo->LCDResInfo == Panel1024x768 )
3966 {
3967 if ( resinfo == 4 )
3968 { /* 512x384 */
3969 tempbx |= EnableLVDSDDA ;
3970 }
3971 }
3972 }
3973 }
3974 }
3975 }
3976
3977 if ( pVBInfo->VBInfo & SetInSlaveMode )
3978 {
3979 if ( pVBInfo->VBInfo & SetNotSimuMode )
3980 {
3981 tempbx |= LCDVESATiming ;
3982 }
3983 }
3984 else
3985 {
3986 tempbx |= LCDVESATiming ;
3987 }
3988
3989 pVBInfo->LCDInfo = tempbx ;
3990
3991 if ( pVBInfo->IF_DEF_PWD == 1 )
3992 {
3993 if ( pVBInfo->LCDInfo & SetPWDEnable )
3994 {
3995 if ( ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) )
3996 {
3997 if ( !( tempax & PWDEnable ) )
3998 {
3999 pVBInfo->LCDInfo &= ~SetPWDEnable ;
4000 }
4001 }
4002 }
4003 }
4004
4005 if ( pVBInfo->IF_DEF_LVDS == 0 )
4006 {
4007 if ( tempax & ( LockLCDBToA | StLCDBToA ) )
4008 {
4009 if ( pVBInfo->VBInfo & SetInSlaveMode )
4010 {
4011 if ( !( tempax & LockLCDBToA ) )
4012 {
4013 if ( ModeNo <= 0x13 )
4014 {
4015 pVBInfo->VBInfo &= ~( SetSimuScanMode | SetInSlaveMode | SetCRT2ToLCD ) ;
4016 pVBInfo->VBInfo |= SetCRT2ToLCDA | SetCRT2ToDualEdge ;
4017 }
4018 }
4019 }
4020 }
4021 }
4022
4023/*
4024 if ( pVBInfo->IF_DEF_LVDS == 0 )
4025 {
4026 if ( tempax & ( LockLCDBToA | StLCDBToA ) )
4027 {
4028 if ( pVBInfo->VBInfo & SetInSlaveMode )
4029 {
4030 if ( !( ( !( tempax & LockLCDBToA ) ) && ( ModeNo > 0x13 ) ) )
4031 {
4032 pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD);
4033 pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge;
4034 }
4035 }
4036 }
4037 }
4038*/
4039
4040 return( 1 ) ;
4041}
4042
4043
4044/* --------------------------------------------------------------------- */
4045/* Function : XGI_SearchModeID */
4046/* Input : */
4047/* Output : */
4048/* Description : */
4049/* --------------------------------------------------------------------- */
4050BOOLEAN XGI_SearchModeID( USHORT ModeNo , USHORT *ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
4051{
4052
4053#ifdef TC
4054
4055 if ( ModeNo <= 5 )
4056 ModeNo |= 1 ;
4057
4058 if ( ModeNo <= 0x13 )
4059 {
4060 /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->SModeIDTable)/sizeof(XGI_StStruct);(*ModeIdIndex)++) */
4061 for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
4062 {
4063 if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == ModeNo )
4064 break ;
4065 if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == 0xFF )
4066 return( FALSE ) ;
4067 }
4068
4069 VGA_INFO = ( PUCHAR )MK_FP( 0 , 0x489 ) ;
4070
4071 if ( ModeNo == 0x07 )
4072 {
4073 if ( ( *VGA_INFO & 0x10 ) != 0 )
4074 ( *ModeIdIndex )++ ; /* 400 lines */
4075 /* else 350 lines */
4076 }
4077
4078 if ( ModeNo <= 3 )
4079 {
4080 if ( ( *VGA_INFO & 0x80 ) == 0 )
4081 {
4082 ( *ModeIdIndex )++ ;
4083 if ( ( *VGA_INFO & 0x10 ) != 0 )
4084 ( *ModeIdIndex )++ ; /* 400 lines */
4085 /* else 350 lines */
4086 }
4087 /* else 200 lines */
4088 }
4089 }
4090 else
4091 {
4092 /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->EModeIDTable)/sizeof(XGI_ExtStruct);(*ModeIdIndex)++) */
4093 for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
4094 {
4095 if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == ModeNo )
4096 break ;
4097 if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == 0xFF )
4098 return( FALSE ) ;
4099 }
4100 }
4101
4102
4103#endif
4104
4105#ifdef WIN2000
4106
4107 if ( ModeNo <= 5 )
4108 ModeNo |= 1 ;
4109 if ( ModeNo <= 0x13 )
4110 {
4111 /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->SModeIDTable)/sizeof(XGI_StStruct);(*ModeIdIndex)++) */
4112 for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
4113 {
4114 if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == ModeNo )
4115 break ;
4116 if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == 0xFF )
4117 return( FALSE ) ;
4118 }
4119
4120 if ( ModeNo == 0x07 )
4121 ( *ModeIdIndex )++ ; /* 400 lines */
4122
4123 if ( ModeNo <=3 )
4124 ( *ModeIdIndex ) += 2 ; /* 400 lines */
4125 /* else 350 lines */
4126 }
4127 else
4128 {
4129 /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->EModeIDTable)/sizeof(XGI_ExtStruct);(*ModeIdIndex)++) */
4130 for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
4131 {
4132 if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == ModeNo )
4133 break ;
4134 if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == 0xFF )
4135 return( FALSE ) ;
4136 }
4137 }
4138
4139#endif
4140
4141#ifdef LINUX /* chiawen for linux solution */
4142
4143 if ( ModeNo <= 5 )
4144 ModeNo |= 1 ;
4145 if ( ModeNo <= 0x13 )
4146 {
4147 /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->SModeIDTable)/sizeof(XGI_StStruct);(*ModeIdIndex)++) */
4148 for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
4149 {
4150 if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == ModeNo )
4151 break ;
4152 if ( pVBInfo->SModeIDTable[ *ModeIdIndex ].St_ModeID == 0xFF )
4153 return( FALSE ) ;
4154 }
4155
4156 if ( ModeNo == 0x07 )
4157 ( *ModeIdIndex )++ ; /* 400 lines */
4158
4159 if ( ModeNo <= 3 )
4160 ( *ModeIdIndex ) += 2 ; /* 400 lines */
4161 /* else 350 lines */
4162 }
4163 else
4164 {
4165 /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->EModeIDTable)/sizeof(XGI_ExtStruct);(*ModeIdIndex)++) */
4166 for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
4167 {
4168 if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == ModeNo )
4169 break ;
4170 if ( pVBInfo->EModeIDTable[ *ModeIdIndex ].Ext_ModeID == 0xFF )
4171 return( FALSE ) ;
4172 }
4173 }
4174
4175#endif
4176
4177 return( TRUE ) ;
4178}
4179
4180
4181
4182
4183/* win2000 MM adapter not support standard mode! */
4184
4185/* --------------------------------------------------------------------- */
4186/* Function : */
4187/* Input : */
4188/* Output : */
4189/* Description : */
4190/* --------------------------------------------------------------------- */
4191BOOLEAN XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo)
4192{
4193 USHORT memorysize ,
4194 modeflag ,
4195 temp ,
4196 temp1 ,
4197 tmp ;
4198
4199/* if ( ( HwDeviceExtension->jChipType == XGI_650 ) ||
4200 ( HwDeviceExtension->jChipType == XGI_650M ) )
4201 {
4202 return( TRUE ) ;
4203 } */
4204
4205 if ( ModeNo <= 0x13 )
4206 {
4207 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
4208 }
4209 else {
4210 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
4211 }
4212
4213 /* ModeType = modeflag&ModeInfoFlag ; // Get mode type */
4214
4215 memorysize = modeflag & MemoryInfoFlag ;
4216 memorysize = memorysize > MemorySizeShift ;
4217 memorysize++ ; /* Get memory size */
4218
4219 temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ; /* Get DRAM Size */
4220 tmp = temp ;
4221
4222 if ( HwDeviceExtension->jChipType == XG40 )
4223 {
4224 temp = 1 << ( ( temp & 0x0F0 ) >> 4 ) ; /* memory size per channel SR14[7:4] */
4225 if ( ( tmp & 0x0c ) == 0x0C ) /* Qual channels */
4226 {
4227 temp <<= 2 ;
4228 }
4229 else if ( ( tmp & 0x0c ) == 0x08 ) /* Dual channels */
4230 {
4231 temp <<= 1 ;
4232 }
4233 }
4234 else if ( HwDeviceExtension->jChipType == XG42 )
4235 {
4236 temp = 1 << ( ( temp & 0x0F0 ) >> 4 ) ; /* memory size per channel SR14[7:4] */
4237 if ( ( tmp & 0x04 ) == 0x04 ) /* Dual channels */
4238 {
4239 temp <<= 1 ;
4240 }
4241 }
4242 else if ( HwDeviceExtension->jChipType == XG45 )
4243 {
4244 temp = 1 << ( ( temp & 0x0F0 ) >> 4 ) ; /* memory size per channel SR14[7:4] */
4245 if ( ( tmp & 0x0c ) == 0x0C ) /* Qual channels */
4246 {
4247 temp <<= 2 ;
4248 }
4249 else if ( ( tmp & 0x0c ) == 0x08 ) /* triple channels */
4250 {
4251 temp1 = temp ;
4252 temp <<= 1 ;
4253 temp += temp1 ;
4254 }
4255 else if ( ( tmp & 0x0c ) == 0x04 ) /* Dual channels */
4256 {
4257 temp <<= 1 ;
4258 }
4259 }
4260 if ( temp < memorysize )
4261 return( FALSE ) ;
4262 else
4263 return( TRUE ) ;
4264}
4265
4266
4267/* --------------------------------------------------------------------- */
4268/* Function : XGINew_IsLowResolution */
4269/* Input : */
4270/* Output : */
4271/* Description : */
4272/* --------------------------------------------------------------------- */
4273/*void XGINew_IsLowResolution( USHORT ModeNo , USHORT ModeIdIndex, BOOLEAN XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO pVBInfo)
4274{
4275 USHORT data ;
4276 USHORT ModeFlag ;
4277
4278 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x0F ) ;
4279 data &= 0x7F ;
4280 XGINew_SetReg1( pVBInfo->P3c4 , 0x0F , data ) ;
4281
4282 if ( ModeNo > 0x13 )
4283 {
4284 ModeFlag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
4285 if ( ( ModeFlag & HalfDCLK ) && ( ModeFlag & DoubleScanMode ) )
4286 {
4287 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x0F ) ;
4288 data |= 0x80 ;
4289 XGINew_SetReg1( pVBInfo->P3c4 , 0x0F , data ) ;
4290 data = XGINew_GetReg1( pVBInfo->P3c4 , 0x01 ) ;
4291 data &= 0xF7 ;
4292 XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , data ) ;
4293 }
4294 }
4295}
4296
4297*/
4298
4299/* --------------------------------------------------------------------- */
4300/* Function : XGI_DisplayOn */
4301/* Input : */
4302/* Output : */
4303/* Description : */
4304/* --------------------------------------------------------------------- */
4305void XGI_DisplayOn( PXGI_HW_DEVICE_INFO pXGIHWDE , PVB_DEVICE_INFO pVBInfo )
4306{
4307
4308 XGINew_SetRegANDOR(pVBInfo->P3c4,0x01,0xDF,0x00);
4309 if ( pXGIHWDE->jChipType == XG21 )
4310 {
4311 if ( pVBInfo->IF_DEF_LVDS == 1 )
4312 {
4313 if (!(XGI_XG21GetPSCValue( pVBInfo )&0x1))
4314 {
4315 XGI_XG21BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
4316 XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
4317 }
4318 if (!(XGI_XG21GetPSCValue( pVBInfo )&0x20))
4319 {
4320 XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
4321 }
4322 XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
4323 XGI_XG21BLSignalVDD( 0x02 , 0x02, pVBInfo ) ; /* LVDS backlight on */
4324 }
4325 else
4326 {
4327 XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* DVO/DVI signal on */
4328 }
4329
4330 }
4331
4332 if (pVBInfo->IF_DEF_CH7007 == 1) /* [Billy] 07/05/23 For CH7007 */
4333 {
4334#ifdef WIN2000
4335 if ( IsCH7007TVMode( pVBInfo ) )
4336 {
4337 TurnOnCH7007(pXGIHWDE->pDevice) ; /* 07/05/28 */
4338 }
4339#endif
4340
4341 }
4342
4343
4344 if ( pXGIHWDE->jChipType == XG27 )
4345 {
4346 if ( pVBInfo->IF_DEF_LVDS == 1 )
4347 {
4348 if (!(XGI_XG27GetPSCValue( pVBInfo )&0x1))
4349 {
4350 XGI_XG27BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
4351 XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
4352 }
4353 if (!(XGI_XG27GetPSCValue( pVBInfo )&0x20))
4354 {
4355 XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
4356 }
4357 XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
4358 XGI_XG27BLSignalVDD( 0x02 , 0x02, pVBInfo ) ; /* LVDS backlight on */
4359 }
4360 else
4361 {
4362 XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* DVO/DVI signal on */
4363 }
4364
4365 }
4366}
4367
4368
4369/* --------------------------------------------------------------------- */
4370/* Function : XGI_DisplayOff */
4371/* Input : */
4372/* Output : */
4373/* Description : */
4374/* --------------------------------------------------------------------- */
4375void XGI_DisplayOff( PXGI_HW_DEVICE_INFO pXGIHWDE , PVB_DEVICE_INFO pVBInfo )
4376{
4377
4378 if ( pXGIHWDE->jChipType == XG21 )
4379 {
4380 if ( pVBInfo->IF_DEF_LVDS == 1 )
4381 {
4382 XGI_XG21BLSignalVDD( 0x02 , 0x00, pVBInfo ) ; /* LVDS backlight off */
4383 XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
4384 }
4385 else
4386 {
4387 XGI_XG21BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* DVO/DVI signal off */
4388 }
4389 }
4390
4391 if (pVBInfo->IF_DEF_CH7007 == 1) /*[Billy] 07/05/23 For CH7007 */
4392 {
4393 /* if( IsCH7007TVMode( pVBInfo ) == 0 ) */
4394 {
4395#ifdef WIN2000
4396 TurnOffCH7007(pXGIHWDE->pDevice) ; /* 07/05/28 */
4397#endif
4398 }
4399 }
4400
4401
4402 if ( pXGIHWDE->jChipType == XG27 )
4403 {
4404 if ((XGI_XG27GetPSCValue( pVBInfo )&0x2))
4405 {
4406 XGI_XG27BLSignalVDD( 0x02 , 0x00, pVBInfo ) ; /* LVDS backlight off */
4407 XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
4408 }
4409
4410 if ( pVBInfo->IF_DEF_LVDS == 0 )
4411 {
4412 XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* DVO/DVI signal off */
4413 }
4414 }
4415
4416 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xDF , 0x20 ) ;
4417}
4418
4419
4420/* --------------------------------------------------------------------- */
4421/* Function : XGI_WaitDisply */
4422/* Input : */
4423/* Output : */
4424/* Description : chiawen for sensecrt1 */
4425/* --------------------------------------------------------------------- */
4426void XGI_WaitDisply( PVB_DEVICE_INFO pVBInfo )
4427{
4428 while( ( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) )
4429 break ;
4430
4431 while( !( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) )
4432 break ;
4433}
4434
4435/* --------------------------------------------------------------------- */
4436/* Function : XGI_SenseCRT1 */
4437/* Input : */
4438/* Output : */
4439/* Description : */
4440/* --------------------------------------------------------------------- */
4441
4442void XGI_SenseCRT1( PVB_DEVICE_INFO pVBInfo )
4443{
4444 UCHAR CRTCData[ 17 ] = { 0x5F , 0x4F , 0x50 , 0x82 , 0x55 , 0x81 ,
4445 0x0B , 0x3E , 0xE9 , 0x0B , 0xDF , 0xE7 ,
4446 0x04 , 0x00 , 0x00 , 0x05 , 0x00 } ;
4447
4448 UCHAR SR01 = 0 , SR1F = 0 , SR07 = 0 , SR06 = 0 ;
4449
4450 UCHAR CR17 , CR63 , SR31 ;
4451 USHORT temp ;
4452 UCHAR DAC_TEST_PARMS[ 3 ] = { 0x0F , 0x0F , 0x0F } ;
4453
4454 int i ;
4455 XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
4456
4457 /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
4458 XGINew_SetReg1( pVBInfo->P3d4 , 0x57 , 0x4A ) ;
4459 XGINew_SetReg1( pVBInfo->P3d4 , 0x53 , ( UCHAR )( XGINew_GetReg1( pVBInfo->P3d4 , 0x53 ) | 0x02 ) ) ;
4460
4461 SR31 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x31 ) ;
4462 CR63 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x63 ) ;
4463 SR01 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x01 ) ;
4464
4465 XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , ( UCHAR )( SR01 & 0xDF ) ) ;
4466 XGINew_SetReg1( pVBInfo->P3d4 , 0x63 , ( UCHAR )( CR63 & 0xBF ) ) ;
4467
4468 CR17 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x17 ) ;
4469 XGINew_SetReg1( pVBInfo->P3d4 , 0x17 , ( UCHAR )( CR17 | 0x80 ) ) ;
4470
4471 SR1F = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x1F ) ;
4472 XGINew_SetReg1( pVBInfo->P3c4 , 0x1F , ( UCHAR )( SR1F | 0x04 ) ) ;
4473
4474 SR07 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x07 ) ;
4475 XGINew_SetReg1( pVBInfo->P3c4 , 0x07 , ( UCHAR )( SR07 & 0xFB ) ) ;
4476 SR06 = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x06 ) ;
4477 XGINew_SetReg1( pVBInfo->P3c4 , 0x06 , ( UCHAR )( SR06 & 0xC3 ) ) ;
4478
4479 XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , 0x00 ) ;
4480
4481 for( i = 0 ; i < 8 ; i++ )
4482 XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )i , CRTCData[ i ] ) ;
4483
4484 for( i = 8 ; i < 11 ; i++ )
4485 XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 8 ) , CRTCData[ i ] ) ;
4486
4487 for( i = 11 ; i < 13 ; i++ )
4488 XGINew_SetReg1( pVBInfo->P3d4 , ( USHORT )( i + 4 ) , CRTCData[ i ] ) ;
4489
4490 for( i = 13 ; i < 16 ; i++ )
4491 XGINew_SetReg1( pVBInfo->P3c4 , ( USHORT )( i - 3 ) , CRTCData[ i ] ) ;
4492
4493 XGINew_SetReg1( pVBInfo->P3c4 , 0x0E , ( UCHAR )( CRTCData[ 16 ] & 0xE0 ) ) ;
4494
4495 XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , 0x00 ) ;
4496 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x1B ) ;
4497 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , 0xE1 ) ;
4498
4499 XGINew_SetReg3( pVBInfo->P3c8 , 0x00 ) ;
4500
4501 for( i = 0 ; i < 256 ; i++ )
4502 {
4503 XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , ( UCHAR )DAC_TEST_PARMS[ 0 ] ) ;
4504 XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , ( UCHAR )DAC_TEST_PARMS[ 1 ] ) ;
4505 XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , ( UCHAR )DAC_TEST_PARMS[ 2 ] ) ;
4506 }
4507
4508 XGI_VBLongWait( pVBInfo ) ;
4509 XGI_VBLongWait( pVBInfo ) ;
4510 XGI_VBLongWait( pVBInfo ) ;
4511
4512 XGINew_LCD_Wait_Time( 0x01 , pVBInfo ) ;
4513
4514 XGI_WaitDisply( pVBInfo ) ;
4515 temp = XGINew_GetReg2( pVBInfo->P3c2 ) ;
4516
4517 if( temp & 0x10 )
4518 {
4519 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , 0xDF , 0x20 ) ;
4520 }
4521 else
4522 {
4523 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , 0xDF , 0x00 ) ;
4524 }
4525
4526 /* alan, avoid display something, set BLACK DAC if not restore DAC */
4527 XGINew_SetReg3( pVBInfo->P3c8 , 0x00 ) ;
4528
4529 for( i = 0 ; i < 256 ; i++ )
4530 {
4531 XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , 0 ) ;
4532 XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , 0 ) ;
4533 XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , 0 ) ;
4534 }
4535
4536 XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , SR01 ) ;
4537 XGINew_SetReg1( pVBInfo->P3d4 , 0x63 , CR63 ) ;
4538 XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , SR31 ) ;
4539
4540 /* [2004/05/11] Vicent */
4541 XGINew_SetReg1( pVBInfo->P3d4 , 0x53 , ( UCHAR )( XGINew_GetReg1( pVBInfo->P3d4 , 0x53 ) & 0xFD ) ) ;
4542 XGINew_SetReg1( pVBInfo->P3c4 , 0x1F , ( UCHAR ) SR1F ) ;
4543}
4544
4545
4546
4547
4548
4549#ifdef TC
4550/* --------------------------------------------------------------------- */
4551/* Function : INT1AReturnCode */
4552/* Input : */
4553/* Output : */
4554/* Description : */
4555/* --------------------------------------------------------------------- */
4556int INT1AReturnCode( union REGS regs )
4557{
4558 if ( regs.x.cflag )
4559 {
4560 /* printf( "Error to find pci device!\n" ) ; */
4561 return( 1 ) ;
4562 }
4563
4564 switch(regs.h.ah)
4565 {
4566 case 0: return 0;
4567 break ;
4568 case 0x81:
4569 printf( "Function not support\n" ) ;
4570 break ;
4571 case 0x83:
4572 printf( "bad vendor id\n" ) ;
4573 break ;
4574 case 0x86:
4575 printf( "device not found\n" ) ;
4576 break ;
4577 case 0x87:
4578 printf( "bad register number\n" ) ;
4579 break ;
4580 case 0x88:
4581 printf( "set failed\n" ) ;
4582 break ;
4583 case 0x89:
4584 printf( "buffer too small" ) ;
4585 break ;
4586 default:
4587 break ;
4588 }
4589 return( 1 ) ;
4590}
4591
4592
4593/* --------------------------------------------------------------------- */
4594/* Function : FindPCIIOBase */
4595/* Input : */
4596/* Output : */
4597/* Description : */
4598/* --------------------------------------------------------------------- */
4599unsigned FindPCIIOBase( unsigned index , unsigned deviceid )
4600{
4601 union REGS regs ;
4602
4603 regs.h.ah = 0xb1 ; /* PCI_FUNCTION_ID */
4604 regs.h.al = 0x02 ; /* FIND_PCI_DEVICE */
4605 regs.x.cx = deviceid ;
4606 regs.x.dx = 0x1039 ;
4607 regs.x.si = index ; /* find n-th device */
4608
4609 int86( 0x1A , &regs , &regs ) ;
4610
4611 if ( INT1AReturnCode( regs ) != 0 )
4612 return( 0 ) ;
4613
4614 /* regs.h.bh bus number */
4615 /* regs.h.bl device number */
4616 regs.h.ah = 0xb1 ; /* PCI_FUNCTION_ID */
4617 regs.h.al = 0x09 ; /* READ_CONFIG_WORD */
4618 regs.x.cx = deviceid ;
4619 regs.x.dx = 0x1039 ;
4620 regs.x.di = 0x18 ; /* register number */
4621 int86( 0x1A , &regs , &regs ) ;
4622
4623 if ( INT1AReturnCode( regs ) != 0 )
4624 return( 0 ) ;
4625
4626 return( regs.x.cx ) ;
4627}
4628
4629#endif
4630
4631
4632
4633#ifdef TC
4634/* --------------------------------------------------------------------- */
4635/* Function : main */
4636/* Input : */
4637/* Output : */
4638/* Description : */
4639/* --------------------------------------------------------------------- */
4640void main(int argc, char *argv[])
4641{
4642 XGI_HW_DEVICE_INFO HwDeviceExtension ;
4643 USHORT temp ;
4644 USHORT ModeNo ;
4645
4646 /* HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
4647 /* HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0); */
4648
4649
4650 HwDeviceExtension.pjIOAddress = ( FindPCIIOBase( 0 ,0x6300 ) & 0xFF80 ) + 0x30 ;
4651 HwDeviceExtension.jChipType = XGI_340 ;
4652
4653
4654
4655 /* HwDeviceExtension.pjIOAddress = ( FindPCIIOBase( 0 , 0x5315 ) & 0xFF80 ) + 0x30 ; */
4656
4657 HwDeviceExtension.pjIOAddress = ( FindPCIIOBase( 0 , 0x330 ) & 0xFF80 ) + 0x30 ;
4658 HwDeviceExtension.jChipType = XGI_340 ;
4659
4660
4661 HwDeviceExtension.ujVBChipID = VB_CHIP_301 ;
4662 StrCpy(HwDeviceExtension.szVBIOSVer , "0.84" ) ;
4663 HwDeviceExtension.bSkipDramSizing = FALSE ;
4664 HwDeviceExtension.ulVideoMemorySize = 0 ;
4665
4666 if ( argc == 2 )
4667 {
4668 ModeNo = atoi( argv[ 1 ] ) ;
4669 }
4670 else
4671 {
4672 ModeNo = 0x2e ;
4673 /* ModeNo = 0x37 ; 1024x768x 4bpp */
4674 /* ModeNo = 0x38 ; 1024x768x 8bpp */
4675 /* ModeNo = 0x4A ; 1024x768x 16bpp */
4676 /* ModeNo = 0x47 ; 800x600x 16bpp */
4677 }
4678
4679 /* XGIInitNew( &HwDeviceExtension ) ; */
4680 XGISetModeNew( &HwDeviceExtension , ModeNo ) ;
4681}
4682#endif
4683
4684
4685/* --------------------------------------------------------------------- */
4686/* Function : XGI_WaitDisplay */
4687/* Input : */
4688/* Output : */
4689/* Description : */
4690/* --------------------------------------------------------------------- */
4691void XGI_WaitDisplay( PVB_DEVICE_INFO pVBInfo )
4692{
4693 while( !( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) ) ;
4694
4695 while( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) ;
4696}
4697
4698
4699
4700
4701/* --------------------------------------------------------------------- */
4702/* Function : XGI_SetCRT2Group301 */
4703/* Input : */
4704/* Output : */
4705/* Description : */
4706/* --------------------------------------------------------------------- */
4707BOOLEAN XGI_SetCRT2Group301( USHORT ModeNo , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
4708{
4709 USHORT tempbx ,
4710 ModeIdIndex ,
4711 RefreshRateTableIndex ;
4712
4713 tempbx=pVBInfo->VBInfo ;
4714 pVBInfo->SetFlag |= ProgrammingCRT2 ;
4715 XGI_SearchModeID( ModeNo , &ModeIdIndex, pVBInfo ) ;
4716 pVBInfo->SelectCRT2Rate = 4 ;
4717 RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, pVBInfo ) ;
4718 XGI_SaveCRT2Info( ModeNo, pVBInfo ) ;
4719 XGI_GetCRT2ResInfo( ModeNo , ModeIdIndex, pVBInfo) ;
4720 XGI_GetCRT2Data( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
4721 XGI_PreSetGroup1( ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
4722 XGI_SetGroup1( ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
4723 XGI_SetLockRegs( ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
4724 XGI_SetGroup2( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
4725 XGI_SetLCDRegs(ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
4726 XGI_SetTap4Regs(pVBInfo) ;
4727 XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
4728 XGI_SetGroup4( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
4729 XGI_SetCRT2VCLK( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
4730 XGI_SetGroup5( ModeNo , ModeIdIndex, pVBInfo) ;
4731 XGI_AutoThreshold( pVBInfo) ;
4732 return 1 ;
4733}
4734
4735
4736/* --------------------------------------------------------------------- */
4737/* Function : XGI_AutoThreshold */
4738/* Input : */
4739/* Output : */
4740/* Description : */
4741/* --------------------------------------------------------------------- */
4742void XGI_AutoThreshold( PVB_DEVICE_INFO pVBInfo )
4743{
4744 if ( !( pVBInfo->SetFlag & Win9xDOSMode ) )
4745 XGINew_SetRegOR( pVBInfo->Part1Port , 0x01 , 0x40 ) ;
4746}
4747
4748
4749/* --------------------------------------------------------------------- */
4750/* Function : XGI_SaveCRT2Info */
4751/* Input : */
4752/* Output : */
4753/* Description : */
4754/* --------------------------------------------------------------------- */
4755void XGI_SaveCRT2Info( USHORT ModeNo , PVB_DEVICE_INFO pVBInfo)
4756{
4757 USHORT temp1 ,
4758 temp2 ;
4759
4760 XGINew_SetReg1( pVBInfo->P3d4 , 0x34 , ModeNo ) ; /* reserve CR34 for CRT1 Mode No */
4761 temp1 = ( pVBInfo->VBInfo&SetInSlaveMode ) >> 8 ;
4762 temp2 = ~( SetInSlaveMode >> 8 ) ;
4763 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x31 , temp2 , temp1 ) ;
4764}
4765
4766
4767/* --------------------------------------------------------------------- */
4768/* Function : XGI_GetCRT2ResInfo */
4769/* Input : */
4770/* Output : */
4771/* Description : */
4772/* --------------------------------------------------------------------- */
4773void XGI_GetCRT2ResInfo( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
4774{
4775 USHORT xres ,
4776 yres ,
4777 modeflag ,
4778 resindex ;
4779
4780 resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo) ;
4781 if ( ModeNo <= 0x13 )
4782 {
4783 xres = pVBInfo->StResInfo[ resindex ].HTotal ;
4784 yres = pVBInfo->StResInfo[ resindex ].VTotal ;
4785 /* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */
4786 }
4787 else
4788 {
4789 xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
4790 yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
4791 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
4792
4793/* if ( pVBInfo->IF_DEF_FSTN )
4794 {
4795 xres *= 2 ;
4796 yres *= 2 ;
4797 }
4798 else
4799 {
4800*/
4801 if ( modeflag & HalfDCLK )
4802 xres *= 2;
4803
4804 if ( modeflag & DoubleScanMode )
4805 yres *= 2 ;
4806/* } */
4807 }
4808
4809 if ( pVBInfo->VBInfo & SetCRT2ToLCD )
4810 {
4811 if ( pVBInfo->IF_DEF_LVDS == 0 )
4812 {
4813 if ( pVBInfo->LCDResInfo == Panel1600x1200 )
4814 {
4815 if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
4816 {
4817 if ( yres == 1024 )
4818 yres = 1056 ;
4819 }
4820 }
4821
4822 if ( pVBInfo->LCDResInfo == Panel1280x1024 )
4823 {
4824 if ( yres == 400 )
4825 yres = 405 ;
4826 else if ( yres == 350 )
4827 yres = 360 ;
4828
4829 if ( pVBInfo->LCDInfo & LCDVESATiming )
4830 {
4831 if ( yres == 360 )
4832 yres = 375 ;
4833 }
4834 }
4835
4836 if ( pVBInfo->LCDResInfo == Panel1024x768 )
4837 {
4838 if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
4839 {
4840 if ( !( pVBInfo->LCDInfo & LCDNonExpanding ) )
4841 {
4842 if ( yres == 350 )
4843 yres = 357 ;
4844 else if ( yres == 400 )
4845 yres = 420 ;
4846 else if ( yres == 480 )
4847 yres = 525 ;
4848 }
4849 }
4850 }
4851 }
4852
4853 if ( xres == 720 )
4854 xres = 640 ;
4855 }
4856
4857 pVBInfo->VGAHDE = xres ;
4858 pVBInfo->HDE = xres ;
4859 pVBInfo->VGAVDE = yres ;
4860 pVBInfo->VDE = yres ;
4861}
4862
4863
4864/* --------------------------------------------------------------------- */
4865/* Function : XGI_IsLCDDualLink */
4866/* Input : */
4867/* Output : */
4868/* Description : */
4869/* --------------------------------------------------------------------- */
4870BOOLEAN XGI_IsLCDDualLink( PVB_DEVICE_INFO pVBInfo )
4871{
4872
4873 if ( ( ( ( pVBInfo->VBInfo & SetCRT2ToLCD ) | SetCRT2ToLCDA ) ) && ( pVBInfo->LCDInfo & SetLCDDualLink ) ) /* shampoo0129 */
4874 return ( 1 ) ;
4875
4876 return( 0 ) ;
4877}
4878
4879
4880/* --------------------------------------------------------------------- */
4881/* Function : XGI_GetCRT2Data */
4882/* Input : */
4883/* Output : */
4884/* Description : */
4885/* --------------------------------------------------------------------- */
4886void XGI_GetCRT2Data( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
4887{
4888 USHORT tempax = 0,
4889 tempbx ,
4890 modeflag ,
4891 resinfo ;
4892
4893 XGI_LCDDataStruct *LCDPtr = NULL ;
4894 XGI_TVDataStruct *TVPtr = NULL ;
4895
4896 if ( ModeNo <= 0x13 )
4897 {
4898 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
4899 resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
4900 }
4901 else
4902 {
4903 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
4904 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
4905 }
4906
4907 pVBInfo->NewFlickerMode = 0 ;
4908 pVBInfo->RVBHRS = 50 ;
4909
4910 if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
4911 {
4912 XGI_GetRAMDAC2DATA( ModeNo , ModeIdIndex , RefreshRateTableIndex,pVBInfo ) ;
4913 return ;
4914 }
4915
4916 tempbx = 4 ;
4917
4918 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
4919 {
4920 LCDPtr = (XGI_LCDDataStruct* )XGI_GetLcdPtr( tempbx, ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
4921
4922 pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX ;
4923 pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT ;
4924 pVBInfo->VGAHT = LCDPtr->VGAHT ;
4925 pVBInfo->VGAVT = LCDPtr->VGAVT ;
4926 pVBInfo->HT = LCDPtr->LCDHT ;
4927 pVBInfo->VT = LCDPtr->LCDVT ;
4928
4929 if ( pVBInfo->LCDResInfo == Panel1024x768 )
4930 {
4931 tempax = 1024 ;
4932 tempbx = 768 ;
4933
4934 if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
4935 {
4936 if ( pVBInfo->VGAVDE == 357 )
4937 tempbx = 527 ;
4938 else if ( pVBInfo->VGAVDE == 420 )
4939 tempbx = 620 ;
4940 else if ( pVBInfo->VGAVDE == 525 )
4941 tempbx = 775 ;
4942 else if ( pVBInfo->VGAVDE == 600 )
4943 tempbx = 775 ;
4944 /* else if(pVBInfo->VGAVDE==350) tempbx=560; */
4945 /* else if(pVBInfo->VGAVDE==400) tempbx=640; */
4946 else
4947 tempbx = 768 ;
4948 }
4949 else
4950 tempbx = 768 ;
4951 }
4952 else if ( pVBInfo->LCDResInfo == Panel1024x768x75 )
4953 {
4954 tempax = 1024 ;
4955 tempbx = 768 ;
4956 }
4957 else if ( pVBInfo->LCDResInfo == Panel1280x1024 )
4958 {
4959 tempax = 1280 ;
4960 if ( pVBInfo->VGAVDE == 360 )
4961 tempbx = 768 ;
4962 else if ( pVBInfo->VGAVDE == 375 )
4963 tempbx = 800 ;
4964 else if ( pVBInfo->VGAVDE == 405 )
4965 tempbx = 864 ;
4966 else
4967 tempbx = 1024 ;
4968 }
4969 else if ( pVBInfo->LCDResInfo == Panel1280x1024x75 )
4970 {
4971 tempax = 1280 ;
4972 tempbx = 1024 ;
4973 }
4974 else if ( pVBInfo->LCDResInfo == Panel1280x960 )
4975 {
4976 tempax = 1280 ;
4977 if ( pVBInfo->VGAVDE == 350 )
4978 tempbx = 700 ;
4979 else if ( pVBInfo->VGAVDE == 400 )
4980 tempbx = 800 ;
4981 else if ( pVBInfo->VGAVDE == 1024 )
4982 tempbx = 960 ;
4983 else
4984 tempbx = 960 ;
4985 }
4986 else if ( pVBInfo->LCDResInfo == Panel1400x1050 )
4987 {
4988 tempax = 1400 ;
4989 tempbx = 1050 ;
4990
4991 if ( pVBInfo->VGAVDE == 1024 )
4992 {
4993 tempax = 1280 ;
4994 tempbx = 1024 ;
4995 }
4996 }
4997 else if ( pVBInfo->LCDResInfo == Panel1600x1200 )
4998 {
4999 tempax = 1600 ;
5000 tempbx = 1200 ; /* alan 10/14/2003 */
5001 if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
5002 {
5003 if ( pVBInfo->VGAVDE == 350 )
5004 tempbx = 875 ;
5005 else if ( pVBInfo->VGAVDE == 400 )
5006 tempbx = 1000 ;
5007 }
5008 }
5009
5010 if ( pVBInfo->LCDInfo & LCDNonExpanding )
5011 {
5012 tempax = pVBInfo->VGAHDE ;
5013 tempbx = pVBInfo->VGAVDE ;
5014 }
5015
5016 pVBInfo->HDE = tempax ;
5017 pVBInfo->VDE = tempbx ;
5018 return ;
5019 }
5020
5021 if ( pVBInfo->VBInfo & ( SetCRT2ToTV ) )
5022 {
5023 tempbx = 4 ;
5024 TVPtr = ( XGI_TVDataStruct * )XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
5025
5026 pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX ;
5027 pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT ;
5028 pVBInfo->VGAHT = TVPtr->VGAHT ;
5029 pVBInfo->VGAVT = TVPtr->VGAVT ;
5030 pVBInfo->HDE = TVPtr->TVHDE ;
5031 pVBInfo->VDE = TVPtr->TVVDE ;
5032 pVBInfo->RVBHRS = TVPtr->RVBHRS ;
5033 pVBInfo->NewFlickerMode = TVPtr->FlickerMode ;
5034
5035 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
5036 {
5037 if ( resinfo == 0x08 )
5038 pVBInfo->NewFlickerMode = 0x40 ;
5039 else if ( resinfo == 0x09 )
5040 pVBInfo->NewFlickerMode = 0x40 ;
5041 else if ( resinfo == 0x12 )
5042 pVBInfo->NewFlickerMode = 0x40 ;
5043
5044 if ( pVBInfo->VGAVDE == 350 )
5045 pVBInfo->TVInfo |= TVSimuMode ;
5046
5047 tempax = ExtHiTVHT ;
5048 tempbx = ExtHiTVVT ;
5049
5050 if ( pVBInfo->VBInfo & SetInSlaveMode )
5051 {
5052 if ( pVBInfo->TVInfo & TVSimuMode )
5053 {
5054 tempax = StHiTVHT ;
5055 tempbx = StHiTVVT ;
5056
5057 if ( !( modeflag & Charx8Dot ) )
5058 {
5059 tempax = StHiTextTVHT ;
5060 tempbx = StHiTextTVVT ;
5061 }
5062 }
5063 }
5064 }
5065 else if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
5066 {
5067 if ( pVBInfo->TVInfo & SetYPbPrMode750p )
5068 {
5069 tempax = YPbPrTV750pHT ; /* Ext750pTVHT */
5070 tempbx = YPbPrTV750pVT ; /* Ext750pTVVT */
5071 }
5072
5073 if ( pVBInfo->TVInfo & SetYPbPrMode525p )
5074 {
5075 tempax = YPbPrTV525pHT ; /* Ext525pTVHT */
5076 tempbx = YPbPrTV525pVT ; /* Ext525pTVVT */
5077 }
5078 else if ( pVBInfo->TVInfo & SetYPbPrMode525i )
5079 {
5080 tempax = YPbPrTV525iHT ; /* Ext525iTVHT */
5081 tempbx = YPbPrTV525iVT ; /* Ext525iTVVT */
5082 if ( pVBInfo->TVInfo & NTSC1024x768 )
5083 tempax = NTSC1024x768HT ;
5084 }
5085 }
5086 else
5087 {
5088 tempax = PALHT ;
5089 tempbx = PALVT ;
5090 if ( !( pVBInfo->TVInfo & SetPALTV ) )
5091 {
5092 tempax = NTSCHT ;
5093 tempbx = NTSCVT ;
5094 if ( pVBInfo->TVInfo & NTSC1024x768 )
5095 tempax = NTSC1024x768HT ;
5096 }
5097 }
5098
5099 pVBInfo->HT = tempax ;
5100 pVBInfo->VT = tempbx ;
5101 return ;
5102 }
5103}
5104
5105
5106/* --------------------------------------------------------------------- */
5107/* Function : XGI_SetCRT2VCLK */
5108/* Input : */
5109/* Output : */
5110/* Description : */
5111/* --------------------------------------------------------------------- */
5112void XGI_SetCRT2VCLK( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
5113{
5114 UCHAR di_0 ,
5115 di_1 ,
5116 tempal ;
5117
5118 tempal = XGI_GetVCLKPtr( RefreshRateTableIndex , ModeNo , ModeIdIndex, pVBInfo ) ;
5119 XGI_GetVCLKLen( tempal, &di_0 , &di_1, pVBInfo ) ;
5120 XGI_GetLCDVCLKPtr( &di_0 , &di_1, pVBInfo ) ;
5121
5122 if ( pVBInfo->VBType & VB_XGI301 ) /* shampoo 0129 */
5123 { /* 301 */
5124 XGINew_SetReg1(pVBInfo->Part4Port , 0x0A , 0x10 ) ;
5125 XGINew_SetReg1(pVBInfo->Part4Port , 0x0B , di_1 ) ;
5126 XGINew_SetReg1(pVBInfo->Part4Port , 0x0A , di_0 ) ;
5127 }
5128 else
5129 { /* 301b/302b/301lv/302lv */
5130 XGINew_SetReg1( pVBInfo->Part4Port , 0x0A , di_0 ) ;
5131 XGINew_SetReg1( pVBInfo->Part4Port , 0x0B , di_1 ) ;
5132 }
5133
5134 XGINew_SetReg1( pVBInfo->Part4Port , 0x00 , 0x12 ) ;
5135
5136 if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
5137 XGINew_SetRegOR( pVBInfo->Part4Port , 0x12 , 0x28 ) ;
5138 else
5139 XGINew_SetRegOR( pVBInfo->Part4Port , 0x12 , 0x08 ) ;
5140}
5141
5142
5143/* --------------------------------------------------------------------- */
5144/* Function : XGI_GETLCDVCLKPtr */
5145/* Input : */
5146/* Output : al -> VCLK Index */
5147/* Description : */
5148/* --------------------------------------------------------------------- */
5149void XGI_GetLCDVCLKPtr( UCHAR* di_0 , UCHAR *di_1, PVB_DEVICE_INFO pVBInfo )
5150{
5151 USHORT index ;
5152
5153 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
5154 {
5155 if ( pVBInfo->IF_DEF_ScaleLCD == 1 )
5156 {
5157 if ( pVBInfo->LCDInfo & EnableScalingLCD )
5158 return ;
5159 }
5160
5161 /* index = XGI_GetLCDCapPtr(pVBInfo) ; */
5162 index = XGI_GetLCDCapPtr1( pVBInfo) ;
5163
5164 if ( pVBInfo->VBInfo & SetCRT2ToLCD )
5165 { /* LCDB */
5166 *di_0 = pVBInfo->LCDCapList[ index ].LCUCHAR_VCLKData1 ;
5167 *di_1 = pVBInfo->LCDCapList[ index ].LCUCHAR_VCLKData2 ;
5168 }
5169 else
5170 { /* LCDA */
5171 *di_0 = pVBInfo->LCDCapList[ index ].LCDA_VCLKData1 ;
5172 *di_1 = pVBInfo->LCDCapList[ index ].LCDA_VCLKData2 ;
5173 }
5174 }
5175 return ;
5176}
5177
5178
5179/* --------------------------------------------------------------------- */
5180/* Function : XGI_GetVCLKPtr */
5181/* Input : */
5182/* Output : */
5183/* Description : */
5184/* --------------------------------------------------------------------- */
5185UCHAR XGI_GetVCLKPtr(USHORT RefreshRateTableIndex,USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
5186{
5187
5188 USHORT index ,
5189 modeflag ;
5190#ifndef LINUX_XF86
5191 USHORT tempbx ;
5192#endif
5193
5194 UCHAR tempal ;
5195 UCHAR *CHTVVCLKPtr = NULL ;
5196
5197 if ( ModeNo <= 0x13 )
5198 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
5199 else
5200 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
5201
5202
5203 if ( ( pVBInfo->SetFlag & ProgrammingCRT2 ) && ( !( pVBInfo->LCDInfo & EnableScalingLCD ) ) )
5204 { /* {LCDA/LCDB} */
5205 index = XGI_GetLCDCapPtr(pVBInfo) ;
5206 tempal = pVBInfo->LCDCapList[ index ].LCD_VCLK ;
5207
5208 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
5209 return tempal ;
5210
5211 /* {TV} */
5212 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV| VB_XGI302LV| VB_XGI301C ) )
5213 {
5214 if(pVBInfo->VBInfo&SetCRT2ToHiVisionTV)
5215 {
5216 tempal = HiTVVCLKDIV2;
5217 if(!(pVBInfo->TVInfo & RPLLDIV2XO))
5218 tempal = HiTVVCLK;
5219 if(pVBInfo->TVInfo & TVSimuMode)
5220 {
5221 tempal = HiTVSimuVCLK;
5222 if(!(modeflag & Charx8Dot))
5223 tempal = HiTVTextVCLK;
5224
5225 }
5226 return tempal;
5227 }
5228
5229 if ( pVBInfo->TVInfo & SetYPbPrMode750p )
5230 {
5231 tempal = YPbPr750pVCLK ;
5232 return tempal ;
5233 }
5234
5235 if ( pVBInfo->TVInfo & SetYPbPrMode525p )
5236 {
5237 tempal = YPbPr525pVCLK ;
5238 return tempal ;
5239 }
5240
5241 tempal = NTSC1024VCLK ;
5242
5243 if ( !( pVBInfo->TVInfo & NTSC1024x768 ) )
5244 {
5245 tempal = TVVCLKDIV2 ;
5246 if ( !( pVBInfo->TVInfo & RPLLDIV2XO ) )
5247 tempal = TVVCLK ;
5248 }
5249
5250 if ( pVBInfo->VBInfo & SetCRT2ToTV )
5251 return tempal ;
5252 }
5253 /*else
5254 if((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017))
5255 {
5256 if(ModeNo<=0x13)
5257 *tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5258 else
5259 *tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5260 *tempal = *tempal & 0x1F;
5261
5262 tempbx = 0;
5263 if(pVBInfo->TVInfo & SetPALTV)
5264 tempbx = tempbx + 2;
5265 if(pVBInfo->TVInfo & SetCHTVOverScan)
5266 tempbx++;
5267 tempbx = tempbx << 1;
5268 } */
5269 } /* {End of VB} */
5270
5271 if((pVBInfo->IF_DEF_CH7007==1)&&(pVBInfo->VBType&VB_CH7007)) /* [Billy] 07/05/08 CH7007 */
5272 {
5273 /* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
5274 if ( (pVBInfo->VBInfo & SetCRT2ToTV) )
5275 {
5276 if( ModeNo <= 0x13 )
5277 {
5278 tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
5279 }
5280 else
5281 {
5282 tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5283 }
5284
5285 tempal = tempal & 0x0F;
5286 tempbx = 0;
5287
5288 if(pVBInfo->TVInfo & SetPALTV)
5289 {
5290 tempbx = tempbx + 2;
5291 }
5292 if(pVBInfo->TVInfo & SetCHTVOverScan)
5293 {
5294 tempbx++;
5295 }
5296 /** tempbx = tempbx << 1; CH7007 ? **/
5297
5298/*[Billy]07/05/29 CH7007*/
5299 if ( pVBInfo->IF_DEF_CH7007 == 1 )
5300 {
5301 switch( tempbx )
5302 {
5303 case 0:
5304 CHTVVCLKPtr = XGI7007_CHTVVCLKUNTSC ;
5305 break ;
5306 case 1:
5307 CHTVVCLKPtr = XGI7007_CHTVVCLKONTSC ;
5308 break ;
5309 case 2:
5310 CHTVVCLKPtr = XGI7007_CHTVVCLKUPAL ;
5311 break ;
5312 case 3:
5313 CHTVVCLKPtr = XGI7007_CHTVVCLKOPAL ;
5314 break ;
5315 default:
5316 break ;
5317
5318 }
5319 }
5320 /*else
5321 {
5322 switch( tempbx )
5323 {
5324 case 0:
5325 CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC ;
5326 break ;
5327 case 1:
5328 CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC ;
5329 break ;
5330 case 2:
5331 CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL ;
5332 break ;
5333 case 3:
5334 CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL ;
5335 break ;
5336 default:
5337 break ;
5338 }
5339 }*/
5340
5341 tempal = CHTVVCLKPtr[ tempal ] ;
5342 return tempal ;
5343 }
5344
5345 }
5346
5347 tempal = ( UCHAR )XGINew_GetReg2( ( pVBInfo->P3ca + 0x02 ) ) ;
5348 tempal = tempal >> 2 ;
5349 tempal &= 0x03 ;
5350
5351 if ( ( pVBInfo->LCDInfo & EnableScalingLCD ) && ( modeflag & Charx8Dot ) ) /* for Dot8 Scaling LCD */
5352 tempal = tempal ^ tempal ; /* ; set to VCLK25MHz always */
5353
5354 if ( ModeNo <= 0x13 )
5355 return tempal ;
5356
5357 tempal = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
5358 return tempal ;
5359}
5360
5361
5362/* --------------------------------------------------------------------- */
5363/* Function : XGI_GetVCLKLen */
5364/* Input : */
5365/* Output : */
5366/* Description : */
5367/* --------------------------------------------------------------------- */
5368void XGI_GetVCLKLen(UCHAR tempal,UCHAR* di_0,UCHAR* di_1, PVB_DEVICE_INFO pVBInfo)
5369{
5370 if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 2007/05/16 */
5371 {
5372 /* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
5373 *di_0 = ( UCHAR )XGI_CH7007VCLKData[ tempal ].SR2B ;
5374 *di_1 = ( UCHAR )XGI_CH7007VCLKData[ tempal ].SR2C ;
5375 }
5376 else if ( pVBInfo->VBType & ( VB_XGI301 | VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
5377 {
5378 if ( ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) && ( pVBInfo->SetFlag & ProgrammingCRT2 ) )
5379 {
5380 *di_0 = ( UCHAR )XGI_VBVCLKData[ tempal ].SR2B ;
5381 *di_1 = XGI_VBVCLKData[ tempal ].SR2C ;
5382 }
5383 }
5384 else
5385 {
5386 *di_0 = XGI_VCLKData[ tempal ].SR2B ;
5387 *di_1 = XGI_VCLKData[ tempal ].SR2C ;
5388 }
5389}
5390
5391
5392/* --------------------------------------------------------------------- */
5393/* Function : XGI_SetCRT2Offset */
5394/* Input : */
5395/* Output : */
5396/* Description : */
5397/* --------------------------------------------------------------------- */
5398void XGI_SetCRT2Offset( USHORT ModeNo ,
5399 USHORT ModeIdIndex , USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
5400{
5401 USHORT offset ;
5402 UCHAR temp ;
5403
5404 if ( pVBInfo->VBInfo & SetInSlaveMode )
5405 {
5406 return ;
5407 }
5408
5409 offset = XGI_GetOffset( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
5410 temp = ( UCHAR )( offset & 0xFF ) ;
5411 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , temp ) ;
5412 temp =( UCHAR)( ( offset & 0xFF00 ) >> 8 ) ;
5413 XGINew_SetReg1( pVBInfo->Part1Port , 0x09 , temp ) ;
5414 temp =( UCHAR )( ( ( offset >> 3 ) & 0xFF ) + 1 ) ;
5415 XGINew_SetReg1( pVBInfo->Part1Port , 0x03 , temp ) ;
5416}
5417
5418
5419/* --------------------------------------------------------------------- */
5420/* Function : XGI_GetOffset */
5421/* Input : */
5422/* Output : */
5423/* Description : */
5424/* --------------------------------------------------------------------- */
5425USHORT XGI_GetOffset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo)
5426{
5427 USHORT temp ,
5428 colordepth ,
5429 modeinfo ,
5430 index ,
5431 infoflag ,
5432 ColorDepth[] = { 0x01 , 0x02 , 0x04 } ;
5433
5434 modeinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeInfo ;
5435 if ( ModeNo <= 0x14 )
5436 infoflag = 0 ;
5437 else
5438 infoflag = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
5439
5440
5441 index = ( modeinfo >> 8 ) & 0xFF ;
5442
5443 temp = pVBInfo->ScreenOffset[ index ] ;
5444
5445 if ( infoflag & InterlaceMode )
5446 {
5447 temp = temp << 1 ;
5448 }
5449
5450 colordepth = XGI_GetColorDepth( ModeNo , ModeIdIndex, pVBInfo ) ;
5451
5452 if ( ( ModeNo >= 0x7C ) && ( ModeNo <= 0x7E ) )
5453 {
5454 temp = ModeNo - 0x7C ;
5455 colordepth = ColorDepth[ temp ] ;
5456 temp = 0x6B ;
5457 if ( infoflag & InterlaceMode )
5458 {
5459 temp = temp << 1 ;
5460 }
5461 return( temp * colordepth ) ;
5462 }
5463 else
5464 return( temp * colordepth ) ;
5465}
5466
5467
5468/* --------------------------------------------------------------------- */
5469/* Function : XGI_SetCRT2FIFO */
5470/* Input : */
5471/* Output : */
5472/* Description : */
5473/* --------------------------------------------------------------------- */
5474void XGI_SetCRT2FIFO( PVB_DEVICE_INFO pVBInfo)
5475{
5476 XGINew_SetReg1( pVBInfo->Part1Port , 0x01 , 0x3B ) ; /* threshold high ,disable auto threshold */
5477 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x02 , ~( 0x3F ) , 0x04 ) ; /* threshold low default 04h */
5478}
5479
5480
5481/* --------------------------------------------------------------------- */
5482/* Function : XGI_PreSetGroup1 */
5483/* Input : */
5484/* Output : */
5485/* Description : */
5486/* --------------------------------------------------------------------- */
5487void XGI_PreSetGroup1(USHORT ModeNo , USHORT ModeIdIndex ,PXGI_HW_DEVICE_INFO HwDeviceExtension,
5488 USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
5489{
5490 USHORT tempcx = 0 ,
5491 CRT1Index = 0 ,
5492 resinfo = 0 ;
5493
5494 if ( ModeNo > 0x13 )
5495 {
5496 CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
5497 CRT1Index &= IndexMask ;
5498 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
5499 }
5500
5501 XGI_SetCRT2Offset( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
5502 XGI_SetCRT2FIFO(pVBInfo) ;
5503 /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
5504
5505 for( tempcx = 4 ; tempcx < 7 ; tempcx++ )
5506 {
5507 XGINew_SetReg1( pVBInfo->Part1Port , tempcx , 0x0 ) ;
5508 }
5509
5510 XGINew_SetReg1( pVBInfo->Part1Port , 0x50 , 0x00 ) ;
5511 XGINew_SetReg1( pVBInfo->Part1Port , 0x02 , 0x44 ) ; /* temp 0206 */
5512}
5513
5514
5515/* --------------------------------------------------------------------- */
5516/* Function : XGI_SetGroup1 */
5517/* Input : */
5518/* Output : */
5519/* Description : */
5520/* --------------------------------------------------------------------- */
5521void XGI_SetGroup1( USHORT ModeNo , USHORT ModeIdIndex ,
5522 PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
5523{
5524 USHORT temp = 0 ,
5525 tempax = 0 ,
5526 tempbx = 0 ,
5527 tempcx = 0 ,
5528 pushbx = 0 ,
5529 CRT1Index = 0 ,
5530 modeflag ,
5531 resinfo = 0 ;
5532
5533 if ( ModeNo > 0x13 )
5534 {
5535 CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
5536 CRT1Index &= IndexMask ;
5537 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
5538 }
5539
5540 if ( ModeNo <= 0x13 )
5541 {
5542 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
5543 }
5544 else
5545 {
5546 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
5547 }
5548
5549 /* bainy change table name */
5550 if ( modeflag & HalfDCLK )
5551 {
5552 temp = ( pVBInfo->VGAHT / 2 - 1 ) & 0x0FF ; /* BTVGA2HT 0x08,0x09 */
5553 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , temp ) ;
5554 temp = ( ( ( pVBInfo->VGAHT / 2 - 1 ) & 0xFF00 ) >> 8 ) << 4 ;
5555 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x09 , ~0x0F0 , temp ) ;
5556 temp = ( pVBInfo->VGAHDE / 2 + 16 ) & 0x0FF ; /* BTVGA2HDEE 0x0A,0x0C */
5557 XGINew_SetReg1( pVBInfo->Part1Port , 0x0A , temp ) ;
5558 tempcx = ( ( pVBInfo->VGAHT - pVBInfo->VGAHDE ) / 2 ) >> 2 ;
5559 pushbx = pVBInfo->VGAHDE / 2 + 16 ;
5560 tempcx = tempcx >> 1 ;
5561 tempbx = pushbx + tempcx ; /* bx BTVGA@HRS 0x0B,0x0C */
5562 tempcx += tempbx ;
5563
5564 if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
5565 {
5566 tempbx = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 4 ] ;
5567 tempbx |= ( ( pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 14 ] & 0xC0 ) << 2 ) ;
5568 tempbx = ( tempbx - 3 ) << 3 ; /* (VGAHRS-3)*8 */
5569 tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[ 5 ] ;
5570 tempcx &= 0x1F ;
5571 temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 15 ] ;
5572 temp = ( temp & 0x04 ) << ( 5 - 2 ) ; /* VGAHRE D[5] */
5573 tempcx = ( ( tempcx | temp ) - 3 ) << 3 ; /* (VGAHRE-3)*8 */
5574 }
5575
5576 tempbx += 4 ;
5577 tempcx += 4 ;
5578
5579 if ( tempcx > ( pVBInfo->VGAHT / 2 ) )
5580 tempcx = pVBInfo->VGAHT / 2 ;
5581
5582 temp = tempbx & 0x00FF ;
5583
5584 XGINew_SetReg1( pVBInfo->Part1Port , 0x0B , temp ) ;
5585 }
5586 else
5587 {
5588 temp = ( pVBInfo->VGAHT - 1 ) & 0x0FF ; /* BTVGA2HT 0x08,0x09 */
5589 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , temp ) ;
5590 temp = ( ( ( pVBInfo->VGAHT - 1 ) & 0xFF00 ) >> 8 ) << 4 ;
5591 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x09 , ~0x0F0 , temp ) ;
5592 temp = ( pVBInfo->VGAHDE + 16 ) & 0x0FF ; /* BTVGA2HDEE 0x0A,0x0C */
5593 XGINew_SetReg1( pVBInfo->Part1Port , 0x0A , temp ) ;
5594 tempcx = ( pVBInfo->VGAHT - pVBInfo->VGAHDE ) >> 2 ; /* cx */
5595 pushbx = pVBInfo->VGAHDE + 16 ;
5596 tempcx = tempcx >> 1 ;
5597 tempbx = pushbx + tempcx ; /* bx BTVGA@HRS 0x0B,0x0C */
5598 tempcx += tempbx ;
5599
5600 if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
5601 {
5602 tempbx = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 3 ] ;
5603 tempbx |= ( ( pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 5 ] & 0xC0 ) << 2 ) ;
5604 tempbx = ( tempbx - 3 ) << 3 ; /* (VGAHRS-3)*8 */
5605 tempcx = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 4 ] ;
5606 tempcx &= 0x1F ;
5607 temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 6 ] ;
5608 temp = ( temp & 0x04 ) << ( 5 - 2 ) ; /* VGAHRE D[5] */
5609 tempcx = ( ( tempcx | temp ) - 3 ) << 3 ; /* (VGAHRE-3)*8 */
5610 tempbx += 16 ;
5611 tempcx += 16 ;
5612 }
5613
5614 if ( tempcx > pVBInfo->VGAHT )
5615 tempcx = pVBInfo->VGAHT ;
5616
5617 temp = tempbx & 0x00FF ;
5618 XGINew_SetReg1( pVBInfo->Part1Port , 0x0B , temp ) ;
5619 }
5620
5621 tempax = ( tempax & 0x00FF ) | ( tempbx & 0xFF00 ) ;
5622 tempbx = pushbx ;
5623 tempbx = ( tempbx & 0x00FF ) | ( ( tempbx & 0xFF00 ) << 4 ) ;
5624 tempax |= ( tempbx & 0xFF00 ) ;
5625 temp = ( tempax & 0xFF00 ) >> 8 ;
5626 XGINew_SetReg1( pVBInfo->Part1Port , 0x0C , temp ) ;
5627 temp = tempcx & 0x00FF ;
5628 XGINew_SetReg1( pVBInfo->Part1Port , 0x0D , temp ) ;
5629 tempcx = ( pVBInfo->VGAVT - 1 ) ;
5630 temp = tempcx & 0x00FF ;
5631
5632 if ( pVBInfo->IF_DEF_CH7005 == 1 )
5633 {
5634 if ( pVBInfo->VBInfo & 0x0C )
5635 {
5636 temp-- ;
5637 }
5638 }
5639
5640 XGINew_SetReg1( pVBInfo->Part1Port , 0x0E , temp ) ;
5641 tempbx = pVBInfo->VGAVDE - 1 ;
5642 temp = tempbx & 0x00FF ;
5643 XGINew_SetReg1( pVBInfo->Part1Port , 0x0F , temp ) ;
5644 temp = ( ( tempbx & 0xFF00 ) << 3 ) >> 8 ;
5645 temp |= ( ( tempcx & 0xFF00 ) >> 8 ) ;
5646 XGINew_SetReg1( pVBInfo->Part1Port , 0x12 , temp ) ;
5647
5648 tempax = pVBInfo->VGAVDE ;
5649 tempbx = pVBInfo->VGAVDE ;
5650 tempcx = pVBInfo->VGAVT ;
5651 tempbx = ( pVBInfo->VGAVT + pVBInfo->VGAVDE ) >> 1 ; /* BTVGA2VRS 0x10,0x11 */
5652 tempcx = ( ( pVBInfo->VGAVT - pVBInfo->VGAVDE ) >> 4 ) + tempbx + 1 ; /* BTVGA2VRE 0x11 */
5653
5654 if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
5655 {
5656 tempbx = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 10 ] ;
5657 temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 9 ] ;
5658
5659 if ( temp & 0x04 )
5660 tempbx |= 0x0100 ;
5661
5662 if ( temp & 0x080 )
5663 tempbx |= 0x0200 ;
5664
5665 temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 14 ] ;
5666
5667 if ( temp & 0x08 )
5668 tempbx |= 0x0400 ;
5669
5670 temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 11 ] ;
5671 tempcx = ( tempcx & 0xFF00 ) | ( temp & 0x00FF ) ;
5672 }
5673
5674 temp = tempbx & 0x00FF ;
5675 XGINew_SetReg1( pVBInfo->Part1Port , 0x10 , temp ) ;
5676 temp = ( ( tempbx & 0xFF00 ) >> 8 ) << 4 ;
5677 temp = ( ( tempcx & 0x000F ) | ( temp ) ) ;
5678 XGINew_SetReg1( pVBInfo->Part1Port , 0x11 , temp ) ;
5679 tempax = 0 ;
5680
5681 if ( modeflag & DoubleScanMode )
5682 tempax |= 0x80 ;
5683
5684 if ( modeflag & HalfDCLK )
5685 tempax |= 0x40 ;
5686
5687 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2C , ~0x0C0 , tempax ) ;
5688}
5689
5690
5691/* --------------------------------------------------------------------- */
5692/* Function : XGI_SetLockRegs */
5693/* Input : */
5694/* Output : */
5695/* Description : */
5696/* --------------------------------------------------------------------- */
5697void XGI_SetLockRegs( USHORT ModeNo , USHORT ModeIdIndex ,
5698 PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
5699{
5700 USHORT push1 ,
5701 push2 ,
5702 tempax ,
5703 tempbx = 0 ,
5704 tempcx ,
5705 temp ,
5706 resinfo ,
5707 modeflag ,
5708 CRT1Index ;
5709
5710 if ( ModeNo <= 0x13 )
5711 {
5712 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
5713 resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
5714 }
5715 else
5716 {
5717 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
5718 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
5719 CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
5720 CRT1Index &= IndexMask;
5721 }
5722
5723 if ( !( pVBInfo->VBInfo & SetInSlaveMode ) )
5724 {
5725 return ;
5726 }
5727
5728 temp = 0xFF ; /* set MAX HT */
5729 XGINew_SetReg1( pVBInfo->Part1Port , 0x03 , temp ) ;
5730 /* if ( modeflag & Charx8Dot ) tempcx = 0x08 ; */
5731 /* else */
5732 tempcx=0x08;
5733
5734 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
5735 modeflag |= Charx8Dot ;
5736
5737 tempax = pVBInfo->VGAHDE ; /* 0x04 Horizontal Display End */
5738
5739 if ( modeflag & HalfDCLK )
5740 tempax = tempax >> 1 ;
5741
5742 tempax = ( tempax / tempcx ) - 1 ;
5743 tempbx |= ( ( tempax & 0x00FF ) << 8 ) ;
5744 temp = tempax & 0x00FF ;
5745 XGINew_SetReg1( pVBInfo->Part1Port , 0x04 , temp ) ;
5746
5747 temp = ( tempbx & 0xFF00 ) >> 8 ;
5748
5749 if ( pVBInfo->VBInfo & SetCRT2ToTV )
5750 {
5751 if ( !( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) ) )
5752 temp += 2 ;
5753
5754 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
5755 {
5756 if ( pVBInfo->VBType & VB_XGI301LV )
5757 {
5758 if ( pVBInfo->VBExtInfo == VB_YPbPr1080i )
5759 {
5760 if ( resinfo == 7 )
5761 temp -= 2 ;
5762 }
5763 }
5764 else
5765 if ( resinfo == 7 )
5766 temp -= 2 ;
5767 }
5768 }
5769
5770 XGINew_SetReg1( pVBInfo->Part1Port , 0x05 , temp ) ; /* 0x05 Horizontal Display Start */
5771 XGINew_SetReg1( pVBInfo->Part1Port , 0x06 , 0x03 ) ; /* 0x06 Horizontal Blank end */
5772
5773 if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
5774 { /* 030226 bainy */
5775 if ( pVBInfo->VBInfo & SetCRT2ToTV )
5776 tempax = pVBInfo->VGAHT ;
5777 else
5778 tempax = XGI_GetVGAHT2( pVBInfo) ;
5779 }
5780
5781 if ( tempax >= pVBInfo->VGAHT )
5782 {
5783 tempax = pVBInfo->VGAHT ;
5784 }
5785
5786 if ( modeflag & HalfDCLK )
5787 {
5788 tempax = tempax >> 1 ;
5789 }
5790
5791 tempax = ( tempax / tempcx ) - 5 ;
5792 tempcx = tempax ; /* 20030401 0x07 horizontal Retrace Start */
5793 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
5794 {
5795 temp = ( tempbx & 0x00FF ) - 1 ;
5796 if ( !( modeflag & HalfDCLK ) )
5797 {
5798 temp -= 6 ;
5799 if ( pVBInfo->TVInfo & TVSimuMode )
5800 {
5801 temp -= 4 ;
5802 if ( ModeNo > 0x13 )
5803 temp -= 10 ;
5804 }
5805 }
5806 }
5807 else
5808 {
5809 /* tempcx = tempbx & 0x00FF ; */
5810 tempbx = ( tempbx & 0xFF00 ) >> 8 ;
5811 tempcx = ( tempcx + tempbx ) >> 1 ;
5812 temp = ( tempcx & 0x00FF ) + 2 ;
5813
5814 if ( pVBInfo->VBInfo & SetCRT2ToTV )
5815 {
5816 temp -= 1 ;
5817 if ( !( modeflag & HalfDCLK ) )
5818 {
5819 if ( ( modeflag & Charx8Dot ) )
5820 {
5821 temp += 4 ;
5822 if ( pVBInfo->VGAHDE >= 800 )
5823 {
5824 temp -= 6 ;
5825 }
5826 }
5827 }
5828 }
5829 else
5830 {
5831 if ( !( modeflag & HalfDCLK ) )
5832 {
5833 temp -= 4 ;
5834 if ( pVBInfo->LCDResInfo != Panel1280x960 )
5835 {
5836 if( pVBInfo->VGAHDE >= 800 )
5837 {
5838 temp -= 7 ;
5839 if ( pVBInfo->ModeType == ModeEGA )
5840 {
5841 if ( pVBInfo->VGAVDE == 1024 )
5842 {
5843 temp += 15 ;
5844 if ( pVBInfo->LCDResInfo != Panel1280x1024 )
5845 {
5846 temp += 7 ;
5847 }
5848 }
5849 }
5850
5851 if ( pVBInfo->VGAHDE >= 1280 )
5852 {
5853 if ( pVBInfo->LCDResInfo != Panel1280x960 )
5854 {
5855 if ( pVBInfo->LCDInfo & LCDNonExpanding )
5856 {
5857 temp += 28 ;
5858 }
5859 }
5860 }
5861 }
5862 }
5863 }
5864 }
5865 }
5866
5867 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , temp ) ; /* 0x07 Horizontal Retrace Start */
5868 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0 ) ; /* 0x08 Horizontal Retrace End */
5869
5870 if ( pVBInfo->VBInfo & SetCRT2ToTV )
5871 {
5872 if ( pVBInfo->TVInfo & TVSimuMode )
5873 {
5874 if ( ( ModeNo == 0x06 ) || ( ModeNo == 0x10 ) || ( ModeNo == 0x11 ) || ( ModeNo == 0x13 ) || ( ModeNo == 0x0F ) )
5875 {
5876 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x5b ) ;
5877 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x03 ) ;
5878 }
5879
5880 if ( ( ModeNo == 0x00 ) || ( ModeNo == 0x01 ) )
5881 {
5882 if ( pVBInfo->TVInfo & SetNTSCTV )
5883 {
5884 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x2A ) ;
5885 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x61 ) ;
5886 }
5887 else
5888 {
5889 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x2A ) ;
5890 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x41 ) ;
5891 XGINew_SetReg1( pVBInfo->Part1Port , 0x0C , 0xF0 ) ;
5892 }
5893 }
5894
5895 if ( ( ModeNo == 0x02 ) || ( ModeNo == 0x03 ) || ( ModeNo == 0x07 ) )
5896 {
5897 if ( pVBInfo->TVInfo & SetNTSCTV )
5898 {
5899 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x54 ) ;
5900 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x00 ) ;
5901 }
5902 else
5903 {
5904 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x55 ) ;
5905 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x00 ) ;
5906 XGINew_SetReg1( pVBInfo->Part1Port , 0x0C , 0xF0 ) ;
5907 }
5908 }
5909
5910 if ( ( ModeNo == 0x04 ) || ( ModeNo == 0x05 ) || ( ModeNo == 0x0D ) || ( ModeNo == 0x50 ) )
5911 {
5912 if ( pVBInfo->TVInfo & SetNTSCTV )
5913 {
5914 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x30 ) ;
5915 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x03 ) ;
5916 }
5917 else
5918 {
5919 XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x2f ) ;
5920 XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x02 ) ;
5921 }
5922 }
5923 }
5924 }
5925
5926 XGINew_SetReg1( pVBInfo->Part1Port , 0x18 , 0x03 ) ; /* 0x18 SR0B */
5927 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x19 , 0xF0 , 0x00 ) ;
5928 XGINew_SetReg1( pVBInfo->Part1Port , 0x09 , 0xFF ) ; /* 0x09 Set Max VT */
5929
5930 tempbx = pVBInfo->VGAVT ;
5931 push1 = tempbx ;
5932 tempcx = 0x121 ;
5933 tempbx = pVBInfo->VGAVDE ; /* 0x0E Virtical Display End */
5934
5935 if ( tempbx == 357 )
5936 tempbx = 350 ;
5937 if ( tempbx == 360 )
5938 tempbx =350 ;
5939 if ( tempbx == 375 )
5940 tempbx = 350 ;
5941 if ( tempbx == 405 )
5942 tempbx = 400 ;
5943 if ( tempbx == 525 )
5944 tempbx = 480 ;
5945
5946 push2 = tempbx ;
5947
5948 if ( pVBInfo->VBInfo & SetCRT2ToLCD )
5949 {
5950 if ( pVBInfo->LCDResInfo == Panel1024x768 )
5951 {
5952 if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
5953 {
5954 if ( tempbx == 350 )
5955 tempbx += 5 ;
5956 if ( tempbx == 480 )
5957 tempbx += 5 ;
5958 }
5959 }
5960 }
5961 tempbx-- ;
5962 temp = tempbx & 0x00FF ;
5963 tempbx-- ;
5964 temp = tempbx & 0x00FF ;
5965 XGINew_SetReg1( pVBInfo->Part1Port , 0x10 ,temp ) ; /* 0x10 vertical Blank Start */
5966 tempbx = push2 ;
5967 tempbx-- ;
5968 temp = tempbx & 0x00FF ;
5969 XGINew_SetReg1( pVBInfo->Part1Port , 0x0E , temp ) ;
5970
5971 if ( tempbx & 0x0100 )
5972 {
5973 tempcx |= 0x0002 ;
5974 }
5975
5976 tempax = 0x000B ;
5977
5978 if ( modeflag & DoubleScanMode )
5979 {
5980 tempax |= 0x08000 ;
5981 }
5982
5983 if ( tempbx & 0x0200 )
5984 {
5985 tempcx |= 0x0040 ;
5986 }
5987
5988 temp = ( tempax & 0xFF00 ) >> 8 ;
5989 XGINew_SetReg1( pVBInfo->Part1Port , 0x0B , temp ) ;
5990
5991 if ( tempbx & 0x0400 )
5992 {
5993 tempcx |= 0x0600 ;
5994 }
5995
5996 XGINew_SetReg1( pVBInfo->Part1Port , 0x11 , 0x00 ) ; /* 0x11 Vertival Blank End */
5997
5998 tempax = push1 ;
5999 tempax -= tempbx ; /* 0x0C Vertical Retrace Start */
6000 tempax = tempax >> 2 ;
6001 push1 = tempax ; /* push ax */
6002
6003 if ( resinfo != 0x09 )
6004 {
6005 tempax = tempax << 1 ;
6006 tempbx += tempax ;
6007 }
6008
6009 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6010 {
6011 if ( pVBInfo->VBType & VB_XGI301LV )
6012 {
6013 if ( pVBInfo->TVInfo & SetYPbPrMode1080i )
6014 tempbx -= 10 ;
6015 else
6016 {
6017 if ( pVBInfo->TVInfo & TVSimuMode )
6018 {
6019 if ( pVBInfo->TVInfo & SetPALTV )
6020 {
6021 if ( pVBInfo->VBType & VB_XGI301LV )
6022 {
6023 if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
6024 tempbx += 40 ;
6025 }
6026 else
6027 tempbx += 40 ;
6028 }
6029 }
6030 }
6031 }
6032 else
6033 tempbx -= 10 ;
6034 }
6035 else
6036 {
6037 if ( pVBInfo->TVInfo & TVSimuMode )
6038 {
6039 if ( pVBInfo->TVInfo & SetPALTV )
6040 {
6041 if ( pVBInfo->VBType & VB_XGI301LV )
6042 {
6043 if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
6044 tempbx += 40 ;
6045 }
6046 else
6047 tempbx += 40 ;
6048 }
6049 }
6050 }
6051 tempax = push1 ;
6052 tempax = tempax >> 2 ;
6053 tempax++ ;
6054 tempax += tempbx ;
6055 push1 = tempax ; /* push ax */
6056
6057 if ( ( pVBInfo->TVInfo & SetPALTV ) )
6058 {
6059 if ( tempbx <= 513 )
6060 {
6061 if ( tempax >= 513 )
6062 {
6063 tempbx = 513 ;
6064 }
6065 }
6066 }
6067
6068 temp = tempbx & 0x00FF ;
6069 XGINew_SetReg1( pVBInfo->Part1Port , 0x0C , temp ) ;
6070 tempbx-- ;
6071 temp = tempbx & 0x00FF ;
6072 XGINew_SetReg1( pVBInfo->Part1Port , 0x10 , temp ) ;
6073
6074 if ( tempbx & 0x0100 )
6075 {
6076 tempcx |= 0x0008 ;
6077 }
6078
6079 if ( tempbx & 0x0200 )
6080 {
6081 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x0B , 0x0FF , 0x20 ) ;
6082 }
6083
6084 tempbx++ ;
6085
6086 if ( tempbx & 0x0100 )
6087 {
6088 tempcx |= 0x0004 ;
6089 }
6090
6091 if ( tempbx & 0x0200 )
6092 {
6093 tempcx |= 0x0080 ;
6094 }
6095
6096 if ( tempbx & 0x0400 )
6097 {
6098 tempcx |= 0x0C00 ;
6099 }
6100
6101 tempbx = push1 ; /* pop ax */
6102 temp = tempbx & 0x00FF ;
6103 temp &= 0x0F ;
6104 XGINew_SetReg1( pVBInfo->Part1Port , 0x0D , temp ) ; /* 0x0D vertical Retrace End */
6105
6106 if ( tempbx & 0x0010 )
6107 {
6108 tempcx |= 0x2000 ;
6109 }
6110
6111 temp = tempcx & 0x00FF ;
6112 XGINew_SetReg1( pVBInfo->Part1Port , 0x0A , temp ) ; /* 0x0A CR07 */
6113 temp = ( tempcx & 0x0FF00 ) >> 8 ;
6114 XGINew_SetReg1( pVBInfo->Part1Port , 0x17 , temp ) ; /* 0x17 SR0A */
6115 tempax = modeflag ;
6116 temp = ( tempax & 0xFF00 ) >> 8 ;
6117
6118 temp = ( temp >> 1 ) & 0x09 ;
6119
6120 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
6121 temp |= 0x01 ;
6122
6123 XGINew_SetReg1( pVBInfo->Part1Port , 0x16 , temp ) ; /* 0x16 SR01 */
6124 XGINew_SetReg1( pVBInfo->Part1Port , 0x0F , 0 ) ; /* 0x0F CR14 */
6125 XGINew_SetReg1( pVBInfo->Part1Port , 0x12 , 0 ) ; /* 0x12 CR17 */
6126
6127 if ( pVBInfo->LCDInfo & LCDRGB18Bit )
6128 temp = 0x80 ;
6129 else
6130 temp = 0x00 ;
6131
6132 XGINew_SetReg1( pVBInfo->Part1Port , 0x1A , temp ) ; /* 0x1A SR0E */
6133
6134 return ;
6135}
6136
6137
6138/* --------------------------------------------------------------------- */
6139/* Function : XGI_SetGroup2 */
6140/* Input : */
6141/* Output : */
6142/* Description : */
6143/* --------------------------------------------------------------------- */
6144void XGI_SetGroup2( USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6145 PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
6146{
6147 USHORT i ,
6148 j ,
6149 tempax ,
6150 tempbx ,
6151 tempcx ,
6152 temp ,
6153 push1 ,
6154 push2 ,
6155 modeflag ,
6156 resinfo ,
6157 crt2crtc ;
6158 UCHAR *TimingPoint ;
6159
6160 ULONG longtemp ,
6161 tempeax ,
6162 tempebx ,
6163 temp2 ,
6164 tempecx ;
6165
6166 if ( ModeNo <= 0x13 )
6167 {
6168 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
6169 resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
6170 crt2crtc = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
6171 }
6172 else
6173 {
6174 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
6175 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
6176 crt2crtc = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
6177 }
6178
6179 tempax = 0 ;
6180
6181 if ( !( pVBInfo->VBInfo & SetCRT2ToAVIDEO ) )
6182 tempax |= 0x0800 ;
6183
6184 if ( !( pVBInfo->VBInfo & SetCRT2ToSVIDEO ) )
6185 tempax |= 0x0400 ;
6186
6187 if ( pVBInfo->VBInfo & SetCRT2ToSCART )
6188 tempax |= 0x0200 ;
6189
6190 if ( !( pVBInfo->TVInfo & SetPALTV ) )
6191 tempax |= 0x1000 ;
6192
6193 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6194 tempax |= 0x0100 ;
6195
6196 if ( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
6197 tempax &= 0xfe00 ;
6198
6199 tempax = ( tempax & 0xff00 ) >> 8 ;
6200
6201 XGINew_SetReg1( pVBInfo->Part2Port , 0x0 , tempax ) ;
6202 TimingPoint = pVBInfo->NTSCTiming ;
6203
6204 if ( pVBInfo->TVInfo & SetPALTV )
6205 {
6206 TimingPoint = pVBInfo->PALTiming ;
6207 }
6208
6209 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6210 {
6211 TimingPoint = pVBInfo->HiTVExtTiming ;
6212
6213 if ( pVBInfo->VBInfo & SetInSlaveMode )
6214 TimingPoint = pVBInfo->HiTVSt2Timing ;
6215
6216 if ( pVBInfo->SetFlag & TVSimuMode )
6217 TimingPoint = pVBInfo->HiTVSt1Timing ;
6218
6219 if ( !(modeflag & Charx8Dot) )
6220 TimingPoint = pVBInfo->HiTVTextTiming ;
6221 }
6222
6223 if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
6224 {
6225 if ( pVBInfo->TVInfo & SetYPbPrMode525i )
6226 TimingPoint = pVBInfo->YPbPr525iTiming ;
6227
6228 if ( pVBInfo->TVInfo & SetYPbPrMode525p )
6229 TimingPoint = pVBInfo->YPbPr525pTiming ;
6230
6231 if ( pVBInfo->TVInfo & SetYPbPrMode750p )
6232 TimingPoint = pVBInfo->YPbPr750pTiming ;
6233 }
6234
6235 for( i = 0x01 , j = 0 ; i <= 0x2D ; i++ , j++ )
6236 {
6237 XGINew_SetReg1( pVBInfo->Part2Port , i , TimingPoint[ j ] ) ;
6238 }
6239
6240 for( i = 0x39 ; i <= 0x45 ; i++ , j++ )
6241 {
6242 XGINew_SetReg1( pVBInfo->Part2Port , i , TimingPoint[ j ] ) ; /* di->temp2[j] */
6243 }
6244
6245 if ( pVBInfo->VBInfo & SetCRT2ToTV )
6246 {
6247 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x3A , 0x1F , 0x00 ) ;
6248 }
6249
6250 temp = pVBInfo->NewFlickerMode ;
6251 temp &= 0x80 ;
6252 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x0A , 0xFF , temp ) ;
6253
6254 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6255 tempax = 950 ;
6256
6257 if ( pVBInfo->TVInfo & SetPALTV )
6258 tempax = 520 ;
6259 else
6260 tempax = 440 ;
6261
6262 if ( pVBInfo->VDE <= tempax )
6263 {
6264 tempax -= pVBInfo->VDE ;
6265 tempax = tempax >> 2 ;
6266 tempax = ( tempax & 0x00FF ) | ( ( tempax & 0x00FF ) << 8 ) ;
6267 push1 = tempax ;
6268 temp = ( tempax & 0xFF00 ) >> 8 ;
6269 temp += ( USHORT )TimingPoint[ 0 ] ;
6270
6271 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
6272 {
6273 if ( pVBInfo->VBInfo & ( SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr ) )
6274 {
6275 tempcx=pVBInfo->VGAHDE;
6276 if ( tempcx >= 1024 )
6277 {
6278 temp = 0x17 ; /* NTSC */
6279 if ( pVBInfo->TVInfo & SetPALTV )
6280 temp = 0x19 ; /* PAL */
6281 }
6282 }
6283 }
6284
6285 XGINew_SetReg1( pVBInfo->Part2Port , 0x01 , temp ) ;
6286 tempax = push1 ;
6287 temp = ( tempax & 0xFF00 ) >> 8 ;
6288 temp += TimingPoint[ 1 ] ;
6289
6290 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
6291 {
6292 if ( ( pVBInfo->VBInfo & ( SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr ) ) )
6293 {
6294 tempcx = pVBInfo->VGAHDE ;
6295 if ( tempcx >= 1024 )
6296 {
6297 temp = 0x1D ; /* NTSC */
6298 if ( pVBInfo->TVInfo & SetPALTV )
6299 temp = 0x52 ; /* PAL */
6300 }
6301 }
6302 }
6303 XGINew_SetReg1( pVBInfo->Part2Port , 0x02 , temp ) ;
6304 }
6305
6306 /* 301b */
6307 tempcx = pVBInfo->HT ;
6308
6309 if ( XGI_IsLCDDualLink( pVBInfo ) )
6310 tempcx = tempcx >> 1 ;
6311
6312 tempcx -= 2 ;
6313 temp = tempcx & 0x00FF ;
6314 XGINew_SetReg1( pVBInfo->Part2Port , 0x1B , temp ) ;
6315
6316 temp = ( tempcx & 0xFF00 ) >> 8 ;
6317 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x1D , ~0x0F , temp ) ;
6318
6319 tempcx = pVBInfo->HT >> 1 ;
6320 push1 = tempcx ; /* push cx */
6321 tempcx += 7 ;
6322
6323 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6324 {
6325 tempcx -= 4 ;
6326 }
6327
6328 temp = tempcx & 0x00FF ;
6329 temp = temp << 4 ;
6330 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x22 , 0x0F , temp ) ;
6331
6332 tempbx = TimingPoint[ j ] | ( ( TimingPoint[ j + 1 ] ) << 8 ) ;
6333 tempbx += tempcx ;
6334 push2 = tempbx ;
6335 temp = tempbx & 0x00FF ;
6336 XGINew_SetReg1( pVBInfo->Part2Port , 0x24 , temp ) ;
6337 temp = ( tempbx & 0xFF00 ) >> 8 ;
6338 temp = temp << 4 ;
6339 XGINew_SetRegANDOR(pVBInfo->Part2Port,0x25,0x0F,temp);
6340
6341 tempbx=push2;
6342 tempbx=tempbx+8;
6343 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6344 {
6345 tempbx=tempbx-4;
6346 tempcx=tempbx;
6347 }
6348
6349 temp = ( tempbx & 0x00FF ) << 4 ;
6350 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x29 , 0x0F , temp ) ;
6351
6352 j += 2 ;
6353 tempcx += ( TimingPoint[ j ] | ( ( TimingPoint[ j + 1 ] ) << 8 ) ) ;
6354 temp = tempcx & 0x00FF ;
6355 XGINew_SetReg1( pVBInfo->Part2Port , 0x27 , temp ) ;
6356 temp = ( ( tempcx & 0xFF00 ) >> 8 ) << 4 ;
6357 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x28 , 0x0F , temp ) ;
6358
6359 tempcx += 8 ;
6360 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6361 {
6362 tempcx -= 4 ;
6363 }
6364
6365 temp = tempcx & 0xFF ;
6366 temp = temp << 4 ;
6367 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x2A , 0x0F , temp ) ;
6368
6369 tempcx = push1 ; /* pop cx */
6370 j += 2 ;
6371 temp = TimingPoint[ j ] | ( ( TimingPoint[ j + 1 ] ) << 8 ) ;
6372 tempcx -= temp ;
6373 temp = tempcx & 0x00FF ;
6374 temp = temp << 4 ;
6375 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x2D , 0x0F ,temp ) ;
6376
6377 tempcx -= 11 ;
6378
6379 if ( !( pVBInfo->VBInfo & SetCRT2ToTV ) )
6380 {
6381 tempax = XGI_GetVGAHT2( pVBInfo) ;
6382 tempcx = tempax - 1 ;
6383 }
6384 temp = tempcx & 0x00FF ;
6385 XGINew_SetReg1( pVBInfo->Part2Port , 0x2E , temp ) ;
6386
6387 tempbx = pVBInfo->VDE ;
6388
6389 if ( pVBInfo->VGAVDE == 360 )
6390 tempbx = 746 ;
6391 if ( pVBInfo->VGAVDE == 375 )
6392 tempbx = 746 ;
6393 if ( pVBInfo->VGAVDE == 405 )
6394 tempbx = 853 ;
6395
6396 if ( pVBInfo->VBInfo & SetCRT2ToTV )
6397 {
6398 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
6399 {
6400 if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) )
6401 tempbx = tempbx >> 1 ;
6402 }
6403 else
6404 tempbx = tempbx >> 1 ;
6405 }
6406
6407 tempbx -= 2 ;
6408 temp = tempbx & 0x00FF ;
6409
6410 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6411 {
6412 if ( pVBInfo->VBType & VB_XGI301LV )
6413 {
6414 if ( pVBInfo->TVInfo & SetYPbPrMode1080i )
6415 {
6416 if ( pVBInfo->VBInfo & SetInSlaveMode )
6417 {
6418 if ( ModeNo == 0x2f )
6419 temp += 1 ;
6420 }
6421 }
6422 }
6423 else
6424 {
6425 if ( pVBInfo->VBInfo & SetInSlaveMode )
6426 {
6427 if ( ModeNo == 0x2f )
6428 temp += 1 ;
6429 }
6430 }
6431 }
6432
6433 XGINew_SetReg1( pVBInfo->Part2Port , 0x2F , temp ) ;
6434
6435 temp = ( tempcx & 0xFF00 ) >> 8 ;
6436 temp |= ( ( tempbx & 0xFF00 ) >> 8 ) << 6 ;
6437
6438 if ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) )
6439 {
6440 if ( pVBInfo->VBType & VB_XGI301LV )
6441 {
6442 if ( pVBInfo->TVInfo & SetYPbPrMode1080i )
6443 {
6444 temp |= 0x10 ;
6445
6446 if ( !( pVBInfo->VBInfo & SetCRT2ToSVIDEO ) )
6447 temp |= 0x20 ;
6448 }
6449 }
6450 else
6451 {
6452 temp |= 0x10 ;
6453 if ( !( pVBInfo->VBInfo & SetCRT2ToSVIDEO ) )
6454 temp |= 0x20 ;
6455 }
6456 }
6457
6458 XGINew_SetReg1( pVBInfo->Part2Port , 0x30 , temp ) ;
6459
6460 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) ) /* TV gatingno */
6461 {
6462 tempbx = pVBInfo->VDE ;
6463 tempcx = tempbx - 2 ;
6464
6465 if ( pVBInfo->VBInfo & SetCRT2ToTV )
6466 {
6467 if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) )
6468 tempbx = tempbx >> 1 ;
6469 }
6470
6471 if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
6472 {
6473 temp=0;
6474 if( tempcx & 0x0400 )
6475 temp |= 0x20 ;
6476
6477 if ( tempbx & 0x0400 )
6478 temp |= 0x40 ;
6479
6480 XGINew_SetReg1( pVBInfo->Part4Port , 0x10 , temp ) ;
6481 }
6482
6483 temp = ( ( ( tempbx - 3 ) & 0x0300 ) >> 8 ) << 5 ;
6484 XGINew_SetReg1( pVBInfo->Part2Port , 0x46 , temp ) ;
6485 temp = ( tempbx - 3 ) & 0x00FF ;
6486 XGINew_SetReg1( pVBInfo->Part2Port , 0x47 , temp ) ;
6487 }
6488
6489 tempbx = tempbx & 0x00FF ;
6490
6491 if ( !( modeflag & HalfDCLK ) )
6492 {
6493 tempcx = pVBInfo->VGAHDE ;
6494 if ( tempcx >= pVBInfo->HDE )
6495 {
6496 tempbx |= 0x2000 ;
6497 tempax &= 0x00FF ;
6498 }
6499 }
6500
6501 tempcx = 0x0101 ;
6502
6503 if( pVBInfo->VBInfo & SetCRT2ToTV ) { /*301b*/
6504 if(pVBInfo->VGAHDE>=1024)
6505 {
6506 tempcx=0x1920;
6507 if(pVBInfo->VGAHDE>=1280)
6508 {
6509 tempcx=0x1420;
6510 tempbx=tempbx&0xDFFF;
6511 }
6512 }
6513 }
6514
6515 if ( !( tempbx & 0x2000 ) )
6516 {
6517 if ( modeflag & HalfDCLK )
6518 {
6519 tempcx = ( tempcx & 0xFF00 ) | ( ( tempcx & 0x00FF ) << 1 ) ;
6520 }
6521
6522 push1 = tempbx ;
6523 tempeax = pVBInfo->VGAHDE ;
6524 tempebx = ( tempcx & 0xFF00 ) >> 8 ;
6525 longtemp = tempeax * tempebx ;
6526 tempecx = tempcx & 0x00FF ;
6527 longtemp = longtemp / tempecx ;
6528
6529 /* 301b */
6530 tempecx = 8 * 1024 ;
6531
6532 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
6533 {
6534 tempecx = tempecx * 8 ;
6535 }
6536
6537 longtemp = longtemp * tempecx ;
6538 tempecx = pVBInfo->HDE ;
6539 temp2 = longtemp % tempecx ;
6540 tempeax = longtemp / tempecx ;
6541 if ( temp2 != 0 )
6542 {
6543 tempeax += 1 ;
6544 }
6545
6546 tempax = ( USHORT )tempeax ;
6547
6548 /* 301b */
6549 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
6550 {
6551 tempcx = ( ( tempax & 0xFF00 ) >> 5 ) >> 8 ;
6552 }
6553 /* end 301b */
6554
6555 tempbx = push1 ;
6556 tempbx =( USHORT )( ( ( tempeax & 0x0000FF00 ) & 0x1F00 ) | ( tempbx & 0x00FF ) ) ;
6557 tempax =( USHORT )( ( ( tempeax & 0x000000FF ) << 8 ) | ( tempax & 0x00FF ) ) ;
6558 temp = ( tempax & 0xFF00 ) >> 8 ;
6559 }
6560 else
6561 {
6562 temp = ( tempax & 0x00FF ) >> 8 ;
6563 }
6564
6565 XGINew_SetReg1( pVBInfo->Part2Port , 0x44 , temp ) ;
6566 temp = ( tempbx & 0xFF00 ) >> 8 ;
6567 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x45 , ~0x03F , temp ) ;
6568 temp = tempcx & 0x00FF ;
6569
6570 if ( tempbx & 0x2000 )
6571 temp = 0 ;
6572
6573 if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
6574 temp |= 0x18 ;
6575
6576 XGINew_SetRegANDOR(pVBInfo->Part2Port,0x46,~0x1F,temp);
6577 if ( pVBInfo->TVInfo & SetPALTV )
6578 {
6579 tempbx = 0x0382 ;
6580 tempcx = 0x007e ;
6581 }
6582 else
6583 {
6584 tempbx = 0x0369 ;
6585 tempcx = 0x0061 ;
6586 }
6587
6588 temp = tempbx & 0x00FF ;
6589 XGINew_SetReg1( pVBInfo->Part2Port , 0x4b , temp ) ;
6590 temp = tempcx & 0x00FF ;
6591 XGINew_SetReg1( pVBInfo->Part2Port , 0x4c , temp ) ;
6592
6593 temp = ( ( tempcx & 0xFF00 ) >> 8 ) & 0x03 ;
6594 temp = temp << 2 ;
6595 temp |= ( ( tempbx & 0xFF00 ) >> 8 ) & 0x03 ;
6596
6597 if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
6598 {
6599 temp |= 0x10 ;
6600
6601 if ( pVBInfo->TVInfo & SetYPbPrMode525p )
6602 temp |= 0x20 ;
6603
6604 if ( pVBInfo->TVInfo & SetYPbPrMode750p )
6605 temp |= 0x60 ;
6606 }
6607
6608 XGINew_SetReg1( pVBInfo->Part2Port , 0x4d , temp ) ;
6609 temp=XGINew_GetReg1( pVBInfo->Part2Port , 0x43 ) ; /* 301b change */
6610 XGINew_SetReg1( pVBInfo->Part2Port , 0x43 , ( USHORT )( temp - 3 ) ) ;
6611
6612 if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) )
6613 {
6614 if ( pVBInfo->TVInfo & NTSC1024x768 )
6615 {
6616 TimingPoint = XGI_NTSC1024AdjTime ;
6617 for( i = 0x1c , j = 0 ; i <= 0x30 ; i++ , j++ )
6618 {
6619 XGINew_SetReg1( pVBInfo->Part2Port , i , TimingPoint[ j ] ) ;
6620 }
6621 XGINew_SetReg1( pVBInfo->Part2Port , 0x43 , 0x72 ) ;
6622 }
6623 }
6624
6625 /* [ycchen] 01/14/03 Modify for 301C PALM Support */
6626 if ( pVBInfo->VBType & VB_XGI301C )
6627 {
6628 if ( pVBInfo->TVInfo & SetPALMTV )
6629 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x4E , ~0x08 , 0x08 ) ; /* PALM Mode */
6630 }
6631
6632 if ( pVBInfo->TVInfo & SetPALMTV )
6633 {
6634 tempax = ( UCHAR )XGINew_GetReg1( pVBInfo->Part2Port , 0x01 ) ;
6635 tempax-- ;
6636 XGINew_SetRegAND( pVBInfo->Part2Port , 0x01 , tempax ) ;
6637
6638 /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
6639 XGINew_SetRegAND( pVBInfo->Part2Port , 0x00 , 0xEF ) ;
6640 }
6641
6642 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6643 {
6644 if ( !( pVBInfo->VBInfo & SetInSlaveMode ) )
6645 {
6646 XGINew_SetReg1( pVBInfo->Part2Port , 0x0B , 0x00 ) ;
6647 }
6648 }
6649
6650 if ( pVBInfo->VBInfo & SetCRT2ToTV )
6651 {
6652 return ;
6653 }
6654}
6655
6656
6657/* --------------------------------------------------------------------- */
6658/* Function : XGI_SetLCDRegs */
6659/* Input : */
6660/* Output : */
6661/* Description : */
6662/* --------------------------------------------------------------------- */
6663void XGI_SetLCDRegs(USHORT ModeNo,USHORT ModeIdIndex, PXGI_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
6664{
6665 USHORT push1 ,
6666 push2 ,
6667 pushbx ,
6668 tempax ,
6669 tempbx ,
6670 tempcx ,
6671 temp ,
6672 tempah ,
6673 tempbh ,
6674 tempch ,
6675 resinfo ,
6676 modeflag ,
6677 CRT1Index ;
6678
6679 XGI_LCDDesStruct *LCDBDesPtr = NULL ;
6680
6681
6682 if ( ModeNo <= 0x13 )
6683 {
6684 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
6685 resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
6686 }
6687 else
6688 {
6689 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
6690 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
6691 CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
6692 CRT1Index &= IndexMask ;
6693 }
6694
6695 if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
6696 {
6697 return ;
6698 }
6699
6700 tempbx = pVBInfo->HDE ; /* RHACTE=HDE-1 */
6701
6702 if ( XGI_IsLCDDualLink( pVBInfo ) )
6703 tempbx = tempbx >> 1 ;
6704
6705 tempbx -= 1 ;
6706 temp = tempbx & 0x00FF ;
6707 XGINew_SetReg1( pVBInfo->Part2Port , 0x2C , temp ) ;
6708 temp = ( tempbx & 0xFF00 ) >> 8 ;
6709 temp = temp << 4 ;
6710 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x2B , 0x0F , temp ) ;
6711 temp = 0x01 ;
6712
6713 if ( pVBInfo->LCDResInfo == Panel1280x1024 )
6714 {
6715 if ( pVBInfo->ModeType == ModeEGA )
6716 {
6717 if ( pVBInfo->VGAHDE >= 1024 )
6718 {
6719 temp = 0x02 ;
6720 if ( pVBInfo->LCDInfo & LCDVESATiming )
6721 temp = 0x01 ;
6722 }
6723 }
6724 }
6725
6726 XGINew_SetReg1( pVBInfo->Part2Port , 0x0B , temp ) ;
6727 tempbx = pVBInfo->VDE ; /* RTVACTEO=(VDE-1)&0xFF */
6728 push1 = tempbx ;
6729 tempbx-- ;
6730 temp = tempbx & 0x00FF ;
6731 XGINew_SetReg1( pVBInfo->Part2Port , 0x03 , temp ) ;
6732 temp = ( ( tempbx & 0xFF00 ) >> 8 ) & 0x07 ;
6733 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x0C , ~0x07 , temp ) ;
6734
6735 tempcx = pVBInfo->VT - 1 ;
6736 push2 = tempcx + 1 ;
6737 temp = tempcx & 0x00FF ; /* RVTVT=VT-1 */
6738 XGINew_SetReg1( pVBInfo->Part2Port , 0x19 , temp ) ;
6739 temp = ( tempcx & 0xFF00 ) >> 8 ;
6740 temp = temp << 5 ;
6741 XGINew_SetReg1( pVBInfo->Part2Port , 0x1A , temp ) ;
6742 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x09 , 0xF0 , 0x00 ) ;
6743 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x0A , 0xF0 , 0x00 ) ;
6744 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x17 , 0xFB , 0x00 ) ;
6745 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x18 , 0xDF , 0x00 ) ;
6746
6747 /* Customized LCDB Des no add */
6748 tempbx = 5 ;
6749 LCDBDesPtr = ( XGI_LCDDesStruct * )XGI_GetLcdPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
6750 tempah = pVBInfo->LCDResInfo ;
6751 tempah &= PanelResInfo ;
6752
6753 if ( ( tempah == Panel1024x768 ) || ( tempah == Panel1024x768x75 ) )
6754 {
6755 tempbx = 1024 ;
6756 tempcx = 768 ;
6757 }
6758 else if ( ( tempah == Panel1280x1024 ) || ( tempah == Panel1280x1024x75 ) )
6759 {
6760 tempbx = 1280 ;
6761 tempcx = 1024 ;
6762 }
6763 else if ( tempah == Panel1400x1050 )
6764 {
6765 tempbx = 1400 ;
6766 tempcx = 1050 ;
6767 }
6768 else
6769 {
6770 tempbx = 1600 ;
6771 tempcx = 1200 ;
6772 }
6773
6774 if ( pVBInfo->LCDInfo & EnableScalingLCD )
6775 {
6776 tempbx = pVBInfo->HDE ;
6777 tempcx = pVBInfo->VDE ;
6778 }
6779
6780 pushbx = tempbx ;
6781 tempax = pVBInfo->VT ;
6782 pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES ;
6783 pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS ;
6784 pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES ;
6785 pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS ;
6786 tempbx = pVBInfo->LCDVDES ;
6787 tempcx += tempbx ;
6788
6789 if ( tempcx >= tempax )
6790 tempcx -= tempax ; /* lcdvdes */
6791
6792 temp = tempbx & 0x00FF ; /* RVEQ1EQ=lcdvdes */
6793 XGINew_SetReg1( pVBInfo->Part2Port , 0x05 , temp ) ;
6794 temp = tempcx & 0x00FF ;
6795 XGINew_SetReg1( pVBInfo->Part2Port , 0x06 , temp ) ;
6796 tempch = ( ( tempcx & 0xFF00 ) >> 8 ) & 0x07 ;
6797 tempbh = ( ( tempbx & 0xFF00 ) >> 8 ) & 0x07 ;
6798 tempah = tempch ;
6799 tempah = tempah << 3 ;
6800 tempah |= tempbh ;
6801 XGINew_SetReg1( pVBInfo->Part2Port , 0x02 , tempah ) ;
6802
6803 /* getlcdsync() */
6804 XGI_GetLCDSync( &tempax , &tempbx,pVBInfo ) ;
6805 tempcx = tempbx ;
6806 tempax = pVBInfo->VT ;
6807 tempbx = pVBInfo->LCDVRS ;
6808
6809 /* if ( SetLCD_Info & EnableScalingLCD ) */
6810 tempcx += tempbx ;
6811 if ( tempcx >= tempax )
6812 tempcx -= tempax ;
6813
6814 temp = tempbx & 0x00FF ; /* RTVACTEE=lcdvrs */
6815 XGINew_SetReg1( pVBInfo->Part2Port , 0x04 , temp ) ;
6816 temp = ( tempbx & 0xFF00 ) >> 8 ;
6817 temp = temp << 4 ;
6818 temp |= ( tempcx & 0x000F ) ;
6819 XGINew_SetReg1( pVBInfo->Part2Port , 0x01 , temp ) ;
6820 tempcx = pushbx ;
6821 tempax = pVBInfo->HT ;
6822 tempbx = pVBInfo->LCDHDES ;
6823 tempbx &= 0x0FFF ;
6824
6825 if ( XGI_IsLCDDualLink( pVBInfo ) )
6826 {
6827 tempax = tempax >> 1 ;
6828 tempbx = tempbx >> 1 ;
6829 tempcx = tempcx >> 1 ;
6830 }
6831
6832 if ( pVBInfo->VBType & VB_XGI302LV )
6833 tempbx += 1 ;
6834
6835 if ( pVBInfo->VBType & VB_XGI301C ) /* tap4 */
6836 tempbx += 1 ;
6837
6838 tempcx += tempbx ;
6839
6840 if ( tempcx >= tempax )
6841 tempcx -= tempax ;
6842
6843 temp = tempbx & 0x00FF ;
6844 XGINew_SetReg1( pVBInfo->Part2Port , 0x1F , temp ) ; /* RHBLKE=lcdhdes */
6845 temp = ( ( tempbx & 0xFF00 ) >> 8 ) << 4 ;
6846 XGINew_SetReg1( pVBInfo->Part2Port , 0x20 , temp ) ;
6847 temp = tempcx & 0x00FF ;
6848 XGINew_SetReg1( pVBInfo->Part2Port , 0x23 , temp ) ; /* RHEQPLE=lcdhdee */
6849 temp = ( tempcx & 0xFF00 ) >> 8 ;
6850 XGINew_SetReg1( pVBInfo->Part2Port , 0x25 , temp ) ;
6851
6852 /* getlcdsync() */
6853 XGI_GetLCDSync( &tempax , &tempbx ,pVBInfo) ;
6854 tempcx = tempax ;
6855 tempax = pVBInfo->HT ;
6856 tempbx = pVBInfo->LCDHRS ;
6857 /* if ( SetLCD_Info & EnableScalingLCD) */
6858 if ( XGI_IsLCDDualLink( pVBInfo) )
6859 {
6860 tempax = tempax >> 1 ;
6861 tempbx = tempbx >> 1 ;
6862 tempcx = tempcx >> 1 ;
6863 }
6864
6865 if ( pVBInfo->VBType & VB_XGI302LV )
6866 tempbx += 1 ;
6867
6868 tempcx += tempbx ;
6869
6870 if ( tempcx >= tempax )
6871 tempcx -= tempax ;
6872
6873 temp = tempbx & 0x00FF ; /* RHBURSTS=lcdhrs */
6874 XGINew_SetReg1( pVBInfo->Part2Port , 0x1C , temp ) ;
6875
6876 temp = ( tempbx & 0xFF00 ) >> 8 ;
6877 temp = temp << 4 ;
6878 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x1D , ~0x0F0 , temp ) ;
6879 temp = tempcx & 0x00FF ; /* RHSYEXP2S=lcdhre */
6880 XGINew_SetReg1( pVBInfo->Part2Port , 0x21 , temp ) ;
6881
6882 if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
6883 {
6884 if ( pVBInfo->VGAVDE == 525 )
6885 {
6886 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
6887 {
6888 temp = 0xC6 ;
6889 }
6890 else
6891 temp = 0xC4 ;
6892
6893 XGINew_SetReg1( pVBInfo->Part2Port , 0x2f , temp ) ;
6894 XGINew_SetReg1( pVBInfo->Part2Port , 0x30 , 0xB3 ) ;
6895 }
6896
6897 if ( pVBInfo->VGAVDE == 420 )
6898 {
6899 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
6900 {
6901 temp = 0x4F ;
6902 }
6903 else
6904 temp = 0x4E ;
6905 XGINew_SetReg1( pVBInfo->Part2Port , 0x2f , temp ) ;
6906 }
6907 }
6908}
6909
6910
6911/* --------------------------------------------------------------------- */
6912/* Function : XGI_GetTap4Ptr */
6913/* Input : */
6914/* Output : di -> Tap4 Reg. Setting Pointer */
6915/* Description : */
6916/* --------------------------------------------------------------------- */
6917XGI301C_Tap4TimingStruct* XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
6918{
6919 USHORT tempax ,
6920 tempbx ,
6921 i ;
6922
6923 XGI301C_Tap4TimingStruct *Tap4TimingPtr ;
6924
6925 if ( tempcx == 0 )
6926 {
6927 tempax = pVBInfo->VGAHDE ;
6928 tempbx = pVBInfo->HDE ;
6929 }
6930 else
6931 {
6932 tempax = pVBInfo->VGAVDE ;
6933 tempbx = pVBInfo->VDE ;
6934 }
6935
6936 if ( tempax < tempbx )
6937 return &EnlargeTap4Timing[ 0 ] ;
6938 else if( tempax == tempbx )
6939 return &NoScaleTap4Timing[ 0 ] ; /* 1:1 */
6940 else
6941 Tap4TimingPtr = NTSCTap4Timing ; /* NTSC */
6942
6943 if ( pVBInfo->TVInfo & SetPALTV )
6944 Tap4TimingPtr = PALTap4Timing ;
6945
6946
6947 if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
6948 {
6949 if ( pVBInfo->TVInfo & SetYPbPrMode525i )
6950 Tap4TimingPtr = YPbPr525iTap4Timing ;
6951 if ( pVBInfo->TVInfo & SetYPbPrMode525p )
6952 Tap4TimingPtr = YPbPr525pTap4Timing ;
6953 if ( pVBInfo->TVInfo & SetYPbPrMode750p )
6954 Tap4TimingPtr = YPbPr750pTap4Timing ;
6955 }
6956
6957 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
6958 Tap4TimingPtr = HiTVTap4Timing ;
6959
6960 i = 0 ;
6961 while( Tap4TimingPtr[ i ].DE != 0xFFFF )
6962 {
6963 if ( Tap4TimingPtr[ i ].DE == tempax )
6964 break ;
6965 i++ ;
6966 }
6967 return &Tap4TimingPtr[ i ] ;
6968}
6969
6970
6971/* --------------------------------------------------------------------- */
6972/* Function : XGI_SetTap4Regs */
6973/* Input : */
6974/* Output : */
6975/* Description : */
6976/* --------------------------------------------------------------------- */
6977void XGI_SetTap4Regs( PVB_DEVICE_INFO pVBInfo)
6978{
6979 USHORT i ,
6980 j ;
6981
6982 XGI301C_Tap4TimingStruct *Tap4TimingPtr ;
6983
6984 if ( !( pVBInfo->VBType & VB_XGI301C ) )
6985 return ;
6986
6987#ifndef Tap4
6988 XGINew_SetRegAND( pVBInfo->Part2Port , 0x4E , 0xEB ) ; /* Disable Tap4 */
6989#else /* Tap4 Setting */
6990
6991 Tap4TimingPtr = XGI_GetTap4Ptr( 0 , pVBInfo) ; /* Set Horizontal Scaling */
6992 for( i = 0x80 , j = 0 ; i <= 0xBF ; i++ , j++ )
6993 XGINew_SetReg1( pVBInfo->Part2Port , i , Tap4TimingPtr->Reg[ j ] ) ;
6994
6995 if ( ( pVBInfo->VBInfo & SetCRT2ToTV ) && ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) )
6996 {
6997 Tap4TimingPtr = XGI_GetTap4Ptr( 1 , pVBInfo); /* Set Vertical Scaling */
6998 for( i = 0xC0 , j = 0 ; i < 0xFF ; i++ , j++ )
6999 XGINew_SetReg1( pVBInfo->Part2Port , i , Tap4TimingPtr->Reg[ j ] ) ;
7000 }
7001
7002 if ( ( pVBInfo->VBInfo & SetCRT2ToTV ) && ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) )
7003 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x4E , ~0x14 , 0x04 ) ; /* Enable V.Scaling */
7004 else
7005 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x4E , ~0x14 , 0x10 ) ; /* Enable H.Scaling */
7006#endif
7007}
7008
7009/* --------------------------------------------------------------------- */
7010/* Function : XGI_SetGroup3 */
7011/* Input : */
7012/* Output : */
7013/* Description : */
7014/* --------------------------------------------------------------------- */
7015void XGI_SetGroup3(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
7016{
7017 USHORT i;
7018 UCHAR *tempdi;
7019 USHORT modeflag;
7020
7021 if(ModeNo<=0x13)
7022 {
7023 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
7024 }
7025 else
7026 {
7027 modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
7028 }
7029
7030
7031 XGINew_SetReg1(pVBInfo->Part3Port,0x00,0x00);
7032 if(pVBInfo->TVInfo&SetPALTV)
7033 {
7034 XGINew_SetReg1(pVBInfo->Part3Port,0x13,0xFA);
7035 XGINew_SetReg1(pVBInfo->Part3Port,0x14,0xC8);
7036 }
7037 else
7038 {
7039 XGINew_SetReg1(pVBInfo->Part3Port,0x13,0xF5);
7040 XGINew_SetReg1(pVBInfo->Part3Port,0x14,0xB7);
7041 }
7042
7043 if(!(pVBInfo->VBInfo&SetCRT2ToTV))
7044 {
7045 return;
7046 }
7047
7048 if(pVBInfo->TVInfo&SetPALMTV)
7049 {
7050 XGINew_SetReg1(pVBInfo->Part3Port,0x13,0xFA);
7051 XGINew_SetReg1(pVBInfo->Part3Port,0x14,0xC8);
7052 XGINew_SetReg1(pVBInfo->Part3Port,0x3D,0xA8);
7053 }
7054
7055 if((pVBInfo->VBInfo&SetCRT2ToHiVisionTV)|| (pVBInfo->VBInfo&SetCRT2ToYPbPr))
7056 {
7057 if(pVBInfo->TVInfo & SetYPbPrMode525i)
7058 {
7059 return;
7060 }
7061 tempdi=pVBInfo->HiTVGroup3Data;
7062 if(pVBInfo->SetFlag&TVSimuMode)
7063 {
7064 tempdi=pVBInfo->HiTVGroup3Simu;
7065 if(!(modeflag&Charx8Dot))
7066 {
7067 tempdi=pVBInfo->HiTVGroup3Text;
7068 }
7069 }
7070
7071 if(pVBInfo->TVInfo & SetYPbPrMode525p)
7072 {
7073 tempdi=pVBInfo->Ren525pGroup3;
7074 }
7075 if(pVBInfo->TVInfo & SetYPbPrMode750p)
7076 {
7077 tempdi=pVBInfo->Ren750pGroup3;
7078 }
7079
7080 for(i=0;i<=0x3E;i++)
7081 {
7082 XGINew_SetReg1(pVBInfo->Part3Port,i,tempdi[i]);
7083 }
7084 if(pVBInfo->VBType&VB_XGI301C) /* Marcovision */
7085 {
7086 if(pVBInfo->TVInfo & SetYPbPrMode525p)
7087 {
7088 XGINew_SetReg1(pVBInfo->Part3Port,0x28,0x3f);
7089 }
7090 }
7091 }
7092 return;
7093} /* {end of XGI_SetGroup3} */
7094
7095
7096/* --------------------------------------------------------------------- */
7097/* Function : XGI_SetGroup4 */
7098/* Input : */
7099/* Output : */
7100/* Description : */
7101/* --------------------------------------------------------------------- */
7102void XGI_SetGroup4(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
7103{
7104 USHORT tempax ,
7105 tempcx ,
7106 tempbx ,
7107 modeflag ,
7108 temp ,
7109 temp2 ;
7110
7111 ULONG tempebx ,
7112 tempeax ,
7113 templong ;
7114
7115
7116 if ( ModeNo <= 0x13 )
7117 {
7118 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
7119 }
7120 else
7121 {
7122 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
7123 }
7124
7125 temp = pVBInfo->RVBHCFACT ;
7126 XGINew_SetReg1( pVBInfo->Part4Port , 0x13 , temp ) ;
7127
7128 tempbx = pVBInfo->RVBHCMAX ;
7129 temp = tempbx & 0x00FF ;
7130 XGINew_SetReg1( pVBInfo->Part4Port , 0x14 , temp ) ;
7131 temp2 = ( ( tempbx & 0xFF00 ) >> 8 ) << 7 ;
7132 tempcx = pVBInfo->VGAHT - 1 ;
7133 temp = tempcx & 0x00FF ;
7134 XGINew_SetReg1( pVBInfo->Part4Port , 0x16 , temp ) ;
7135
7136 temp =( ( tempcx & 0xFF00 ) >> 8 ) << 3 ;
7137 temp2 |= temp ;
7138
7139 tempcx = pVBInfo->VGAVT - 1 ;
7140 if ( !( pVBInfo->VBInfo & SetCRT2ToTV ) )
7141 {
7142 tempcx -= 5 ;
7143 }
7144
7145 temp = tempcx & 0x00FF ;
7146 XGINew_SetReg1( pVBInfo->Part4Port , 0x17 , temp ) ;
7147 temp = temp2 | ( ( tempcx & 0xFF00 ) >> 8 ) ;
7148 XGINew_SetReg1( pVBInfo->Part4Port , 0x15 , temp ) ;
7149 XGINew_SetRegOR( pVBInfo->Part4Port , 0x0D , 0x08 ) ;
7150 tempcx = pVBInfo->VBInfo ;
7151 tempbx = pVBInfo->VGAHDE ;
7152
7153 if ( modeflag & HalfDCLK )
7154 {
7155 tempbx = tempbx >> 1 ;
7156 }
7157
7158 if ( XGI_IsLCDDualLink( pVBInfo ) )
7159 tempbx = tempbx >> 1 ;
7160
7161 if(tempcx&SetCRT2ToHiVisionTV)
7162 {
7163 temp=0;
7164 if(tempbx<=1024)
7165 temp=0xA0;
7166 if(tempbx == 1280)
7167 temp = 0xC0;
7168 }
7169 else if(tempcx&SetCRT2ToTV)
7170 {
7171 temp=0xA0;
7172 if(tempbx <= 800)
7173 temp=0x80;
7174 }
7175 else
7176 {
7177 temp=0x80;
7178 if(pVBInfo->VBInfo&SetCRT2ToLCD)
7179 {
7180 temp=0;
7181 if(tempbx>800)
7182 temp=0x60;
7183 }
7184 }
7185
7186 if ( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
7187 {
7188 temp = 0x00 ;
7189 if ( pVBInfo->VGAHDE == 1280 )
7190 temp = 0x40 ;
7191 if ( pVBInfo->VGAHDE == 1024 )
7192 temp = 0x20 ;
7193 }
7194 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x0E , ~0xEF , temp ) ;
7195
7196 tempebx = pVBInfo->VDE ;
7197
7198 if ( tempcx & SetCRT2ToHiVisionTV )
7199 {
7200 if ( !( temp & 0xE000 ) )
7201 tempbx = tempbx >> 1 ;
7202 }
7203
7204 tempcx = pVBInfo->RVBHRS ;
7205 temp = tempcx & 0x00FF ;
7206 XGINew_SetReg1( pVBInfo->Part4Port , 0x18 , temp );
7207
7208 tempeax = pVBInfo->VGAVDE ;
7209 tempcx |= 0x04000 ;
7210
7211
7212 if ( tempeax <= tempebx )
7213 {
7214 tempcx=(tempcx&(~0x4000));
7215 tempeax = pVBInfo->VGAVDE ;
7216 }
7217 else
7218 {
7219 tempeax -= tempebx ;
7220 }
7221
7222
7223 templong = ( tempeax * 256 * 1024 ) % tempebx ;
7224 tempeax = ( tempeax * 256 * 1024 ) / tempebx ;
7225 tempebx = tempeax ;
7226
7227 if ( templong != 0 )
7228 {
7229 tempebx++ ;
7230 }
7231
7232
7233 temp = ( USHORT )( tempebx & 0x000000FF ) ;
7234 XGINew_SetReg1( pVBInfo->Part4Port , 0x1B , temp ) ;
7235
7236 temp = ( USHORT )( ( tempebx & 0x0000FF00 ) >> 8 ) ;
7237 XGINew_SetReg1( pVBInfo->Part4Port , 0x1A , temp ) ;
7238 tempbx = ( USHORT )( tempebx >> 16 ) ;
7239 temp = tempbx & 0x00FF ;
7240 temp = temp << 4 ;
7241 temp |= ( ( tempcx & 0xFF00 ) >> 8 ) ;
7242 XGINew_SetReg1( pVBInfo->Part4Port , 0x19 , temp ) ;
7243
7244 /* 301b */
7245 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
7246 {
7247 temp = 0x0028 ;
7248 XGINew_SetReg1( pVBInfo->Part4Port , 0x1C , temp ) ;
7249 tempax = pVBInfo->VGAHDE ;
7250 if ( modeflag & HalfDCLK )
7251 {
7252 tempax = tempax >> 1 ;
7253 }
7254
7255 if ( XGI_IsLCDDualLink( pVBInfo ) )
7256 tempax = tempax >> 1 ;
7257
7258 /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
7259 if ( pVBInfo->VBInfo & SetCRT2ToLCD )
7260 {
7261 if ( tempax > 800 )
7262 tempax -= 800 ;
7263 }
7264 else
7265 {
7266 if ( pVBInfo->VGAHDE > 800 )
7267 {
7268 if ( pVBInfo->VGAHDE == 1024 )
7269 tempax = ( tempax * 25 / 32 ) - 1 ;
7270 else
7271 tempax = ( tempax * 20 / 32 ) - 1 ;
7272 }
7273 }
7274 tempax -= 1 ;
7275
7276/*
7277 if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToHiVisionTV ) )
7278 {
7279 if ( pVBInfo->VBType & VB_XGI301LV )
7280 {
7281 if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
7282 {
7283 if ( pVBInfo->VGAHDE > 800 )
7284 {
7285 if ( pVBInfo->VGAHDE == 1024 )
7286 tempax = ( tempax * 25 / 32 ) - 1 ;
7287 else
7288 tempax = ( tempax * 20 / 32 ) - 1 ;
7289 }
7290 }
7291 }
7292 else
7293 {
7294 if ( pVBInfo->VGAHDE > 800 )
7295 {
7296 if ( pVBInfo->VGAHDE == 1024 )
7297 tempax = ( tempax * 25 / 32 ) - 1 ;
7298 else
7299 tempax = ( tempax * 20 / 32 ) - 1 ;
7300 }
7301 }
7302 }
7303*/
7304
7305 temp = ( tempax & 0xFF00 ) >> 8 ;
7306 temp = ( ( temp & 0x0003 ) << 4 ) ;
7307 XGINew_SetReg1( pVBInfo->Part4Port , 0x1E , temp ) ;
7308 temp = ( tempax & 0x00FF ) ;
7309 XGINew_SetReg1( pVBInfo->Part4Port , 0x1D , temp ) ;
7310
7311 if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToHiVisionTV ) )
7312 {
7313 if ( pVBInfo->VGAHDE > 800 )
7314 {
7315 XGINew_SetRegOR( pVBInfo->Part4Port , 0x1E , 0x08 ) ;
7316 }
7317 }
7318 temp = 0x0036 ;
7319
7320 if ( pVBInfo->VBInfo & SetCRT2ToTV )
7321 {
7322 if ( !( pVBInfo->TVInfo & ( NTSC1024x768 | SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
7323 {
7324 temp |= 0x0001 ;
7325 if ( ( pVBInfo->VBInfo & SetInSlaveMode ) && ( !( pVBInfo->TVInfo & TVSimuMode ) ) )
7326 temp &= ( ~0x0001 ) ;
7327 }
7328 }
7329
7330 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x1F , 0x00C0 , temp ) ;
7331 tempbx = pVBInfo->HT ;
7332 if ( XGI_IsLCDDualLink( pVBInfo ) )
7333 tempbx = tempbx >> 1 ;
7334 tempbx = ( tempbx >> 1 ) - 2 ;
7335 temp = ( ( tempbx & 0x0700 ) >> 8 ) << 3 ;
7336 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x21 , 0x00C0 , temp ) ;
7337 temp = tempbx & 0x00FF ;
7338 XGINew_SetReg1( pVBInfo->Part4Port , 0x22 , temp ) ;
7339 }
7340 /* end 301b */
7341
7342 if ( pVBInfo->ISXPDOS == 0 )
7343 XGI_SetCRT2VCLK( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
7344}
7345
7346
7347/* --------------------------------------------------------------------- */
7348/* Function : XGI_SetGroup5 */
7349/* Input : */
7350/* Output : */
7351/* Description : */
7352/* --------------------------------------------------------------------- */
7353void XGI_SetGroup5( USHORT ModeNo , USHORT ModeIdIndex , PVB_DEVICE_INFO pVBInfo)
7354{
7355 USHORT Pindex ,
7356 Pdata ;
7357
7358 Pindex = pVBInfo->Part5Port ;
7359 Pdata = pVBInfo->Part5Port + 1 ;
7360 if ( pVBInfo->ModeType == ModeVGA )
7361 {
7362 if ( !( pVBInfo->VBInfo & ( SetInSlaveMode | LoadDACFlag | CRT2DisplayFlag ) ) )
7363 {
7364 XGINew_EnableCRT2(pVBInfo) ;
7365 /* LoadDAC2(pVBInfo->Part5Port,ModeNo,ModeIdIndex); */
7366 }
7367 }
7368 return ;
7369}
7370
7371
7372/* --------------------------------------------------------------------- */
7373/* Function : XGI_GetLcdPtr */
7374/* Input : */
7375/* Output : */
7376/* Description : */
7377/* --------------------------------------------------------------------- */
7378void* XGI_GetLcdPtr( USHORT BX , USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
7379{
7380 USHORT i ,
7381 tempdx ,
7382 tempcx ,
7383 tempbx ,
7384 tempal ,
7385 modeflag ,
7386 table ;
7387
7388 XGI330_LCDDataTablStruct *tempdi = 0 ;
7389
7390
7391 tempbx = BX;
7392
7393 if ( ModeNo <= 0x13 )
7394 {
7395 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
7396 tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
7397 }
7398 else
7399 {
7400 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
7401 tempal = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
7402 }
7403
7404 tempal = tempal & 0x0f ;
7405
7406 if ( tempbx <= 1 ) /* ExpLink */
7407 {
7408 if ( ModeNo <= 0x13 )
7409 {
7410 tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ; /* find no Ext_CRT2CRTC2 */
7411 }
7412 else
7413 {
7414 tempal= pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
7415 }
7416
7417 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
7418 {
7419 if ( ModeNo <= 0x13 )
7420 tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC2 ;
7421 else
7422 tempal= pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC2 ;
7423 }
7424
7425 if ( tempbx & 0x01 )
7426 tempal = ( tempal >> 4 ) ;
7427
7428 tempal = ( tempal & 0x0f ) ;
7429 }
7430
7431 tempcx = LCDLenList[ tempbx ] ; /* mov cl,byte ptr cs:LCDLenList[bx] */
7432
7433 if ( pVBInfo->LCDInfo & EnableScalingLCD ) /* ScaleLCD */
7434 {
7435 if ( ( tempbx == 5 ) || ( tempbx ) == 7 )
7436 tempcx = LCDDesDataLen2 ;
7437 else if ( ( tempbx == 3 ) || ( tempbx == 8 ) )
7438 tempcx = LVDSDesDataLen2 ;
7439 }
7440 /* mov di, word ptr cs:LCDDataList[bx] */
7441 /* tempdi=pVideoMemory[LCDDataList+tempbx*2]|(pVideoMemory[LCDDataList+tempbx*2+1]<<8); */
7442
7443 switch( tempbx )
7444 {
7445 case 0:
7446 tempdi = XGI_EPLLCDCRT1Ptr_H ;
7447 break ;
7448 case 1:
7449 tempdi = XGI_EPLLCDCRT1Ptr_V ;
7450 break ;
7451 case 2:
7452 tempdi = XGI_EPLLCDDataPtr ;
7453 break ;
7454 case 3:
7455 tempdi = XGI_EPLLCDDesDataPtr ;
7456 break ;
7457 case 4:
7458 tempdi = XGI_LCDDataTable ;
7459 break ;
7460 case 5:
7461 tempdi = XGI_LCDDesDataTable ;
7462 break ;
7463 case 6:
7464 tempdi = XGI_EPLCHLCDRegPtr ;
7465 break ;
7466 case 7:
7467 case 8:
7468 case 9:
7469 tempdi = 0 ;
7470 break ;
7471 default:
7472 break ;
7473 }
7474
7475 if ( tempdi == 0x00 ) /* OEMUtil */
7476 return 0 ;
7477
7478 table = tempbx ;
7479 i = 0 ;
7480
7481 while( tempdi[ i ].PANELID != 0xff )
7482 {
7483 tempdx = pVBInfo->LCDResInfo ;
7484 if ( tempbx & 0x0080 ) /* OEMUtil */
7485 {
7486 tempbx &= ( ~0x0080 ) ;
7487 tempdx = pVBInfo->LCDTypeInfo ;
7488 }
7489
7490 if ( pVBInfo->LCDInfo & EnableScalingLCD )
7491 tempdx &= ( ~PanelResInfo ) ;
7492
7493 if ( tempdi[ i ].PANELID == tempdx )
7494 {
7495 tempbx = tempdi[ i ].MASK ;
7496 tempdx = pVBInfo->LCDInfo ;
7497
7498 if ( ModeNo <= 0x13 ) /* alan 09/10/2003 */
7499 tempdx |= SetLCDStdMode ;
7500
7501 if ( modeflag & HalfDCLK )
7502 tempdx |= SetLCDLowResolution ;
7503
7504 tempbx &= tempdx;
7505 if ( tempbx == tempdi[ i ].CAP )
7506 break ;
7507 }
7508 i++ ;
7509 }
7510
7511 if ( table == 0 )
7512 {
7513 switch( tempdi[ i ].DATAPTR )
7514 {
7515 case 0:
7516 return &XGI_LVDSCRT11024x768_1_H[ tempal ] ;
7517 break ;
7518 case 1:
7519 return &XGI_LVDSCRT11024x768_2_H[ tempal ] ;
7520 break ;
7521 case 2:
7522 return &XGI_LVDSCRT11280x1024_1_H[ tempal ] ;
7523 break ;
7524 case 3:
7525 return &XGI_LVDSCRT11280x1024_2_H[ tempal ] ;
7526 break ;
7527 case 4:
7528 return &XGI_LVDSCRT11400x1050_1_H[ tempal ] ;
7529 break ;
7530 case 5:
7531 return &XGI_LVDSCRT11400x1050_2_H[ tempal ] ;
7532 break ;
7533 case 6:
7534 return &XGI_LVDSCRT11600x1200_1_H[ tempal ] ;
7535 break ;
7536 case 7:
7537 return &XGI_LVDSCRT11024x768_1_Hx75[ tempal ] ;
7538 break ;
7539 case 8:
7540 return &XGI_LVDSCRT11024x768_2_Hx75[ tempal ] ;
7541 break ;
7542 case 9:
7543 return &XGI_LVDSCRT11280x1024_1_Hx75[ tempal ] ;
7544 break ;
7545 case 10:
7546 return &XGI_LVDSCRT11280x1024_2_Hx75[ tempal ] ;
7547 break ;
7548 default:
7549 break ;
7550 }
7551 }
7552 else if ( table == 1 )
7553 {
7554 switch( tempdi[ i ].DATAPTR )
7555 {
7556 case 0:
7557 return &XGI_LVDSCRT11024x768_1_V[ tempal ] ;
7558 break ;
7559 case 1:
7560 return &XGI_LVDSCRT11024x768_2_V[ tempal ] ;
7561 break ;
7562 case 2:
7563 return &XGI_LVDSCRT11280x1024_1_V[ tempal ] ;
7564 break ;
7565 case 3:
7566 return &XGI_LVDSCRT11280x1024_2_V[ tempal ] ;
7567 break ;
7568 case 4:
7569 return &XGI_LVDSCRT11400x1050_1_V[ tempal ] ;
7570 break ;
7571 case 5:
7572 return &XGI_LVDSCRT11400x1050_2_V[ tempal ] ;
7573 break ;
7574 case 6:
7575 return &XGI_LVDSCRT11600x1200_1_V[ tempal ] ;
7576 break ;
7577 case 7:
7578 return &XGI_LVDSCRT11024x768_1_Vx75[ tempal ] ;
7579 break ;
7580 case 8:
7581 return &XGI_LVDSCRT11024x768_2_Vx75[ tempal ] ;
7582 break ;
7583 case 9:
7584 return &XGI_LVDSCRT11280x1024_1_Vx75[ tempal ] ;
7585 break ;
7586 case 10:
7587 return &XGI_LVDSCRT11280x1024_2_Vx75[ tempal ] ;
7588 break ;
7589 default:
7590 break ;
7591 }
7592 }
7593 else if ( table == 2 )
7594 {
7595 switch( tempdi[ i ].DATAPTR )
7596 {
7597 case 0:
7598 return &XGI_LVDS1024x768Data_1[ tempal ] ;
7599 break ;
7600 case 1:
7601 return &XGI_LVDS1024x768Data_2[ tempal ] ;
7602 break ;
7603 case 2:
7604 return &XGI_LVDS1280x1024Data_1[ tempal ] ;
7605 break ;
7606 case 3:
7607 return &XGI_LVDS1280x1024Data_2[ tempal ] ;
7608 break ;
7609 case 4:
7610 return &XGI_LVDS1400x1050Data_1[ tempal ] ;
7611 break ;
7612 case 5:
7613 return &XGI_LVDS1400x1050Data_2[ tempal ] ;
7614 break ;
7615 case 6:
7616 return &XGI_LVDS1600x1200Data_1[ tempal ] ;
7617 break ;
7618 case 7:
7619 return &XGI_LVDSNoScalingData[ tempal ] ;
7620 break ;
7621 case 8:
7622 return &XGI_LVDS1024x768Data_1x75[ tempal ] ;
7623 break ;
7624 case 9:
7625 return &XGI_LVDS1024x768Data_2x75[ tempal ] ;
7626 break ;
7627 case 10:
7628 return &XGI_LVDS1280x1024Data_1x75[ tempal ] ;
7629 break ;
7630 case 11:
7631 return &XGI_LVDS1280x1024Data_2x75[ tempal ] ;
7632 break ;
7633 case 12:
7634 return &XGI_LVDSNoScalingDatax75[ tempal ] ;
7635 break ;
7636 default:
7637 break ;
7638 }
7639 }
7640 else if ( table == 3 )
7641 {
7642 switch( tempdi[ i ].DATAPTR )
7643 {
7644 case 0:
7645 return &XGI_LVDS1024x768Des_1[ tempal ] ;
7646 break ;
7647 case 1:
7648 return &XGI_LVDS1024x768Des_3[ tempal ] ;
7649 break ;
7650 case 2:
7651 return &XGI_LVDS1024x768Des_2[ tempal ] ;
7652 break ;
7653 case 3:
7654 return &XGI_LVDS1280x1024Des_1[ tempal ] ;
7655 break ;
7656 case 4:
7657 return &XGI_LVDS1280x1024Des_2[ tempal ] ;
7658 break ;
7659 case 5:
7660 return &XGI_LVDS1400x1050Des_1[ tempal ] ;
7661 break ;
7662 case 6:
7663 return &XGI_LVDS1400x1050Des_2[ tempal ] ;
7664 break ;
7665 case 7:
7666 return &XGI_LVDS1600x1200Des_1[ tempal ] ;
7667 break ;
7668 case 8:
7669 return &XGI_LVDSNoScalingDesData[ tempal ] ;
7670 break ;
7671 case 9:
7672 return &XGI_LVDS1024x768Des_1x75[ tempal ] ;
7673 break ;
7674 case 10:
7675 return &XGI_LVDS1024x768Des_3x75[ tempal ] ;
7676 break ;
7677 case 11:
7678 return &XGI_LVDS1024x768Des_2x75[ tempal ] ;
7679 break;
7680 case 12:
7681 return &XGI_LVDS1280x1024Des_1x75[ tempal ] ;
7682 break ;
7683 case 13:
7684 return &XGI_LVDS1280x1024Des_2x75[ tempal ] ;
7685 break ;
7686 case 14:
7687 return &XGI_LVDSNoScalingDesDatax75[ tempal ] ;
7688 break ;
7689 default:
7690 break ;
7691 }
7692 }
7693 else if ( table == 4 )
7694 {
7695 switch( tempdi[ i ].DATAPTR )
7696 {
7697 case 0:
7698 return &XGI_ExtLCD1024x768Data[ tempal ] ;
7699 break ;
7700 case 1:
7701 return &XGI_StLCD1024x768Data[ tempal ] ;
7702 break ;
7703 case 2:
7704 return &XGI_CetLCD1024x768Data[ tempal ] ;
7705 break ;
7706 case 3:
7707 return &XGI_ExtLCD1280x1024Data[ tempal ] ;
7708 break ;
7709 case 4:
7710 return &XGI_StLCD1280x1024Data[ tempal ] ;
7711 break ;
7712 case 5:
7713 return &XGI_CetLCD1280x1024Data[ tempal ] ;
7714 break ;
7715 case 6:
7716 return &XGI_ExtLCD1400x1050Data[ tempal ] ;
7717 break ;
7718 case 7:
7719 return &XGI_StLCD1400x1050Data[ tempal ] ;
7720 break ;
7721 case 8:
7722 return &XGI_CetLCD1400x1050Data[ tempal ] ;
7723 break ;
7724 case 9:
7725 return &XGI_ExtLCD1600x1200Data[ tempal ] ;
7726 break ;
7727 case 10:
7728 return &XGI_StLCD1600x1200Data[ tempal ] ;
7729 break ;
7730 case 11:
7731 return &XGI_NoScalingData[ tempal ] ;
7732 break ;
7733 case 12:
7734 return &XGI_ExtLCD1024x768x75Data[ tempal ] ;
7735 break ;
7736 case 13:
7737 return &XGI_ExtLCD1024x768x75Data[ tempal ] ;
7738 break ;
7739 case 14:
7740 return &XGI_CetLCD1024x768x75Data[ tempal ] ;
7741 break ;
7742 case 15:
7743 return &XGI_ExtLCD1280x1024x75Data[ tempal ] ;
7744 break ;
7745 case 16:
7746 return &XGI_StLCD1280x1024x75Data[ tempal ] ;
7747 break;
7748 case 17:
7749 return &XGI_CetLCD1280x1024x75Data[ tempal ] ;
7750 break;
7751 case 18:
7752 return &XGI_NoScalingDatax75[ tempal ] ;
7753 break ;
7754 default:
7755 break ;
7756 }
7757 }
7758 else if ( table == 5 )
7759 {
7760 switch( tempdi[ i ].DATAPTR )
7761 {
7762 case 0:
7763 return &XGI_ExtLCDDes1024x768Data[ tempal ] ;
7764 break ;
7765 case 1:
7766 return &XGI_StLCDDes1024x768Data[ tempal ] ;
7767 break ;
7768 case 2:
7769 return &XGI_CetLCDDes1024x768Data[ tempal ] ;
7770 break ;
7771 case 3:
7772 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7773 return &XGI_ExtLCDDLDes1280x1024Data[ tempal ] ;
7774 else
7775 return &XGI_ExtLCDDes1280x1024Data[ tempal ] ;
7776 break ;
7777 case 4:
7778 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7779 return &XGI_StLCDDLDes1280x1024Data[ tempal ] ;
7780 else
7781 return &XGI_StLCDDes1280x1024Data[ tempal ] ;
7782 break ;
7783 case 5:
7784 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7785 return &XGI_CetLCDDLDes1280x1024Data[ tempal ] ;
7786 else
7787 return &XGI_CetLCDDes1280x1024Data[ tempal ] ;
7788 break ;
7789 case 6:
7790 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7791 return &XGI_ExtLCDDLDes1400x1050Data[ tempal ] ;
7792 else
7793 return &XGI_ExtLCDDes1400x1050Data[ tempal ] ;
7794 break ;
7795 case 7:
7796 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7797 return &XGI_StLCDDLDes1400x1050Data[ tempal ] ;
7798 else
7799 return &XGI_StLCDDes1400x1050Data[ tempal ] ;
7800 break ;
7801 case 8:
7802 return &XGI_CetLCDDes1400x1050Data[ tempal ] ;
7803 break ;
7804 case 9:
7805 return &XGI_CetLCDDes1400x1050Data2[ tempal ] ;
7806 break ;
7807 case 10:
7808 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7809 return &XGI_ExtLCDDLDes1600x1200Data[ tempal ] ;
7810 else
7811 return &XGI_ExtLCDDes1600x1200Data[ tempal ] ;
7812 break ;
7813 case 11:
7814 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7815 return &XGI_StLCDDLDes1600x1200Data[ tempal ] ;
7816 else
7817 return &XGI_StLCDDes1600x1200Data[ tempal ] ;
7818 break ;
7819 case 12:
7820 return &XGI_NoScalingDesData[ tempal ] ;
7821 break;
7822 case 13:
7823 return &XGI_ExtLCDDes1024x768x75Data[ tempal ] ;
7824 break ;
7825 case 14:
7826 return &XGI_StLCDDes1024x768x75Data[ tempal ] ;
7827 break ;
7828 case 15:
7829 return &XGI_CetLCDDes1024x768x75Data[ tempal ] ;
7830 break ;
7831 case 16:
7832 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7833 return &XGI_ExtLCDDLDes1280x1024x75Data[ tempal ] ;
7834 else
7835 return &XGI_ExtLCDDes1280x1024x75Data[ tempal ] ;
7836 break ;
7837 case 17:
7838 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7839 return &XGI_StLCDDLDes1280x1024x75Data[ tempal ] ;
7840 else
7841 return &XGI_StLCDDes1280x1024x75Data[ tempal ] ;
7842 break ;
7843 case 18:
7844 if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
7845 return &XGI_CetLCDDLDes1280x1024x75Data[ tempal ] ;
7846 else
7847 return &XGI_CetLCDDes1280x1024x75Data[ tempal ] ;
7848 break ;
7849 case 19:
7850 return &XGI_NoScalingDesDatax75[ tempal ] ;
7851 break ;
7852 default:
7853 break ;
7854 }
7855 }
7856 else if ( table == 6 )
7857 {
7858 switch( tempdi[ i ].DATAPTR )
7859 {
7860 case 0:
7861 return &XGI_CH7017LV1024x768[ tempal ] ;
7862 break ;
7863 case 1:
7864 return &XGI_CH7017LV1400x1050[ tempal ] ;
7865 break ;
7866 default:
7867 break ;
7868 }
7869 }
7870 return 0 ;
7871}
7872
7873
7874/* --------------------------------------------------------------------- */
7875/* Function : XGI_GetTVPtr */
7876/* Input : */
7877/* Output : */
7878/* Description : */
7879/* --------------------------------------------------------------------- */
7880void* XGI_GetTVPtr (USHORT BX,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
7881{
7882 USHORT i , tempdx , tempbx , tempal , modeflag , table ;
7883 XGI330_TVDataTablStruct *tempdi = 0 ;
7884
7885 tempbx = BX ;
7886
7887 if ( ModeNo <= 0x13 )
7888 {
7889 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
7890 tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
7891 }
7892 else
7893 {
7894 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
7895 tempal = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
7896 }
7897
7898 tempal = tempal & 0x3f ;
7899 table = tempbx ;
7900
7901 switch( tempbx )
7902 {
7903 case 0:
7904 tempdi = 0 ; /*EPLCHTVCRT1Ptr_H;*/
7905 if ( pVBInfo->IF_DEF_CH7007 == 1 )
7906 {
7907 tempdi = XGI_EPLCHTVCRT1Ptr;
7908 }
7909 break ;
7910 case 1:
7911 tempdi = 0 ; /*EPLCHTVCRT1Ptr_V;*/
7912 if ( pVBInfo->IF_DEF_CH7007 == 1 )
7913 {
7914 tempdi = XGI_EPLCHTVCRT1Ptr;
7915 }
7916 break ;
7917 case 2:
7918 tempdi = XGI_EPLCHTVDataPtr ;
7919 break ;
7920 case 3:
7921 tempdi = 0 ;
7922 break ;
7923 case 4:
7924 tempdi = XGI_TVDataTable ;
7925 break ;
7926 case 5:
7927 tempdi = 0 ;
7928 break ;
7929 case 6:
7930 tempdi = XGI_EPLCHTVRegPtr ;
7931 break ;
7932 default:
7933 break ;
7934 }
7935
7936 if ( tempdi == 0x00 ) /* OEMUtil */
7937 return( 0 ) ;
7938
7939 tempdx = pVBInfo->TVInfo ;
7940
7941 if ( pVBInfo->VBInfo & SetInSlaveMode )
7942 tempdx = tempdx | SetTVLockMode ;
7943
7944 if ( modeflag & HalfDCLK )
7945 tempdx = tempdx | SetTVLowResolution ;
7946
7947 i = 0 ;
7948
7949 while( tempdi[ i ].MASK != 0xffff )
7950 {
7951 if ( ( tempdx & tempdi[ i ].MASK ) == tempdi[ i ].CAP )
7952 break ;
7953 i++ ;
7954 }
7955
7956 if ( table == 0x00 ) /* 07/05/22 */
7957 {
7958#ifdef WIN2000
7959 if ( pVBInfo->IF_DEF_CH7007 == 1 )
7960 {
7961 switch( tempdi[ i ].DATAPTR )
7962 {
7963 case 0:
7964 return &CH7007TVCRT1UNTSC_H[ tempal ] ;
7965 break ;
7966 case 1:
7967 return &CH7007TVCRT1ONTSC_H[ tempal ] ;
7968 break ;
7969 case 2:
7970 return &CH7007TVCRT1UPAL_H[ tempal ] ;
7971 break ;
7972 case 3:
7973 return &CH7007TVCRT1OPAL_H[ tempal ] ;
7974 break ;
7975 default:
7976 break ;
7977 }
7978 }
7979#endif
7980 }
7981 else if ( table == 0x01 )
7982 {
7983#ifdef WIN2000
7984 if ( pVBInfo->IF_DEF_CH7007 == 1 )
7985 {
7986 switch( tempdi[ i ].DATAPTR )
7987 {
7988 case 0:
7989 return &CH7007TVCRT1UNTSC_V[ tempal ] ;
7990 break ;
7991 case 1:
7992 return &CH7007TVCRT1ONTSC_V[ tempal ] ;
7993 break ;
7994 case 2:
7995 return &CH7007TVCRT1UPAL_V[ tempal ] ;
7996 break ;
7997 case 3:
7998 return &CH7007TVCRT1OPAL_V[ tempal ] ;
7999 break ;
8000 default:
8001 break ;
8002 }
8003 }
8004#endif
8005 }
8006 else if ( table == 0x04 )
8007 {
8008 switch( tempdi[ i ].DATAPTR )
8009 {
8010 case 0:
8011 return &XGI_ExtPALData[ tempal ] ;
8012 break ;
8013 case 1:
8014 return &XGI_ExtNTSCData[ tempal ] ;
8015 break ;
8016 case 2:
8017 return &XGI_StPALData[ tempal ] ;
8018 break ;
8019 case 3:
8020 return &XGI_StNTSCData[ tempal ] ;
8021 break ;
8022 case 4:
8023 return &XGI_ExtHiTVData[ tempal ] ;
8024 break ;
8025 case 5:
8026 return &XGI_St2HiTVData[ tempal ] ;
8027 break ;
8028 case 6:
8029 return &XGI_ExtYPbPr525iData[ tempal ] ;
8030 break ;
8031 case 7:
8032 return &XGI_ExtYPbPr525pData[ tempal ] ;
8033 break ;
8034 case 8:
8035 return &XGI_ExtYPbPr750pData[ tempal ] ;
8036 break ;
8037 case 9:
8038 return &XGI_StYPbPr525iData[ tempal ] ;
8039 break ;
8040 case 10:
8041 return &XGI_StYPbPr525pData[ tempal ] ;
8042 break ;
8043 case 11:
8044 return &XGI_StYPbPr750pData[ tempal ] ;
8045 break;
8046 case 12: /* avoid system hang */
8047 return &XGI_ExtNTSCData[ tempal ] ;
8048 break ;
8049 case 13:
8050 return &XGI_St1HiTVData[ tempal ] ;
8051 break ;
8052 default:
8053 break ;
8054 }
8055 }
8056 else if( table == 0x02 )
8057 {
8058 switch( tempdi[ i ].DATAPTR )
8059 {
8060 case 0:
8061 return &XGI_CHTVUNTSCData[ tempal ] ;
8062 break ;
8063 case 1:
8064 return &XGI_CHTVONTSCData[ tempal ] ;
8065 break ;
8066 case 2:
8067 return &XGI_CHTVUPALData[ tempal ] ;
8068 break ;
8069 case 3:
8070 return &XGI_CHTVOPALData[ tempal ] ;
8071 break ;
8072 default:
8073 break ;
8074 }
8075 }
8076 else if( table == 0x06 )
8077 {
8078#ifdef WIN2000
8079 if ( pVBInfo->IF_DEF_CH7007 == 1 )
8080 {
8081 /* VideoDebugPrint((0, "XGI_GetTVPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
8082 switch( tempdi[ i ].DATAPTR )
8083 {
8084 case 0:
8085 return &CH7007TVReg_UNTSC[ tempal ] ;
8086 break ;
8087 case 1:
8088 return &CH7007TVReg_ONTSC[ tempal ] ;
8089 break ;
8090 case 2:
8091 return &CH7007TVReg_UPAL[ tempal ] ;
8092 break ;
8093 case 3:
8094 return &CH7007TVReg_OPAL[ tempal ] ;
8095 break ;
8096 default:
8097 break ;
8098 }
8099 }
8100 else
8101 {
8102 switch( tempdi[ i ].DATAPTR )
8103 {
8104 case 0:
8105 return &XGI_CHTVRegUNTSC[ tempal ] ;
8106 break ;
8107 case 1:
8108 return &XGI_CHTVRegONTSC[ tempal ] ;
8109 break ;
8110 case 2:
8111 return &XGI_CHTVRegUPAL[ tempal ] ;
8112 break ;
8113 case 3:
8114 return &XGI_CHTVRegOPAL[ tempal ] ;
8115 break ;
8116 default:
8117 break ;
8118 }
8119 }
8120#endif
8121 }
8122 return( 0 ) ;
8123}
8124
8125
8126/* --------------------------------------------------------------------- */
8127/* Function : XGI_BacklightByDrv */
8128/* Input : */
8129/* Output : TRUE -> Skip backlight control */
8130/* Description : */
8131/* --------------------------------------------------------------------- */
8132BOOLEAN XGI_BacklightByDrv( PVB_DEVICE_INFO pVBInfo )
8133{
8134 UCHAR tempah ;
8135
8136 tempah = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x3A ) ;
8137 if ( tempah & BacklightControlBit )
8138 return TRUE ;
8139 else
8140 return FALSE ;
8141}
8142
8143
8144/* --------------------------------------------------------------------- */
8145/* Function : XGI_FirePWDDisable */
8146/* Input : */
8147/* Output : */
8148/* Description : Turn off VDD & Backlight : Fire disable procedure */
8149/* --------------------------------------------------------------------- */
8150/*
8151void XGI_FirePWDDisable( PVB_DEVICE_INFO pVBInfo )
8152{
8153 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x26 , 0x00 , 0xFC ) ;
8154}
8155*/
8156
8157/* --------------------------------------------------------------------- */
8158/* Function : XGI_FirePWDEnable */
8159/* Input : */
8160/* Output : */
8161/* Description : Turn on VDD & Backlight : Fire enable procedure */
8162/* --------------------------------------------------------------------- */
8163void XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo )
8164{
8165 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x26 , 0x03 , 0xFC ) ;
8166}
8167
8168
8169/* --------------------------------------------------------------------- */
8170/* Function : XGI_EnableGatingCRT */
8171/* Input : */
8172/* Output : */
8173/* Description : */
8174/* --------------------------------------------------------------------- */
8175void XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
8176{
8177 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x63 , 0xBF , 0x40 ) ;
8178}
8179
8180
8181/* --------------------------------------------------------------------- */
8182/* Function : XGI_DisableGatingCRT */
8183/* Input : */
8184/* Output : */
8185/* Description : */
8186/* --------------------------------------------------------------------- */
8187void XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
8188{
8189
8190 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x63 , 0xBF , 0x00 ) ;
8191}
8192
8193
8194/* --------------------------------------------------------------------- */
8195/* Function : XGI_SetPanelDelay */
8196/* Input : */
8197/* Output : */
8198/* Description : */
8199/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
8200/* : bl : 2 ; T2 : the duration signal on and Vdd on */
8201/* : bl : 3 ; T3 : the duration between CPL off and signal off */
8202/* : bl : 4 ; T4 : the duration signal off and Vdd off */
8203/* --------------------------------------------------------------------- */
8204void XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
8205{
8206 USHORT index ;
8207
8208 index = XGI_GetLCDCapPtr(pVBInfo) ;
8209
8210 if ( tempbl == 1 )
8211 XGINew_LCD_Wait_Time( pVBInfo->LCDCapList[ index ].PSC_S1, pVBInfo ) ;
8212
8213 if ( tempbl == 2 )
8214 XGINew_LCD_Wait_Time( pVBInfo->LCDCapList[ index ].PSC_S2, pVBInfo ) ;
8215
8216 if ( tempbl == 3 )
8217 XGINew_LCD_Wait_Time( pVBInfo->LCDCapList[ index ].PSC_S3, pVBInfo ) ;
8218
8219 if ( tempbl == 4 )
8220 XGINew_LCD_Wait_Time( pVBInfo->LCDCapList[ index ].PSC_S4, pVBInfo ) ;
8221}
8222
8223
8224/* --------------------------------------------------------------------- */
8225/* Function : XGI_SetPanelPower */
8226/* Input : */
8227/* Output : */
8228/* Description : */
8229/* I/O : ah = 0011b = 03h ; Backlight on, Power on */
8230/* = 0111b = 07h ; Backlight on, Power off */
8231/* = 1011b = 0Bh ; Backlight off, Power on */
8232/* = 1111b = 0Fh ; Backlight off, Power off */
8233/* --------------------------------------------------------------------- */
8234void XGI_SetPanelPower(USHORT tempah,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
8235{
8236 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
8237 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x26 , tempbl , tempah ) ;
8238 else
8239 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x11 , tempbl , tempah ) ;
8240}
8241
8242UCHAR XG21GPIODataTransfer(UCHAR ujDate)
8243{
8244 UCHAR ujRet = 0;
8245 UCHAR i = 0;
8246
8247 for (i=0; i<8; i++)
8248 {
8249 ujRet = ujRet << 1;
8250 /* ujRet |= GETBITS(ujDate >> i, 0:0); */
8251 ujRet |= (ujDate >> i) & 1;
8252 }
8253
8254 return ujRet;
8255}
8256
8257/*----------------------------------------------------------------------------*/
8258/* output */
8259/* bl[5] : LVDS signal */
8260/* bl[1] : LVDS backlight */
8261/* bl[0] : LVDS VDD */
8262/*----------------------------------------------------------------------------*/
8263UCHAR XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo)
8264{
8265 UCHAR CR4A,temp;
8266
8267 CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
8268 XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x23 ) ; /* enable GPIO write */
8269
8270 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
8271
8272 temp = XG21GPIODataTransfer(temp);
8273 temp &= 0x23;
8274 XGINew_SetReg1( pVBInfo->P3d4 , 0x4A , CR4A ) ;
8275 return temp;
8276}
8277
8278/*----------------------------------------------------------------------------*/
8279/* output */
8280/* bl[5] : LVDS signal */
8281/* bl[1] : LVDS backlight */
8282/* bl[0] : LVDS VDD */
8283/*----------------------------------------------------------------------------*/
8284UCHAR XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo)
8285{
8286 UCHAR CR4A,CRB4,temp;
8287
8288 CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
8289 XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x0C ) ; /* enable GPIO write */
8290
8291 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
8292
8293 temp &= 0x0C;
8294 temp >>= 2;
8295 XGINew_SetReg1( pVBInfo->P3d4 , 0x4A , CR4A ) ;
8296 CRB4 = XGINew_GetReg1( pVBInfo->P3d4 , 0xB4 ) ;
8297 temp |= ((CRB4&0x04)<<3);
8298 return temp;
8299}
8300/*----------------------------------------------------------------------------*/
8301/* input */
8302/* bl[5] : 1;LVDS signal on */
8303/* bl[1] : 1;LVDS backlight on */
8304/* bl[0] : 1:LVDS VDD on */
8305/* bh: 100000b : clear bit 5, to set bit5 */
8306/* 000010b : clear bit 1, to set bit1 */
8307/* 000001b : clear bit 0, to set bit0 */
8308/*----------------------------------------------------------------------------*/
8309void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
8310{
8311 UCHAR CR4A,temp;
8312
8313 CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
8314 tempbh &= 0x23;
8315 tempbl &= 0x23;
8316 XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~tempbh ) ; /* enable GPIO write */
8317
8318 if (tempbh&0x20)
8319 {
8320 temp = (tempbl>>4)&0x02;
8321
8322 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0xB4 , ~0x02 , temp) ; /* CR B4[1] */
8323
8324 }
8325
8326 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
8327
8328 temp = XG21GPIODataTransfer(temp);
8329 temp &= ~tempbh;
8330 temp |= tempbl;
8331 XGINew_SetReg1( pVBInfo->P3d4 , 0x48 , temp ) ;
8332}
8333
8334void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
8335{
8336 UCHAR CR4A,temp;
8337 USHORT tempbh0,tempbl0;
8338
8339 tempbh0 = tempbh;
8340 tempbl0 = tempbl;
8341 tempbh0 &= 0x20;
8342 tempbl0 &= 0x20;
8343 tempbh0 >>= 3;
8344 tempbl0 >>= 3;
8345
8346 if (tempbh&0x20)
8347 {
8348 temp = (tempbl>>4)&0x02;
8349
8350 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0xB4 , ~0x02 , temp) ; /* CR B4[1] */
8351
8352 }
8353 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0xB4 , ~tempbh0 , tempbl0 ) ;
8354
8355 CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
8356 tempbh &= 0x03;
8357 tempbl &= 0x03;
8358 tempbh <<= 2;
8359 tempbl <<= 2; /* GPIOC,GPIOD */
8360 XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~tempbh ) ; /* enable GPIO write */
8361 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x48 , ~tempbh , tempbl ) ;
8362}
8363
8364/* --------------------------------------------------------------------- */
8365USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo)
8366{
8367 USHORT index ;
8368
8369 index = XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ;
8370 if (index<sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct))
8371 {
8372 return index;
8373 }
8374 return 0;
8375}
8376
8377/* --------------------------------------------------------------------- */
8378/* Function : XGI_XG21SetPanelDelay */
8379/* Input : */
8380/* Output : */
8381/* Description : */
8382/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
8383/* : bl : 2 ; T2 : the duration signal on and Vdd on */
8384/* : bl : 3 ; T3 : the duration between CPL off and signal off */
8385/* : bl : 4 ; T4 : the duration signal off and Vdd off */
8386/* --------------------------------------------------------------------- */
8387void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
8388{
8389 USHORT index ;
8390
8391 index = XGI_GetLVDSOEMTableIndex( pVBInfo );
8392 if ( tempbl == 1 )
8393 XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S1, pVBInfo ) ;
8394
8395 if ( tempbl == 2 )
8396 XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S2, pVBInfo ) ;
8397
8398 if ( tempbl == 3 )
8399 XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S3, pVBInfo ) ;
8400
8401 if ( tempbl == 4 )
8402 XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S4, pVBInfo ) ;
8403}
8404
8405BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
8406{
8407 USHORT xres ,
8408 yres ,
8409 colordepth ,
8410 modeflag ,
8411 resindex ,
8412 lvdstableindex;
8413
8414 resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
8415 if ( ModeNo <= 0x13 )
8416 {
8417 xres = pVBInfo->StResInfo[ resindex ].HTotal ;
8418 yres = pVBInfo->StResInfo[ resindex ].VTotal ;
8419 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
8420 }
8421 else
8422 {
8423 xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
8424 yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
8425 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
8426 }
8427
8428 if ( !( modeflag & Charx8Dot ) )
8429 {
8430 xres /= 9;
8431 xres *= 8;
8432 }
8433
8434 if ( ModeNo > 0x13 )
8435 {
8436 if ( ( ModeNo>0x13 ) && ( modeflag & HalfDCLK ) )
8437 {
8438 xres *= 2 ;
8439 }
8440 if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
8441 {
8442 yres *= 2 ;
8443 }
8444 }
8445
8446 lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
8447 if ( xres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) )
8448 return FALSE;
8449
8450 if ( yres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE) )
8451 return FALSE;
8452
8453 if ( ModeNo > 0x13 )
8454 {
8455 if ( ( xres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) ) ||
8456 ( yres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE)) )
8457 {
8458 colordepth = XGI_GetColorDepth( ModeNo , ModeIdIndex, pVBInfo ) ;
8459 if ( colordepth > 2 )
8460 {
8461 return FALSE;
8462 }
8463 }
8464 }
8465 return TRUE;
8466}
8467
8468void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
8469{
8470 UCHAR temp;
8471
8472 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ; /* D[0] 1: 18bit */
8473 temp = ( temp & 1 ) << 6;
8474 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x06 , ~0x40 , temp ) ; /* SR06[6] 18bit Dither */
8475 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0xc0 , temp | 0x80 ) ; /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
8476
8477}
8478
8479void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
8480{
8481 UCHAR temp;
8482
8483 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ; /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
8484 temp = ( temp & 3 ) << 6;
8485 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x06 , ~0xc0 , temp & 0x80 ) ; /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
8486 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0xc0 , temp | 0x80 ) ; /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
8487
8488}
8489
8490void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
8491{
8492 UCHAR temp,Miscdata;
8493 USHORT xres ,
8494 yres ,
8495 modeflag ,
8496 resindex ,
8497 lvdstableindex ;
8498 USHORT LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
8499 USHORT LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
8500 USHORT value;
8501
8502 lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
8503
8504 temp = (UCHAR) ( ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8 ) ) >> 8 );
8505 temp &= LCDPolarity;
8506 Miscdata =(UCHAR) XGINew_GetReg2(pVBInfo->P3cc) ;
8507
8508 XGINew_SetReg3( pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
8509
8510 temp = (UCHAR) ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity ) ;
8511 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ; /* SR35[7] FP VSync polarity */
8512 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ; /* SR30[5] FP HSync polarity */
8513
8514 XGI_SetXG21FPBits(pVBInfo);
8515 resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
8516 if ( ModeNo <= 0x13 )
8517 {
8518 xres = pVBInfo->StResInfo[ resindex ].HTotal ;
8519 yres = pVBInfo->StResInfo[ resindex ].VTotal ;
8520 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
8521 }
8522 else
8523 {
8524 xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
8525 yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
8526 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
8527 }
8528
8529 if (!( modeflag & Charx8Dot ))
8530 xres = xres * 8 / 9;
8531
8532 LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
8533
8534 LVDSHBS = xres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE - xres ) / 2 ;
8535 if ( ( ModeNo<=0x13 ) && ( modeflag & HalfDCLK ) )
8536 {
8537 LVDSHBS -= xres/4 ;
8538 }
8539 if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT ;
8540
8541 LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP ;
8542 if (LVDSHRS > LVDSHT) LVDSHRS -= LVDSHT ;
8543
8544 LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC ;
8545 if (LVDSHRE > LVDSHT) LVDSHRE -= LVDSHT ;
8546
8547 LVDSHBE = LVDSHBS + LVDSHT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE ;
8548
8549 LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
8550
8551 LVDSVBS = yres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE - yres ) / 2 ;
8552 if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
8553 {
8554 LVDSVBS += yres/2 ;
8555 }
8556 if (LVDSVBS > LVDSVT) LVDSVBS -= LVDSVT ;
8557
8558 LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP ;
8559 if (LVDSVRS > LVDSVT) LVDSVRS -= LVDSVT ;
8560
8561 LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC ;
8562 if (LVDSVRE > LVDSVT) LVDSVRE -= LVDSVT ;
8563
8564 LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
8565
8566 temp = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
8567 XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ; /* Unlock CRTC */
8568
8569 if (!( modeflag & Charx8Dot ))
8570 {
8571 XGINew_SetRegOR( pVBInfo->P3c4 , 0x1 , 0x1 ) ;
8572 }
8573
8574 /* HT SR0B[1:0] CR00 */
8575 value = ( LVDSHT >> 3 ) - 5;
8576 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0x03 , ( value & 0x300 ) >> 8 ) ;
8577 XGINew_SetReg1( pVBInfo->P3d4 , 0x0 , (value & 0xFF) ) ;
8578
8579 /* HBS SR0B[5:4] CR02 */
8580 value = ( LVDSHBS >> 3 ) - 1;
8581 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0x30 , ( value & 0x300 ) >> 4 ) ;
8582 XGINew_SetReg1( pVBInfo->P3d4 , 0x2 , (value & 0xFF) ) ;
8583
8584 /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
8585 value = ( LVDSHBE >> 3 ) - 1;
8586 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0C , ~0x03 , ( value & 0xC0 ) >> 6 ) ;
8587 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x05 , ~0x80 , ( value & 0x20 ) << 2 ) ;
8588 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x03 , ~0x1F , value & 0x1F ) ;
8589
8590 /* HRS SR0B[7:6] CR04 */
8591 value = ( LVDSHRS >> 3 ) + 2;
8592 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0xC0 , ( value & 0x300 ) >> 2 ) ;
8593 XGINew_SetReg1( pVBInfo->P3d4 , 0x4 , (value & 0xFF) ) ;
8594
8595 /* Panel HRS SR2F[1:0] SR2E[7:0] */
8596 value--;
8597 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x2F , ~0x03 , ( value & 0x300 ) >> 8 ) ;
8598 XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , (value & 0xFF) ) ;
8599
8600 /* HRE SR0C[2] CR05[4:0] */
8601 value = ( LVDSHRE >> 3 ) + 2;
8602 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0C , ~0x04 , ( value & 0x20 ) >> 3 ) ;
8603 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x05 , ~0x1F , value & 0x1F ) ;
8604
8605 /* Panel HRE SR2F[7:2] */
8606 value--;
8607 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x2F , ~0xFC , value << 2 ) ;
8608
8609 /* VT SR0A[0] CR07[5][0] CR06 */
8610 value = LVDSVT - 2 ;
8611 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x01 , ( value & 0x400 ) >> 10 ) ;
8612 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
8613 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x01 , ( value & 0x100 ) >> 8 ) ;
8614 XGINew_SetReg1( pVBInfo->P3d4 , 0x06 , (value & 0xFF) ) ;
8615
8616 /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
8617 value = LVDSVBS - 1 ;
8618 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x04 , ( value & 0x400 ) >> 8 ) ;
8619 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x09 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
8620 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x08 , ( value & 0x100 ) >> 5 ) ;
8621 XGINew_SetReg1( pVBInfo->P3d4 , 0x15 , (value & 0xFF) ) ;
8622
8623 /* VBE SR0A[4] CR16 */
8624 value = LVDSVBE - 1;
8625 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x10 , ( value & 0x100 ) >> 4 ) ;
8626 XGINew_SetReg1( pVBInfo->P3d4 , 0x16 , (value & 0xFF) ) ;
8627
8628 /* VRS SR0A[3] CR7[7][2] CR10 */
8629 value = LVDSVRS - 1 ;
8630 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x08 , ( value & 0x400 ) >> 7 ) ;
8631 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x80 , ( value & 0x200 ) >> 2 ) ;
8632 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x04 , ( value & 0x100 ) >> 6 ) ;
8633 XGINew_SetReg1( pVBInfo->P3d4 , 0x10 , (value & 0xFF) ) ;
8634
8635 /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
8636 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0x03 , ( value & 0x600 ) >> 9 ) ;
8637 XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , (value >> 1) & 0xFF ) ;
8638 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x33 , ~0x01 , value & 0x01 ) ;
8639
8640 /* VRE SR0A[5] CR11[3:0] */
8641 value = LVDSVRE - 1;
8642 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x20 , ( value & 0x10 ) << 1 ) ;
8643 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x11 , ~0x0F , value & 0x0F ) ;
8644
8645 /* Panel VRE SR3F[7:2] */ /* SR3F[7] has to be 0, h/w bug */
8646 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC , ( value << 2 ) & 0x7C ) ;
8647
8648 for ( temp=0, value = 0; temp < 3; temp++)
8649 {
8650
8651 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , value ) ;
8652 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1) ;
8653 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2) ;
8654 value += 0x10;
8655 }
8656
8657 if (!( modeflag & Charx8Dot ))
8658 {
8659 XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
8660 XGINew_SetReg3( pVBInfo->P3c0 , 0x13 ) ; /* set index */
8661 XGINew_SetReg3( pVBInfo->P3c0 , 0x00 ) ; /* set data, panning = 0, shift left 1 dot*/
8662
8663 XGINew_GetReg2( pVBInfo->P3da ) ; /* Enable Attribute */
8664 XGINew_SetReg3( pVBInfo->P3c0 , 0x20 ) ;
8665
8666 XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
8667 }
8668
8669
8670}
8671
8672/* no shadow case */
8673void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
8674{
8675 UCHAR temp,Miscdata;
8676 USHORT xres ,
8677 yres ,
8678 modeflag ,
8679 resindex ,
8680 lvdstableindex ;
8681 USHORT LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
8682 USHORT LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
8683 USHORT value;
8684
8685 lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
8686 temp = (UCHAR) ( ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8 ) ) >> 8 );
8687 temp &= LCDPolarity;
8688 Miscdata =(UCHAR) XGINew_GetReg2(pVBInfo->P3cc) ;
8689
8690 XGINew_SetReg3( pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
8691
8692 temp = (UCHAR) ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity ) ;
8693 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ; /* SR35[7] FP VSync polarity */
8694 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ; /* SR30[5] FP HSync polarity */
8695
8696 XGI_SetXG27FPBits(pVBInfo);
8697 resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
8698 if ( ModeNo <= 0x13 )
8699 {
8700 xres = pVBInfo->StResInfo[ resindex ].HTotal ;
8701 yres = pVBInfo->StResInfo[ resindex ].VTotal ;
8702 modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
8703 }
8704 else
8705 {
8706 xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
8707 yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
8708 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
8709 }
8710
8711 if (!( modeflag & Charx8Dot ))
8712 xres = xres * 8 / 9;
8713
8714 LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
8715
8716 LVDSHBS = xres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE - xres ) / 2 ;
8717 if ( ( ModeNo<=0x13 ) && ( modeflag & HalfDCLK ) )
8718 {
8719 LVDSHBS -= xres/4 ;
8720 }
8721 if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT ;
8722
8723 LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP ;
8724 if (LVDSHRS > LVDSHT) LVDSHRS -= LVDSHT ;
8725
8726 LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC ;
8727 if (LVDSHRE > LVDSHT) LVDSHRE -= LVDSHT ;
8728
8729 LVDSHBE = LVDSHBS + LVDSHT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE ;
8730
8731 LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
8732
8733 LVDSVBS = yres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE - yres ) / 2 ;
8734 if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
8735 {
8736 LVDSVBS += yres/2 ;
8737 }
8738 if (LVDSVBS > LVDSVT) LVDSVBS -= LVDSVT ;
8739
8740 LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP ;
8741 if (LVDSVRS > LVDSVT) LVDSVRS -= LVDSVT ;
8742
8743 LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC ;
8744 if (LVDSVRE > LVDSVT) LVDSVRE -= LVDSVT ;
8745
8746 LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
8747
8748 temp = ( UCHAR )XGINew_GetReg1( pVBInfo->P3d4 , 0x11 ) ;
8749 XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ; /* Unlock CRTC */
8750
8751 if (!( modeflag & Charx8Dot ))
8752 {
8753 XGINew_SetRegOR( pVBInfo->P3c4 , 0x1 , 0x1 ) ;
8754 }
8755
8756 /* HT SR0B[1:0] CR00 */
8757 value = ( LVDSHT >> 3 ) - 5;
8758 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0x03 , ( value & 0x300 ) >> 8 ) ;
8759 XGINew_SetReg1( pVBInfo->P3d4 , 0x0 , (value & 0xFF) ) ;
8760
8761 /* HBS SR0B[5:4] CR02 */
8762 value = ( LVDSHBS >> 3 ) - 1;
8763 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0x30 , ( value & 0x300 ) >> 4 ) ;
8764 XGINew_SetReg1( pVBInfo->P3d4 , 0x2 , (value & 0xFF) ) ;
8765
8766 /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
8767 value = ( LVDSHBE >> 3 ) - 1;
8768 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0C , ~0x03 , ( value & 0xC0 ) >> 6 ) ;
8769 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x05 , ~0x80 , ( value & 0x20 ) << 2 ) ;
8770 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x03 , ~0x1F , value & 0x1F ) ;
8771
8772 /* HRS SR0B[7:6] CR04 */
8773 value = ( LVDSHRS >> 3 ) + 2;
8774 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0xC0 , ( value & 0x300 ) >> 2 ) ;
8775 XGINew_SetReg1( pVBInfo->P3d4 , 0x4 , (value & 0xFF) ) ;
8776
8777 /* Panel HRS SR2F[1:0] SR2E[7:0] */
8778 value--;
8779 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x2F , ~0x03 , ( value & 0x300 ) >> 8 ) ;
8780 XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , (value & 0xFF) ) ;
8781
8782 /* HRE SR0C[2] CR05[4:0] */
8783 value = ( LVDSHRE >> 3 ) + 2;
8784 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0C , ~0x04 , ( value & 0x20 ) >> 3 ) ;
8785 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x05 , ~0x1F , value & 0x1F ) ;
8786
8787 /* Panel HRE SR2F[7:2] */
8788 value--;
8789 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x2F , ~0xFC , value << 2 ) ;
8790
8791 /* VT SR0A[0] CR07[5][0] CR06 */
8792 value = LVDSVT - 2 ;
8793 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x01 , ( value & 0x400 ) >> 10 ) ;
8794 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
8795 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x01 , ( value & 0x100 ) >> 8 ) ;
8796 XGINew_SetReg1( pVBInfo->P3d4 , 0x06 , (value & 0xFF) ) ;
8797
8798 /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
8799 value = LVDSVBS - 1 ;
8800 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x04 , ( value & 0x400 ) >> 8 ) ;
8801 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x09 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
8802 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x08 , ( value & 0x100 ) >> 5 ) ;
8803 XGINew_SetReg1( pVBInfo->P3d4 , 0x15 , (value & 0xFF) ) ;
8804
8805 /* VBE SR0A[4] CR16 */
8806 value = LVDSVBE - 1;
8807 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x10 , ( value & 0x100 ) >> 4 ) ;
8808 XGINew_SetReg1( pVBInfo->P3d4 , 0x16 , (value & 0xFF) ) ;
8809
8810 /* VRS SR0A[3] CR7[7][2] CR10 */
8811 value = LVDSVRS - 1 ;
8812 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x08 , ( value & 0x400 ) >> 7 ) ;
8813 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x80 , ( value & 0x200 ) >> 2 ) ;
8814 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x04 , ( value & 0x100 ) >> 6 ) ;
8815 XGINew_SetReg1( pVBInfo->P3d4 , 0x10 , (value & 0xFF) ) ;
8816
8817 /* Panel VRS SR35[2:0] SR34[7:0] */
8818 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x07 , ( value & 0x700 ) >> 8 ) ;
8819 XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , value & 0xFF ) ;
8820
8821 /* VRE SR0A[5] CR11[3:0] */
8822 value = LVDSVRE - 1;
8823 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x20 , ( value & 0x10 ) << 1 ) ;
8824 XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x11 , ~0x0F , value & 0x0F ) ;
8825
8826 /* Panel VRE SR3F[7:2] */
8827 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC , ( value << 2 ) & 0xFC ) ;
8828
8829 for ( temp=0, value = 0; temp < 3; temp++)
8830 {
8831
8832 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , value ) ;
8833 XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1) ;
8834 XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2) ;
8835 value += 0x10;
8836 }
8837
8838 if (!( modeflag & Charx8Dot ))
8839 {
8840 XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
8841 XGINew_SetReg3( pVBInfo->P3c0 , 0x13 ) ; /* set index */
8842 XGINew_SetReg3( pVBInfo->P3c0 , 0x00 ) ; /* set data, panning = 0, shift left 1 dot*/
8843
8844 XGINew_GetReg2( pVBInfo->P3da ) ; /* Enable Attribute */
8845 XGINew_SetReg3( pVBInfo->P3c0 , 0x20 ) ;
8846
8847 XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
8848 }
8849
8850
8851}
8852
8853/* --------------------------------------------------------------------- */
8854/* Function : XGI_IsLCDON */
8855/* Input : */
8856/* Output : FALSE : Skip PSC Control */
8857/* TRUE: Disable PSC */
8858/* Description : */
8859/* --------------------------------------------------------------------- */
8860BOOLEAN XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo)
8861{
8862 USHORT tempax ;
8863
8864 tempax = pVBInfo->VBInfo ;
8865 if ( tempax & SetCRT2ToDualEdge )
8866 return FALSE ;
8867 else if ( tempax & ( DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode ) )
8868 return TRUE ;
8869
8870 return FALSE ;
8871}
8872
8873
8874/* --------------------------------------------------------------------- */
8875/* Function : XGI_EnablePWD */
8876/* Input : */
8877/* Output : */
8878/* Description : */
8879/* --------------------------------------------------------------------- */
8880void XGI_EnablePWD( PVB_DEVICE_INFO pVBInfo )
8881{
8882 USHORT index ,
8883 temp ;
8884
8885 index = XGI_GetLCDCapPtr(pVBInfo) ;
8886 temp = pVBInfo->LCDCapList[ index ].PWD_2B ;
8887 XGINew_SetReg1( pVBInfo->Part4Port , 0x2B , temp ) ;
8888 XGINew_SetReg1( pVBInfo->Part4Port , 0x2C , pVBInfo->LCDCapList[ index ].PWD_2C ) ;
8889 XGINew_SetReg1( pVBInfo->Part4Port , 0x2D , pVBInfo->LCDCapList[ index ].PWD_2D ) ;
8890 XGINew_SetReg1( pVBInfo->Part4Port , 0x2E , pVBInfo->LCDCapList[ index ].PWD_2E ) ;
8891 XGINew_SetReg1( pVBInfo->Part4Port , 0x2F , pVBInfo->LCDCapList[ index ].PWD_2F ) ;
8892 XGINew_SetRegOR( pVBInfo->Part4Port , 0x27 , 0x80 ) ; /* enable PWD */
8893}
8894
8895
8896/* --------------------------------------------------------------------- */
8897/* Function : XGI_DisablePWD */
8898/* Input : */
8899/* Output : */
8900/* Description : */
8901/* --------------------------------------------------------------------- */
8902void XGI_DisablePWD( PVB_DEVICE_INFO pVBInfo )
8903{
8904 XGINew_SetRegAND( pVBInfo->Part4Port , 0x27 , 0x7F ) ; /* disable PWD */
8905}
8906
8907
8908/* --------------------------------------------------------------------- */
8909/* Function : XGI_DisableChISLCD */
8910/* Input : */
8911/* Output : FALSE -> Not LCD Mode */
8912/* Description : */
8913/* --------------------------------------------------------------------- */
8914BOOLEAN XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo)
8915{
8916 USHORT tempbx ,
8917 tempah ;
8918
8919 tempbx = pVBInfo->SetFlag & ( DisableChA | DisableChB ) ;
8920 tempah = ~( ( USHORT )XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ) ;
8921
8922 if ( tempbx & ( EnableChA | DisableChA ) )
8923 {
8924 if ( !( tempah & 0x08 ) ) /* Chk LCDA Mode */
8925 return FALSE ;
8926 }
8927
8928 if ( !( tempbx & ( EnableChB | DisableChB ) ) )
8929 return FALSE ;
8930
8931 if ( tempah & 0x01 ) /* Chk LCDB Mode */
8932 return TRUE ;
8933
8934 return FALSE ;
8935}
8936
8937
8938/* --------------------------------------------------------------------- */
8939/* Function : XGI_EnableChISLCD */
8940/* Input : */
8941/* Output : 0 -> Not LCD mode */
8942/* Description : */
8943/* --------------------------------------------------------------------- */
8944BOOLEAN XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo)
8945{
8946 USHORT tempbx ,
8947 tempah ;
8948
8949
8950 tempbx = pVBInfo->SetFlag & ( EnableChA | EnableChB ) ;
8951 tempah = ~( ( USHORT )XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ) ;
8952
8953 if ( tempbx & ( EnableChA | DisableChA ) )
8954 {
8955 if ( !( tempah & 0x08 ) ) /* Chk LCDA Mode */
8956 return FALSE ;
8957 }
8958
8959 if ( !( tempbx & ( EnableChB | DisableChB ) ) )
8960 return FALSE ;
8961
8962 if ( tempah & 0x01 ) /* Chk LCDB Mode */
8963 return TRUE ;
8964
8965 return FALSE ;
8966}
8967
8968
8969/* --------------------------------------------------------------------- */
8970/* Function : XGI_GetLCDCapPtr */
8971/* Input : */
8972/* Output : */
8973/* Description : */
8974/* --------------------------------------------------------------------- */
8975USHORT XGI_GetLCDCapPtr( PVB_DEVICE_INFO pVBInfo )
8976{
8977 UCHAR tempal ,
8978 tempah ,
8979 tempbl ,
8980 i ;
8981
8982 tempah = XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ;
8983 tempal = tempah & 0x0F ;
8984 tempah = tempah & 0xF0 ;
8985 i = 0 ;
8986 tempbl = pVBInfo->LCDCapList[ i ].LCD_ID ;
8987
8988 while( tempbl != 0xFF )
8989 {
8990 if ( tempbl & 0x80 ) /* OEMUtil */
8991 {
8992 tempal = tempah ;
8993 tempbl = tempbl & ~( 0x80 ) ;
8994 }
8995
8996 if ( tempal == tempbl )
8997 break ;
8998
8999 i++ ;
9000
9001 tempbl = pVBInfo->LCDCapList[ i ].LCD_ID ;
9002 }
9003
9004 return i ;
9005}
9006
9007
9008/* --------------------------------------------------------------------- */
9009/* Function : XGI_GetLCDCapPtr1 */
9010/* Input : */
9011/* Output : */
9012/* Description : */
9013/* --------------------------------------------------------------------- */
9014USHORT XGI_GetLCDCapPtr1( PVB_DEVICE_INFO pVBInfo )
9015{
9016 USHORT tempah ,
9017 tempal ,
9018 tempbl ,
9019 i ;
9020
9021 tempal = pVBInfo->LCDResInfo ;
9022 tempah = pVBInfo->LCDTypeInfo ;
9023
9024 i = 0 ;
9025 tempbl = pVBInfo->LCDCapList[ i ].LCD_ID;
9026
9027 while( tempbl != 0xFF )
9028 {
9029 if ( ( tempbl & 0x80 ) && ( tempbl != 0x80 ) )
9030 {
9031 tempal = tempah ;
9032 tempbl &= ~0x80 ;
9033 }
9034
9035 if ( tempal == tempbl )
9036 break ;
9037
9038 i++ ;
9039 tempbl = pVBInfo->LCDCapList[ i ].LCD_ID ;
9040 }
9041
9042 if ( tempbl == 0xFF )
9043 {
9044 pVBInfo->LCDResInfo = Panel1024x768 ;
9045 pVBInfo->LCDTypeInfo = 0 ;
9046 i = 0 ;
9047 }
9048
9049 return i ;
9050}
9051
9052
9053/* --------------------------------------------------------------------- */
9054/* Function : XGI_GetLCDSync */
9055/* Input : */
9056/* Output : */
9057/* Description : */
9058/* --------------------------------------------------------------------- */
9059void XGI_GetLCDSync( USHORT* HSyncWidth , USHORT* VSyncWidth, PVB_DEVICE_INFO pVBInfo )
9060{
9061 USHORT Index ;
9062
9063 Index = XGI_GetLCDCapPtr(pVBInfo) ;
9064 *HSyncWidth = pVBInfo->LCDCapList[ Index ].LCD_HSyncWidth ;
9065 *VSyncWidth = pVBInfo->LCDCapList[ Index ].LCD_VSyncWidth ;
9066
9067 return ;
9068}
9069
9070
9071
9072/* --------------------------------------------------------------------- */
9073/* Function : XGI_EnableBridge */
9074/* Input : */
9075/* Output : */
9076/* Description : */
9077/* --------------------------------------------------------------------- */
9078void XGI_EnableBridge( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
9079{
9080 USHORT tempbl ,
9081 tempah ;
9082
9083 if ( pVBInfo->SetFlag == Win9xDOSMode )
9084 {
9085 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9086 {
9087 XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
9088 return ;
9089 }
9090 else /* LVDS or CH7017 */
9091 return ;
9092 }
9093
9094
9095 if ( HwDeviceExtension->jChipType < XG40 )
9096 {
9097 if ( !XGI_DisableChISLCD(pVBInfo) )
9098 {
9099 if ( ( XGI_EnableChISLCD(pVBInfo) ) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) )
9100 {
9101 if ( pVBInfo->LCDInfo & SetPWDEnable )
9102 {
9103 XGI_EnablePWD( pVBInfo);
9104 }
9105 else
9106 {
9107 pVBInfo->LCDInfo &= ( ~SetPWDEnable ) ;
9108 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9109 {
9110 tempbl = 0xFD ;
9111 tempah = 0x02 ;
9112 }
9113 else
9114 {
9115 tempbl = 0xFB ;
9116 tempah = 0x00 ;
9117 }
9118
9119 XGI_SetPanelPower( tempah , tempbl, pVBInfo ) ;
9120 XGI_SetPanelDelay( 1,pVBInfo ) ;
9121 }
9122 }
9123 }
9124 } /* Not 340 */
9125
9126
9127
9128 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9129 {
9130 if ( !( pVBInfo->SetFlag & DisableChA ) )
9131 {
9132 if ( pVBInfo->SetFlag & EnableChA )
9133 {
9134 XGINew_SetReg1( pVBInfo->Part1Port , 0x1E , 0x20 ) ; /* Power on */
9135 }
9136 else
9137 {
9138 if ( pVBInfo->VBInfo & SetCRT2ToDualEdge ) /* SetCRT2ToLCDA ) */
9139 {
9140 XGINew_SetReg1(pVBInfo->Part1Port,0x1E,0x20); /* Power on */
9141 }
9142 }
9143 }
9144
9145 if ( !( pVBInfo->SetFlag & DisableChB ) )
9146 {
9147 if ( ( pVBInfo->SetFlag & EnableChB ) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV | SetCRT2ToRAMDAC ) ) )
9148 {
9149 tempah = ( UCHAR )XGINew_GetReg1( pVBInfo->P3c4 , 0x32 ) ;
9150 tempah &= 0xDF;
9151 if ( pVBInfo->VBInfo & SetInSlaveMode )
9152 {
9153 if ( !( pVBInfo->VBInfo & SetCRT2ToRAMDAC ) )
9154 tempah |= 0x20 ;
9155 }
9156 XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , tempah ) ;
9157 XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x20 ) ;
9158
9159
9160 tempah = ( UCHAR )XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ;
9161
9162 if ( !( tempah & 0x80 ) )
9163 XGINew_SetRegOR( pVBInfo->Part1Port , 0x2E , 0x80 ) ; /* BVBDOENABLE = 1 */
9164
9165 XGINew_SetRegAND( pVBInfo->Part1Port , 0x00 , 0x7F ) ; /* BScreenOFF = 0 */
9166 }
9167 }
9168
9169 if ( ( pVBInfo->SetFlag & ( EnableChA | EnableChB ) ) || ( !( pVBInfo->VBInfo & DisableCRT2Display ) ) )
9170 {
9171 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x00 , ~0xE0 , 0x20 ) ; /* shampoo 0129 */
9172 if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
9173 {
9174 if ( !XGI_DisableChISLCD(pVBInfo) )
9175 {
9176 if ( XGI_EnableChISLCD( pVBInfo) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) )
9177 XGINew_SetRegAND( pVBInfo->Part4Port ,0x2A , 0x7F ) ; /* LVDS PLL power on */
9178 }
9179 XGINew_SetRegAND( pVBInfo->Part4Port , 0x30 , 0x7F ) ; /* LVDS Driver power on */
9180 }
9181 }
9182
9183 tempah = 0x00 ;
9184
9185 if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
9186 {
9187 tempah = 0xc0 ;
9188
9189 if ( !( pVBInfo->VBInfo & SetSimuScanMode ) )
9190 {
9191 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
9192 {
9193 if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
9194 {
9195 tempah = tempah & 0x40;
9196 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
9197 tempah = tempah ^ 0xC0 ;
9198
9199 if ( pVBInfo->SetFlag & DisableChB )
9200 tempah &= 0xBF ;
9201
9202 if ( pVBInfo->SetFlag & DisableChA )
9203 tempah &= 0x7F ;
9204
9205 if ( pVBInfo->SetFlag & EnableChB )
9206 tempah |= 0x40 ;
9207
9208 if ( pVBInfo->SetFlag & EnableChA )
9209 tempah |= 0x80 ;
9210 }
9211 }
9212 }
9213 }
9214
9215 XGINew_SetRegOR( pVBInfo->Part4Port , 0x1F , tempah ) ; /* EnablePart4_1F */
9216
9217 if ( pVBInfo->SetFlag & Win9xDOSMode )
9218 {
9219 XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
9220 return ;
9221 }
9222
9223 if ( !( pVBInfo->SetFlag & DisableChA ) )
9224 {
9225 XGI_VBLongWait( pVBInfo) ;
9226 if ( !( pVBInfo->SetFlag & GatingCRT ) )
9227 {
9228 XGI_DisableGatingCRT( HwDeviceExtension, pVBInfo ) ;
9229 XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
9230 XGI_VBLongWait( pVBInfo) ;
9231 }
9232 }
9233 } /* 301 */
9234 else /* LVDS */
9235 {
9236 if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) )
9237 XGINew_SetRegOR( pVBInfo->Part1Port , 0x1E , 0x20 ) ; /* enable CRT2 */
9238
9239
9240
9241 tempah = ( UCHAR )XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ;
9242 if ( !( tempah & 0x80 ) )
9243 XGINew_SetRegOR( pVBInfo->Part1Port , 0x2E , 0x80 ) ; /* BVBDOENABLE = 1 */
9244
9245 XGINew_SetRegAND(pVBInfo->Part1Port,0x00,0x7F);
9246 XGI_DisplayOn( HwDeviceExtension, pVBInfo);
9247 } /* End of VB */
9248
9249
9250 if ( HwDeviceExtension->jChipType < XG40 )
9251 {
9252 if ( !XGI_EnableChISLCD(pVBInfo) )
9253 {
9254 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
9255 {
9256 if ( XGI_BacklightByDrv(pVBInfo) )
9257 return ;
9258 }
9259 else
9260 return ;
9261 }
9262
9263 if ( pVBInfo->LCDInfo & SetPWDEnable )
9264 {
9265 XGI_FirePWDEnable(pVBInfo) ;
9266 return ;
9267 }
9268
9269 XGI_SetPanelDelay( 2,pVBInfo ) ;
9270
9271 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9272 {
9273 tempah = 0x01 ;
9274 tempbl = 0xFE ; /* turn on backlght */
9275 }
9276 else
9277 {
9278 tempbl = 0xF7 ;
9279 tempah = 0x00 ;
9280 }
9281 XGI_SetPanelPower( tempah , tempbl , pVBInfo) ;
9282 }
9283}
9284
9285
9286/* --------------------------------------------------------------------- */
9287/* Function : XGI_DisableBridge */
9288/* Input : */
9289/* Output : */
9290/* Description : */
9291/* --------------------------------------------------------------------- */
9292void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
9293{
9294 USHORT tempax ,
9295 tempbx ,
9296 tempah = 0 ,
9297 tempbl = 0 ;
9298
9299 if ( pVBInfo->SetFlag == Win9xDOSMode )
9300 return ;
9301
9302
9303 if ( HwDeviceExtension->jChipType < XG40 )
9304 {
9305 if ( ( !( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) ) || ( XGI_DisableChISLCD(pVBInfo) ) )
9306 {
9307 if ( !XGI_IsLCDON(pVBInfo) )
9308 {
9309 if ( pVBInfo->LCDInfo & SetPWDEnable )
9310 XGI_EnablePWD( pVBInfo) ;
9311 else
9312 {
9313 pVBInfo->LCDInfo &= ~SetPWDEnable ;
9314 XGI_DisablePWD(pVBInfo) ;
9315 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9316 {
9317 tempbx = 0xFE ; /* not 01h */
9318 tempax = 0 ;
9319 }
9320 else
9321 {
9322 tempbx = 0xF7 ; /* not 08h */
9323 tempax = 0x08 ;
9324 }
9325 XGI_SetPanelPower( tempax , tempbx , pVBInfo) ;
9326 XGI_SetPanelDelay( 3,pVBInfo ) ;
9327 }
9328 } /* end if(!XGI_IsLCDON(pVBInfo)) */
9329 }
9330 }
9331
9332/* if ( CH7017 )
9333 {
9334 if ( !( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2toLCDA ) ) || ( XGI_DisableChISLCD(pVBInfo) ) )
9335 {
9336 if ( !XGI_IsLCDON(pVBInfo) )
9337 {
9338 if ( DISCHARGE )
9339 {
9340 tempbx = XGINew_GetCH7005( 0x61 ) ;
9341 if ( tempbx < 0x01 ) //first time we power up
9342 XGINew_SetCH7005( 0x0066 ) ; //and disable power sequence
9343 else
9344 XGINew_SetCH7005( 0x5f66 ) ; //leave VDD on - disable power
9345 }
9346 }
9347 }
9348 } */
9349
9350 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B| VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9351 {
9352 tempah = 0x3F ;
9353 if ( !( pVBInfo->VBInfo & ( DisableCRT2Display | SetSimuScanMode ) ) )
9354 {
9355 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
9356 {
9357 if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
9358 {
9359 tempah = 0x7F; /* Disable Channel A */
9360 if ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
9361 tempah = 0xBF ; /* Disable Channel B */
9362
9363 if ( pVBInfo->SetFlag & DisableChB )
9364 tempah &= 0xBF ; /* force to disable Cahnnel */
9365
9366 if ( pVBInfo->SetFlag & DisableChA )
9367 tempah &= 0x7F ; /* Force to disable Channel B */
9368 }
9369 }
9370 }
9371
9372 XGINew_SetRegAND( pVBInfo->Part4Port , 0x1F , tempah ) ; /* disable part4_1f */
9373
9374 if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
9375 {
9376 if ( ( ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) ) || ( XGI_DisableChISLCD(pVBInfo) ) || ( XGI_IsLCDON(pVBInfo) ) )
9377 XGINew_SetRegOR( pVBInfo->Part4Port , 0x30 , 0x80 ) ; /* LVDS Driver power down */
9378 }
9379
9380 if ( ( pVBInfo->SetFlag & DisableChA ) || ( pVBInfo->VBInfo & ( DisableCRT2Display | SetCRT2ToLCDA | SetSimuScanMode ) ) )
9381 {
9382 if ( pVBInfo->SetFlag & GatingCRT )
9383 XGI_EnableGatingCRT( HwDeviceExtension, pVBInfo ) ;
9384 XGI_DisplayOff( HwDeviceExtension, pVBInfo) ;
9385 }
9386
9387 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
9388 {
9389 if ( ( pVBInfo->SetFlag & DisableChA ) || ( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
9390 XGINew_SetRegAND( pVBInfo->Part1Port , 0x1e , 0xdf ) ; /* Power down */
9391 }
9392
9393 XGINew_SetRegAND( pVBInfo->P3c4 , 0x32 , 0xdf ) ; /* disable TV as primary VGA swap */
9394
9395 if ( ( pVBInfo->VBInfo & ( SetSimuScanMode | SetCRT2ToDualEdge ) ) )
9396 XGINew_SetRegAND(pVBInfo->Part2Port,0x00,0xdf);
9397
9398 if ( ( pVBInfo->SetFlag & DisableChB ) || ( pVBInfo->VBInfo & ( DisableCRT2Display | SetSimuScanMode ) )
9399 || ( ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) && ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV ) ) ) )
9400 XGINew_SetRegOR( pVBInfo->Part1Port , 0x00 , 0x80 ) ; /* BScreenOff=1 */
9401
9402 if ( ( pVBInfo->SetFlag & DisableChB ) || ( pVBInfo->VBInfo & ( DisableCRT2Display | SetSimuScanMode ) )
9403 || ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) || ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV ) ) )
9404 {
9405 tempah= XGINew_GetReg1( pVBInfo->Part1Port , 0x00 ) ; /* save Part1 index 0 */
9406 XGINew_SetRegOR( pVBInfo->Part1Port , 0x00 , 0x10 ) ; /* BTDAC = 1, avoid VB reset */
9407 XGINew_SetRegAND( pVBInfo->Part1Port , 0x1E , 0xDF ) ; /* disable CRT2 */
9408 XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , tempah ) ; /* restore Part1 index 0 */
9409 }
9410 }
9411 else /* {301} */
9412 {
9413 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV ) )
9414 {
9415 XGINew_SetRegOR( pVBInfo->Part1Port , 0x00 , 0x80 ) ; /* BScreenOff=1 */
9416 XGINew_SetRegAND( pVBInfo->Part1Port , 0x1E , 0xDF ) ; /* Disable CRT2 */
9417 XGINew_SetRegAND( pVBInfo->P3c4 , 0x32 , 0xDF ) ; /* Disable TV asPrimary VGA swap */
9418 }
9419
9420 if ( pVBInfo->VBInfo & ( DisableCRT2Display | SetCRT2ToLCDA | SetSimuScanMode ) )
9421 XGI_DisplayOff( HwDeviceExtension, pVBInfo) ;
9422 }
9423
9424
9425
9426
9427 if ( HwDeviceExtension->jChipType < XG40 )
9428 {
9429 if ( !( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) || ( XGI_DisableChISLCD(pVBInfo) ) || ( XGI_IsLCDON(pVBInfo) ) )
9430 {
9431 if ( pVBInfo->LCDInfo & SetPWDEnable )
9432 {
9433 if ( pVBInfo->LCDInfo & SetPWDEnable )
9434 XGI_BacklightByDrv(pVBInfo) ;
9435 else
9436 {
9437 XGI_SetPanelDelay( 4 ,pVBInfo) ;
9438 if ( pVBInfo->VBType & VB_XGI301LV )
9439 {
9440 tempbl = 0xFD ;
9441 tempah = 0x00 ;
9442 }
9443 else
9444 {
9445 tempbl = 0xFB ;
9446 tempah = 0x04 ;
9447 }
9448 }
9449 }
9450 XGI_SetPanelPower( tempah , tempbl , pVBInfo) ;
9451 }
9452 }
9453}
9454
9455
9456/* --------------------------------------------------------------------- */
9457/* Function : XGI_GetTVPtrIndex */
9458/* Input : */
9459/* Output : */
9460/* Description : bx 0 : ExtNTSC */
9461/* 1 : StNTSC */
9462/* 2 : ExtPAL */
9463/* 3 : StPAL */
9464/* 4 : ExtHiTV */
9465/* 5 : StHiTV */
9466/* 6 : Ext525i */
9467/* 7 : St525i */
9468/* 8 : Ext525p */
9469/* 9 : St525p */
9470/* A : Ext750p */
9471/* B : St750p */
9472/* --------------------------------------------------------------------- */
9473USHORT XGI_GetTVPtrIndex( PVB_DEVICE_INFO pVBInfo )
9474{
9475 USHORT tempbx = 0 ;
9476
9477 if ( pVBInfo->TVInfo & SetPALTV )
9478 tempbx = 2 ;
9479 if ( pVBInfo->TVInfo & SetYPbPrMode1080i )
9480 tempbx = 4 ;
9481 if ( pVBInfo->TVInfo & SetYPbPrMode525i )
9482 tempbx = 6 ;
9483 if ( pVBInfo->TVInfo & SetYPbPrMode525p )
9484 tempbx = 8 ;
9485 if ( pVBInfo->TVInfo & SetYPbPrMode750p )
9486 tempbx = 10 ;
9487 if ( pVBInfo->TVInfo & TVSimuMode )
9488 tempbx++ ;
9489
9490 return tempbx ;
9491}
9492
9493
9494/* --------------------------------------------------------------------- */
9495/* Function : XGI_OEM310Setting */
9496/* Input : */
9497/* Output : */
9498/* Description : Customized Param. for 301 */
9499/* --------------------------------------------------------------------- */
9500void XGI_OEM310Setting( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
9501{
9502 if ( pVBInfo->SetFlag & Win9xDOSMode )
9503 return ;
9504
9505 /* GetPart1IO(); */
9506 XGI_SetDelayComp(pVBInfo) ;
9507
9508 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
9509 XGI_SetLCDCap(pVBInfo) ;
9510
9511 if ( pVBInfo->VBInfo & SetCRT2ToTV )
9512 {
9513 /* GetPart2IO() */
9514 XGI_SetPhaseIncr(pVBInfo) ;
9515 XGI_SetYFilter( ModeNo , ModeIdIndex,pVBInfo ) ;
9516 XGI_SetAntiFlicker( ModeNo , ModeIdIndex,pVBInfo ) ;
9517
9518 if ( pVBInfo->VBType&VB_XGI301)
9519 XGI_SetEdgeEnhance( ModeNo , ModeIdIndex ,pVBInfo) ;
9520 }
9521}
9522
9523
9524/* --------------------------------------------------------------------- */
9525/* Function : XGI_SetDelayComp */
9526/* Input : */
9527/* Output : */
9528/* Description : */
9529/* --------------------------------------------------------------------- */
9530void XGI_SetDelayComp( PVB_DEVICE_INFO pVBInfo )
9531{
9532 USHORT index ;
9533
9534 UCHAR tempah ,
9535 tempbl ,
9536 tempbh ;
9537
9538 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9539 {
9540 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToTV | SetCRT2ToRAMDAC ) )
9541 {
9542 tempbl = 0;
9543 tempbh = 0;
9544
9545 index = XGI_GetTVPtrIndex(pVBInfo ) ; /* Get TV Delay */
9546 tempbl = pVBInfo->XGI_TVDelayList[ index ] ;
9547
9548 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9549 tempbl = pVBInfo->XGI_TVDelayList2[ index ] ;
9550
9551 if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
9552 tempbl = tempbl >> 4 ;
9553/*
9554 if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
9555 tempbl = CRT2Delay1 ; // Get CRT2 Delay
9556
9557 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9558 tempbl = CRT2Delay2 ;
9559*/
9560 if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
9561 {
9562 index = XGI_GetLCDCapPtr(pVBInfo) ; /* Get LCD Delay */
9563 tempbh=pVBInfo->LCDCapList[ index ].LCD_DelayCompensation ;
9564
9565 if ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
9566 tempbl = tempbh ;
9567 }
9568
9569 tempbl &= 0x0F ;
9570 tempbh &= 0xF0 ;
9571 tempah = XGINew_GetReg1( pVBInfo->Part1Port , 0x2D ) ;
9572
9573 if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV ) ) /* Channel B */
9574 {
9575 tempah &= 0xF0 ;
9576 tempah |= tempbl ;
9577 }
9578
9579 if ( pVBInfo->VBInfo & SetCRT2ToLCDA ) /* Channel A */
9580 {
9581 tempah &= 0x0F ;
9582 tempah |= tempbh ;
9583 }
9584 XGINew_SetReg1(pVBInfo->Part1Port,0x2D,tempah);
9585 }
9586 }
9587 else if ( pVBInfo->IF_DEF_LVDS == 1 )
9588 {
9589 tempbl = 0;
9590 tempbh = 0;
9591 if ( pVBInfo->VBInfo & SetCRT2ToLCD )
9592 {
9593 tempah = pVBInfo->LCDCapList[ XGI_GetLCDCapPtr(pVBInfo) ].LCD_DelayCompensation ; /* / Get LCD Delay */
9594 tempah &= 0x0f ;
9595 tempah = tempah << 4 ;
9596 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2D , 0x0f , tempah ) ;
9597 }
9598 }
9599}
9600
9601
9602/* --------------------------------------------------------------------- */
9603/* Function : XGI_SetLCDCap */
9604/* Input : */
9605/* Output : */
9606/* Description : */
9607/* --------------------------------------------------------------------- */
9608void XGI_SetLCDCap( PVB_DEVICE_INFO pVBInfo )
9609{
9610 USHORT tempcx ;
9611
9612 tempcx = pVBInfo->LCDCapList[ XGI_GetLCDCapPtr(pVBInfo) ].LCD_Capability ;
9613
9614 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9615 {
9616 if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9617 { /* 301LV/302LV only */
9618 /* Set 301LV Capability */
9619 XGINew_SetReg1( pVBInfo->Part4Port , 0x24 , ( UCHAR )( tempcx & 0x1F ) ) ;
9620 }
9621 /* VB Driving */
9622 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x0D , ~( ( EnableVBCLKDRVLOW | EnablePLLSPLOW ) >> 8 ) , ( USHORT )( ( tempcx & ( EnableVBCLKDRVLOW | EnablePLLSPLOW ) ) >> 8 ) ) ;
9623 }
9624
9625 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9626 {
9627 if ( pVBInfo->VBInfo & SetCRT2ToLCD )
9628 XGI_SetLCDCap_B( tempcx,pVBInfo ) ;
9629 else if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
9630 XGI_SetLCDCap_A( tempcx,pVBInfo ) ;
9631
9632 if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
9633 {
9634 if ( tempcx & EnableSpectrum )
9635 SetSpectrum( pVBInfo) ;
9636 }
9637 }
9638 else /* LVDS,CH7017 */
9639 XGI_SetLCDCap_A( tempcx, pVBInfo ) ;
9640}
9641
9642
9643/* --------------------------------------------------------------------- */
9644/* Function : XGI_SetLCDCap_A */
9645/* Input : */
9646/* Output : */
9647/* Description : */
9648/* --------------------------------------------------------------------- */
9649void XGI_SetLCDCap_A(USHORT tempcx,PVB_DEVICE_INFO pVBInfo)
9650{
9651 USHORT temp ;
9652
9653 temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
9654
9655 if ( temp & LCDRGB18Bit )
9656 {
9657 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x19 , 0x0F , ( USHORT )( 0x20 | ( tempcx & 0x00C0 ) ) ) ; /* Enable Dither */
9658 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x1A , 0x7F , 0x80 ) ;
9659 }
9660 else
9661 {
9662 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x19 , 0x0F , ( USHORT )( 0x30 | ( tempcx & 0x00C0 ) ) ) ;
9663 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x1A , 0x7F , 0x00 ) ;
9664 }
9665
9666/*
9667 if ( tempcx & EnableLCD24bpp ) // 24bits
9668 {
9669 XGINew_SetRegANDOR(pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x30|(tempcx&0x00C0)) );
9670 XGINew_SetRegANDOR(pVBInfo->Part1Port,0x1A,0x7F,0x00);
9671 }
9672 else
9673 {
9674 XGINew_SetRegANDOR(pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x20|(tempcx&0x00C0)) );//Enable Dither
9675 XGINew_SetRegANDOR(pVBInfo->Part1Port,0x1A,0x7F,0x80);
9676 }
9677*/
9678}
9679
9680
9681/* --------------------------------------------------------------------- */
9682/* Function : XGI_SetLCDCap_B */
9683/* Input : cx -> LCD Capability */
9684/* Output : */
9685/* Description : */
9686/* --------------------------------------------------------------------- */
9687void XGI_SetLCDCap_B(USHORT tempcx,PVB_DEVICE_INFO pVBInfo)
9688{
9689 if ( tempcx & EnableLCD24bpp ) /* 24bits */
9690 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x1A , 0xE0 , ( USHORT )( ( ( tempcx & 0x00ff ) >> 6 ) | 0x0c ) ) ;
9691 else
9692 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x1A , 0xE0 , ( USHORT )( ( ( tempcx & 0x00ff ) >> 6 ) | 0x18 ) ) ; /* Enable Dither */
9693}
9694
9695
9696/* --------------------------------------------------------------------- */
9697/* Function : SetSpectrum */
9698/* Input : */
9699/* Output : */
9700/* Description : */
9701/* --------------------------------------------------------------------- */
9702void SetSpectrum( PVB_DEVICE_INFO pVBInfo )
9703{
9704 USHORT index ;
9705
9706 index = XGI_GetLCDCapPtr(pVBInfo) ;
9707
9708 XGINew_SetRegAND( pVBInfo->Part4Port , 0x30 , 0x8F ) ; /* disable down spectrum D[4] */
9709 XGI_LongWait(pVBInfo) ;
9710 XGINew_SetRegOR( pVBInfo->Part4Port , 0x30 , 0x20 ) ; /* reset spectrum */
9711 XGI_LongWait(pVBInfo) ;
9712
9713 XGINew_SetReg1( pVBInfo->Part4Port , 0x31 , pVBInfo->LCDCapList[ index ].Spectrum_31 ) ;
9714 XGINew_SetReg1( pVBInfo->Part4Port , 0x32 , pVBInfo->LCDCapList[ index ].Spectrum_32 ) ;
9715 XGINew_SetReg1( pVBInfo->Part4Port , 0x33 , pVBInfo->LCDCapList[ index ].Spectrum_33 ) ;
9716 XGINew_SetReg1( pVBInfo->Part4Port , 0x34 , pVBInfo->LCDCapList[ index ].Spectrum_34 ) ;
9717 XGI_LongWait(pVBInfo) ;
9718 XGINew_SetRegOR( pVBInfo->Part4Port , 0x30 , 0x40 ) ; /* enable spectrum */
9719}
9720
9721
9722/* --------------------------------------------------------------------- */
9723/* Function : XGI_SetAntiFlicker */
9724/* Input : */
9725/* Output : */
9726/* Description : Set TV Customized Param. */
9727/* --------------------------------------------------------------------- */
9728void XGI_SetAntiFlicker( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
9729{
9730 USHORT tempbx ,
9731 index ;
9732
9733 UCHAR tempah ;
9734
9735 if (pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
9736 return ;
9737
9738 tempbx = XGI_GetTVPtrIndex(pVBInfo ) ;
9739 tempbx &= 0xFE ;
9740
9741 if ( ModeNo <= 0x13 )
9742 {
9743 index = pVBInfo->SModeIDTable[ ModeIdIndex ].VB_StTVFlickerIndex ;
9744 }
9745 else
9746 {
9747 index = pVBInfo->EModeIDTable[ ModeIdIndex ].VB_ExtTVFlickerIndex ;
9748 }
9749
9750 tempbx += index ;
9751 tempah = TVAntiFlickList[ tempbx ] ;
9752 tempah = tempah << 4 ;
9753
9754 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x0A , 0x8F , tempah ) ;
9755}
9756
9757
9758/* --------------------------------------------------------------------- */
9759/* Function : XGI_SetEdgeEnhance */
9760/* Input : */
9761/* Output : */
9762/* Description : */
9763/* --------------------------------------------------------------------- */
9764void XGI_SetEdgeEnhance( USHORT ModeNo , USHORT ModeIdIndex , PVB_DEVICE_INFO pVBInfo)
9765{
9766 USHORT tempbx ,
9767 index ;
9768
9769 UCHAR tempah ;
9770
9771
9772 tempbx = XGI_GetTVPtrIndex(pVBInfo ) ;
9773 tempbx &= 0xFE ;
9774
9775 if ( ModeNo <= 0x13 )
9776 {
9777 index = pVBInfo->SModeIDTable[ ModeIdIndex ].VB_StTVEdgeIndex ;
9778 }
9779 else
9780 {
9781 index = pVBInfo->EModeIDTable[ ModeIdIndex ].VB_ExtTVEdgeIndex ;
9782 }
9783
9784 tempbx += index ;
9785 tempah = TVEdgeList[ tempbx ] ;
9786 tempah = tempah << 5 ;
9787
9788 XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x3A , 0x1F , tempah ) ;
9789}
9790
9791
9792/* --------------------------------------------------------------------- */
9793/* Function : XGI_SetPhaseIncr */
9794/* Input : */
9795/* Output : */
9796/* Description : */
9797/* --------------------------------------------------------------------- */
9798void XGI_SetPhaseIncr( PVB_DEVICE_INFO pVBInfo )
9799{
9800 USHORT tempbx ;
9801
9802 UCHAR tempcl ,
9803 tempch ;
9804
9805 ULONG tempData ;
9806
9807 XGI_GetTVPtrIndex2( &tempbx , &tempcl , &tempch, pVBInfo ) ; /* bx, cl, ch */
9808 tempData = TVPhaseList[ tempbx ] ;
9809
9810 XGINew_SetReg1( pVBInfo->Part2Port , 0x31 , ( USHORT )( tempData & 0x000000FF ) ) ;
9811 XGINew_SetReg1( pVBInfo->Part2Port , 0x32 , ( USHORT )( ( tempData & 0x0000FF00 ) >> 8 ) ) ;
9812 XGINew_SetReg1( pVBInfo->Part2Port , 0x33 , ( USHORT )( ( tempData & 0x00FF0000 ) >> 16 ) ) ;
9813 XGINew_SetReg1( pVBInfo->Part2Port , 0x34 , ( USHORT )( ( tempData & 0xFF000000 ) >> 24 ) ) ;
9814}
9815
9816
9817/* --------------------------------------------------------------------- */
9818/* Function : XGI_SetYFilter */
9819/* Input : */
9820/* Output : */
9821/* Description : */
9822/* --------------------------------------------------------------------- */
9823void XGI_SetYFilter( USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
9824{
9825 USHORT tempbx ,
9826 index ;
9827
9828 UCHAR tempcl ,
9829 tempch ,
9830 tempal ,
9831 *filterPtr ;
9832
9833 XGI_GetTVPtrIndex2( &tempbx , &tempcl , &tempch, pVBInfo ) ; /* bx, cl, ch */
9834
9835 switch( tempbx )
9836 {
9837 case 0x00:
9838 case 0x04:
9839 filterPtr = NTSCYFilter1 ;
9840 break ;
9841
9842 case 0x01:
9843 filterPtr = PALYFilter1 ;
9844 break ;
9845
9846 case 0x02:
9847 case 0x05:
9848 case 0x0D:
9849 filterPtr = PALMYFilter1 ;
9850 break ;
9851
9852 case 0x03:
9853 filterPtr = PALNYFilter1 ;
9854 break ;
9855
9856 case 0x08:
9857 case 0x0C:
9858 filterPtr = NTSCYFilter2 ;
9859 break ;
9860
9861 case 0x0A:
9862 filterPtr = PALMYFilter2 ;
9863 break ;
9864
9865 case 0x0B:
9866 filterPtr = PALNYFilter2 ;
9867 break ;
9868
9869 case 0x09:
9870 filterPtr = PALYFilter2 ;
9871 break ;
9872
9873 default:
9874 return ;
9875 }
9876
9877 if ( ModeNo <= 0x13 )
9878 tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].VB_StTVYFilterIndex ;
9879 else
9880 tempal = pVBInfo->EModeIDTable[ ModeIdIndex ].VB_ExtTVYFilterIndex ;
9881
9882 if ( tempcl == 0 )
9883 index = tempal * 4;
9884 else
9885 index = tempal * 7;
9886
9887 if ( ( tempcl == 0 ) && ( tempch == 1 ) )
9888 {
9889 XGINew_SetReg1( pVBInfo->Part2Port , 0x35 , 0 ) ;
9890 XGINew_SetReg1( pVBInfo->Part2Port , 0x36 , 0 ) ;
9891 XGINew_SetReg1( pVBInfo->Part2Port , 0x37 , 0 ) ;
9892 XGINew_SetReg1( pVBInfo->Part2Port , 0x38 , filterPtr[ index++ ] ) ;
9893 }
9894 else
9895 {
9896 XGINew_SetReg1( pVBInfo->Part2Port , 0x35 , filterPtr[ index++ ] ) ;
9897 XGINew_SetReg1( pVBInfo->Part2Port , 0x36 , filterPtr[ index++ ] ) ;
9898 XGINew_SetReg1( pVBInfo->Part2Port , 0x37 , filterPtr[ index++ ] ) ;
9899 XGINew_SetReg1( pVBInfo->Part2Port , 0x38 , filterPtr[ index++ ] ) ;
9900 }
9901
9902 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9903 {
9904 XGINew_SetReg1( pVBInfo->Part2Port , 0x48 , filterPtr[ index++ ] ) ;
9905 XGINew_SetReg1( pVBInfo->Part2Port , 0x49 , filterPtr[ index++ ] ) ;
9906 XGINew_SetReg1( pVBInfo->Part2Port , 0x4A , filterPtr[ index++ ] ) ;
9907 }
9908}
9909
9910
9911/* --------------------------------------------------------------------- */
9912/* Function : XGI_GetTVPtrIndex2 */
9913/* Input : */
9914/* Output : bx 0 : NTSC */
9915/* 1 : PAL */
9916/* 2 : PALM */
9917/* 3 : PALN */
9918/* 4 : NTSC1024x768 */
9919/* 5 : PAL-M 1024x768 */
9920/* 6-7: reserved */
9921/* cl 0 : YFilter1 */
9922/* 1 : YFilter2 */
9923/* ch 0 : 301A */
9924/* 1 : 301B/302B/301LV/302LV */
9925/* Description : */
9926/* --------------------------------------------------------------------- */
9927void XGI_GetTVPtrIndex2(USHORT* tempbx,UCHAR* tempcl,UCHAR* tempch, PVB_DEVICE_INFO pVBInfo)
9928{
9929 *tempbx = 0 ;
9930 *tempcl = 0 ;
9931 *tempch = 0 ;
9932
9933 if ( pVBInfo->TVInfo & SetPALTV )
9934 *tempbx = 1 ;
9935
9936 if ( pVBInfo->TVInfo & SetPALMTV )
9937 *tempbx = 2 ;
9938
9939 if ( pVBInfo->TVInfo & SetPALNTV )
9940 *tempbx = 3 ;
9941
9942 if ( pVBInfo->TVInfo & NTSC1024x768 )
9943 {
9944 *tempbx = 4 ;
9945 if ( pVBInfo->TVInfo & SetPALMTV )
9946 *tempbx = 5 ;
9947 }
9948
9949 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9950 {
9951 if ( ( !( pVBInfo->VBInfo & SetInSlaveMode ) ) || ( pVBInfo->TVInfo & TVSimuMode ) )
9952 {
9953 *tempbx += 8 ;
9954 *tempcl += 1 ;
9955 }
9956 }
9957
9958 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
9959 (*tempch)++ ;
9960}
9961
9962
9963/* --------------------------------------------------------------------- */
9964/* Function : XGI_SetCRT2ModeRegs */
9965/* Input : */
9966/* Output : */
9967/* Description : Origin code for crt2group */
9968/* --------------------------------------------------------------------- */
9969void XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
9970{
9971 USHORT tempbl ;
9972 SHORT tempcl ;
9973
9974 UCHAR tempah ;
9975
9976 /* XGINew_SetReg1( pVBInfo->Part1Port , 0x03 , 0x00 ) ; // fix write part1 index 0 BTDRAM bit Bug */
9977 tempah=0;
9978 if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
9979 {
9980 tempah=XGINew_GetReg1( pVBInfo->Part1Port , 0x00 ) ;
9981 tempah &= ~0x10 ; /* BTRAMDAC */
9982 tempah |= 0x40 ; /* BTRAM */
9983
9984 if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
9985 {
9986 tempah=0x40; /* BTDRAM */
9987 if ( ModeNo > 0x13 )
9988 {
9989 tempcl = pVBInfo->ModeType ;
9990 tempcl -= ModeVGA ;
9991 if ( tempcl >= 0 )
9992 {
9993 tempah = ( 0x008 >> tempcl ) ; /* BT Color */
9994 if ( tempah == 0 )
9995 tempah = 1 ;
9996 tempah |= 0x040 ;
9997 }
9998 }
9999 if ( pVBInfo->VBInfo & SetInSlaveMode )
10000 tempah ^= 0x50 ; /* BTDAC */
10001 }
10002 }
10003
10004/* 0210 shampoo
10005 if ( pVBInfo->VBInfo & DisableCRT2Display )
10006 {
10007 tempah = 0 ;
10008 }
10009
10010 XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , tempah ) ;
10011 if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
10012 {
10013 tempcl = pVBInfo->ModeType ;
10014 if ( ModeNo > 0x13 )
10015 {
10016 tempcl -= ModeVGA ;
10017 if ( ( tempcl > 0 ) || ( tempcl == 0 ) )
10018 {
10019 tempah=(0x008>>tempcl) ;
10020 if ( tempah == 0 )
10021 tempah = 1 ;
10022 tempah |= 0x040;
10023 }
10024 }
10025 else
10026 {
10027 tempah = 0x040 ;
10028 }
10029
10030 if ( pVBInfo->VBInfo & SetInSlaveMode )
10031 {
10032 tempah = ( tempah ^ 0x050 ) ;
10033 }
10034 }
10035*/
10036
10037 XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , tempah ) ;
10038 tempah = 0x08 ;
10039 tempbl = 0xf0 ;
10040
10041 if ( pVBInfo->VBInfo & DisableCRT2Display )
10042 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
10043 else
10044 {
10045 tempah = 0x00 ;
10046 tempbl = 0xff ;
10047
10048 if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) )
10049 {
10050 if ( ( pVBInfo->VBInfo & SetCRT2ToLCDA ) && ( !( pVBInfo->VBInfo & SetSimuScanMode ) ) )
10051 {
10052 tempbl &= 0xf7 ;
10053 tempah |= 0x01 ;
10054 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
10055 }
10056 else
10057 {
10058 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
10059 {
10060 tempbl &= 0xf7 ;
10061 tempah |= 0x01 ;
10062 }
10063
10064 if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
10065 {
10066 tempbl &= 0xf8 ;
10067 tempah = 0x01 ;
10068
10069 if ( !( pVBInfo->VBInfo & SetInSlaveMode ) )
10070 tempah |= 0x02 ;
10071
10072 if ( !( pVBInfo->VBInfo & SetCRT2ToRAMDAC ) )
10073 {
10074 tempah = tempah ^ 0x05 ;
10075 if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
10076 tempah = tempah ^ 0x01 ;
10077 }
10078
10079 if ( !( pVBInfo->VBInfo & SetCRT2ToDualEdge ) )
10080 tempah |= 0x08 ;
10081 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
10082 }
10083 else
10084 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
10085 }
10086 }
10087 else
10088 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
10089 }
10090
10091 if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) )
10092 {
10093 tempah &= ( ~0x08 ) ;
10094 if ( ( pVBInfo->ModeType == ModeVGA ) && ( !( pVBInfo->VBInfo & SetInSlaveMode ) ) )
10095 {
10096 tempah |= 0x010 ;
10097 }
10098 tempah |= 0x080 ;
10099
10100 if ( pVBInfo->VBInfo & SetCRT2ToTV )
10101 {
10102 /* if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) */
10103 /* { */
10104 tempah |= 0x020 ;
10105 if ( ModeNo > 0x13 )
10106 {
10107 if ( pVBInfo->VBInfo & DriverMode )
10108 tempah = tempah ^ 0x20 ;
10109 }
10110 /* } */
10111 }
10112
10113 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x0D , ~0x0BF , tempah ) ;
10114 tempah = 0 ;
10115
10116 if ( pVBInfo->LCDInfo & SetLCDDualLink )
10117 tempah |= 0x40 ;
10118
10119 if ( pVBInfo->VBInfo & SetCRT2ToTV )
10120 {
10121 /* if ( ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) && ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) ) */
10122 /* { */
10123 if ( pVBInfo->TVInfo & RPLLDIV2XO )
10124 tempah |= 0x40 ;
10125 /* } */
10126 }
10127
10128 if ( ( pVBInfo->LCDResInfo == Panel1280x1024 ) || ( pVBInfo->LCDResInfo == Panel1280x1024x75 ) )
10129 tempah |= 0x80 ;
10130
10131 if ( pVBInfo->LCDResInfo == Panel1280x960 )
10132 tempah |= 0x80 ;
10133
10134 XGINew_SetReg1( pVBInfo->Part4Port , 0x0C , tempah ) ;
10135 }
10136
10137 if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
10138 {
10139 tempah = 0 ;
10140 tempbl = 0xfb ;
10141
10142 if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
10143 {
10144 tempbl=0xff;
10145 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
10146 tempah |= 0x04 ; /* shampoo 0129 */
10147 }
10148
10149 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x13 , tempbl , tempah ) ;
10150 tempah = 0x00 ;
10151 tempbl = 0xcf ;
10152 if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
10153 {
10154 if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
10155 tempah |= 0x30 ;
10156 }
10157
10158 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2c , tempbl , tempah ) ;
10159 tempah = 0 ;
10160 tempbl = 0x3f ;
10161
10162 if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
10163 {
10164 if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
10165 tempah |= 0xc0 ;
10166 }
10167 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x21 , tempbl , tempah ) ;
10168 }
10169
10170 tempah = 0 ;
10171 tempbl = 0x7f ;
10172 if ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
10173 {
10174 tempbl = 0xff ;
10175 if ( !( pVBInfo->VBInfo & SetCRT2ToDualEdge ) )
10176 tempah |= 0x80 ;
10177 }
10178
10179 XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x23 , tempbl , tempah ) ;
10180
10181 if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
10182 {
10183 if ( pVBInfo->LCDInfo & SetLCDDualLink )
10184 {
10185 XGINew_SetRegOR( pVBInfo->Part4Port , 0x27 , 0x20 ) ;
10186 XGINew_SetRegOR( pVBInfo->Part4Port , 0x34 , 0x10 ) ;
10187 }
10188 }
10189}
10190
10191
10192/* --------------------------------------------------------------------- */
10193/* Function : XGI_CloseCRTC */
10194/* Input : */
10195/* Output : */
10196/* Description : */
10197/* --------------------------------------------------------------------- */
10198void XGI_CloseCRTC( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
10199{
10200 USHORT tempbx ;
10201
10202 tempbx = 0 ;
10203
10204 if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
10205 tempbx = 0x08A0 ;
10206
10207
10208}
10209
10210
10211/* --------------------------------------------------------------------- */
10212/* Function : XGI_OpenCRTC */
10213/* Input : */
10214/* Output : */
10215/* Description : */
10216/* --------------------------------------------------------------------- */
10217void XGI_OpenCRTC( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
10218{
10219 USHORT tempbx ;
10220
10221 tempbx = 0 ;
10222
10223
10224}
10225
10226
10227/* --------------------------------------------------------------------- */
10228/* Function : XGI_GetRAMDAC2DATA */
10229/* Input : */
10230/* Output : */
10231/* Description : */
10232/* --------------------------------------------------------------------- */
10233void XGI_GetRAMDAC2DATA(USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo )
10234{
10235 USHORT tempax ,
10236 tempbx ,
10237 temp1 ,
10238 temp2 ,
10239 modeflag = 0 ,
10240 tempcx ,
10241 StandTableIndex ,
10242 CRT1Index ;
10243
10244 pVBInfo->RVBHCMAX = 1 ;
10245 pVBInfo->RVBHCFACT = 1 ;
10246
10247 if ( ModeNo <= 0x13 )
10248 {
10249 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
10250 StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
10251 tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 0 ] ;
10252 tempbx = pVBInfo->StandTable[StandTableIndex ].CRTC[ 6 ] ;
10253 temp1 = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ;
10254 }
10255 else
10256 {
10257 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
10258 CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
10259 CRT1Index &= IndexMask ;
10260 temp1 = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 0 ] ;
10261 temp2 = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 5 ] ;
10262 tempax = ( temp1 & 0xFF ) | ( ( temp2 & 0x03 ) << 8 ) ;
10263 tempbx = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 8 ] ;
10264 tempcx = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 14 ] << 8 ;
10265 tempcx &= 0x0100 ;
10266 tempcx = tempcx << 2 ;
10267 tempbx |= tempcx;
10268 temp1 = ( USHORT )pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 9 ] ;
10269 }
10270
10271 if ( temp1 & 0x01 )
10272 tempbx |= 0x0100 ;
10273
10274 if ( temp1 & 0x20 )
10275 tempbx |= 0x0200 ;
10276 tempax += 5 ;
10277
10278 if ( modeflag & Charx8Dot )
10279 tempax *= 8 ;
10280 else
10281 tempax *= 9 ;
10282
10283 pVBInfo->VGAHT = tempax ;
10284 pVBInfo->HT = tempax ;
10285 tempbx++ ;
10286 pVBInfo->VGAVT = tempbx ;
10287 pVBInfo->VT = tempbx ;
10288}
10289
10290
10291
10292/* --------------------------------------------------------------------- */
10293/* Function : XGI_GetColorDepth */
10294/* Input : */
10295/* Output : */
10296/* Description : */
10297/* --------------------------------------------------------------------- */
10298USHORT XGI_GetColorDepth(USHORT ModeNo , USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
10299{
10300 USHORT ColorDepth[ 6 ] = { 1 , 2 , 4 , 4 , 6 , 8 } ;
10301 SHORT index ;
10302 USHORT modeflag ;
10303
10304 if ( ModeNo <= 0x13 )
10305 {
10306 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
10307 }
10308 else
10309 {
10310 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
10311 }
10312
10313 index=(modeflag&ModeInfoFlag)-ModeEGA;
10314
10315 if ( index < 0 )
10316 index = 0 ;
10317
10318 return( ColorDepth[ index ] ) ;
10319}
10320
10321
10322
10323/* --------------------------------------------------------------------- */
10324/* Function : XGI_UnLockCRT2 */
10325/* Input : */
10326/* Output : */
10327/* Description : */
10328/* --------------------------------------------------------------------- */
10329void XGI_UnLockCRT2( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
10330{
10331
10332 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2f , 0xFF , 0x01 ) ;
10333
10334}
10335
10336
10337/* --------------------------------------------------------------------- */
10338/* Function : XGI_LockCRT2 */
10339/* Input : */
10340/* Output : */
10341/* Description : */
10342/* --------------------------------------------------------------------- */
10343void XGI_LockCRT2( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo )
10344{
10345
10346 XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2F , 0xFE , 0x00 ) ;
10347
10348
10349}
10350
10351
10352/* --------------------------------------------------------------------- */
10353/* Function : XGINew_EnableCRT2 */
10354/* Input : */
10355/* Output : */
10356/* Description : */
10357/* --------------------------------------------------------------------- */
10358void XGINew_EnableCRT2( PVB_DEVICE_INFO pVBInfo)
10359{
10360 XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1E , 0xFF , 0x20 ) ;
10361}
10362
10363
10364
10365/* --------------------------------------------------------------------- */
10366/* Function : */
10367/* Input : */
10368/* Output : */
10369/* Description : */
10370/* --------------------------------------------------------------------- */
10371void XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo)
10372{
10373 USHORT i ,
10374 j ;
10375
10376 ULONG temp ,
10377 flag ;
10378
10379 flag = 0 ;
10380//printk("XGINew_LCD_Wait_Time");
10381//return;
10382 for( i = 0 ; i < DelayTime ; i++ )
10383 {
10384 for( j = 0 ; j < 66 ; j++ )
10385 {
10386
10387 temp = XGINew_GetReg3( 0x61 ) ;
10388
10389 //temp &= 0x10000000;
10390 temp &= 0x10;
10391 if ( temp == flag )
10392 continue ;
10393
10394 flag = temp ;
10395 }
10396 }
10397}
10398
10399
10400
10401
10402/* --------------------------------------------------------------------- */
10403/* Function : XGI_BridgeIsOn */
10404/* Input : */
10405/* Output : */
10406/* Description : */
10407/* --------------------------------------------------------------------- */
10408BOOLEAN XGI_BridgeIsOn( PVB_DEVICE_INFO pVBInfo )
10409{
10410 USHORT flag ;
10411
10412 if ( pVBInfo->IF_DEF_LVDS == 1 )
10413 {
10414 return( 1 ) ;
10415 }
10416 else
10417 {
10418 flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x00 ) ;
10419 if ( ( flag == 1 ) || ( flag == 2 ) )
10420 return( 1 ) ; /* 301b */
10421 else
10422 return( 0 ) ;
10423 }
10424}
10425
10426
10427
10428/* --------------------------------------------------------------------- */
10429/* Function : XGI_LongWait */
10430/* Input : */
10431/* Output : */
10432/* Description : */
10433/* --------------------------------------------------------------------- */
10434void XGI_LongWait(PVB_DEVICE_INFO pVBInfo)
10435{
10436 USHORT i ;
10437
10438 i = XGINew_GetReg1( pVBInfo->P3c4 , 0x1F ) ;
10439
10440 if ( !( i & 0xC0 ) )
10441 {
10442 for( i = 0 ; i < 0xFFFF ; i++ )
10443 {
10444 if ( !( XGINew_GetReg2( pVBInfo->P3da ) & 0x08 ) )
10445 break ;
10446 }
10447
10448 for( i = 0 ; i < 0xFFFF ; i++ )
10449 {
10450 if ( ( XGINew_GetReg2( pVBInfo->P3da ) & 0x08 ) )
10451 break ;
10452 }
10453 }
10454}
10455
10456
10457/* --------------------------------------------------------------------- */
10458/* Function : XGI_VBLongWait */
10459/* Input : */
10460/* Output : */
10461/* Description : */
10462/* --------------------------------------------------------------------- */
10463void XGI_VBLongWait( PVB_DEVICE_INFO pVBInfo )
10464{
10465 USHORT tempal ,
10466 temp ,
10467 i ,
10468 j ;
10469return ;
10470 if ( !( pVBInfo->VBInfo & SetCRT2ToTV ) )
10471 {
10472 temp = 0 ;
10473 for( i = 0 ; i < 3 ; i++ )
10474 {
10475 for( j = 0 ; j < 100 ; j++ )
10476 {
10477 tempal = XGINew_GetReg2( pVBInfo->P3da ) ;
10478 if ( temp & 0x01 )
10479 { /* VBWaitMode2 */
10480 if ( ( tempal & 0x08 ) )
10481 {
10482 continue ;
10483 }
10484
10485 if ( !( tempal & 0x08 ) )
10486 {
10487 break ;
10488 }
10489 }
10490 else
10491 { /* VBWaitMode1 */
10492 if ( !( tempal & 0x08 ) )
10493 {
10494 continue ;
10495 }
10496
10497 if ( ( tempal & 0x08 ) )
10498 {
10499 break ;
10500 }
10501 }
10502 }
10503 temp = temp ^ 0x01 ;
10504 }
10505 }
10506 else
10507 {
10508 XGI_LongWait(pVBInfo) ;
10509 }
10510 return ;
10511}
10512
10513
10514
10515
10516/* --------------------------------------------------------------------- */
10517/* Function : XGI_GetVGAHT2 */
10518/* Input : */
10519/* Output : */
10520/* Description : */
10521/* --------------------------------------------------------------------- */
10522USHORT XGI_GetVGAHT2( PVB_DEVICE_INFO pVBInfo )
10523{
10524 ULONG tempax ,
10525 tempbx ;
10526
10527 tempbx = ( ( pVBInfo->VGAVT - pVBInfo->VGAVDE ) * pVBInfo->RVBHCMAX ) & 0xFFFF ;
10528 tempax = ( pVBInfo->VT - pVBInfo->VDE ) * pVBInfo->RVBHCFACT ;
10529 tempax = ( tempax * pVBInfo->HT ) /tempbx ;
10530
10531 return( ( USHORT )tempax ) ;
10532}
10533
10534
10535/* --------------------------------------------------------------------- */
10536/* Function : XGI_GetVCLK2Ptr */
10537/* Input : */
10538/* Output : */
10539/* Description : */
10540/* --------------------------------------------------------------------- */
10541USHORT XGI_GetVCLK2Ptr( USHORT ModeNo , USHORT ModeIdIndex , USHORT RefreshRateTableIndex , PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
10542{
10543 USHORT tempbx ;
10544
10545 USHORT LCDXlat1VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
10546 USHORT LCDXlat2VCLK[ 4 ] = { VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 } ;
10547 USHORT LVDSXlat1VCLK[ 4 ] = { VCLK40 , VCLK40 , VCLK40 , VCLK40 } ;
10548 USHORT LVDSXlat2VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
10549 USHORT LVDSXlat3VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
10550
10551 USHORT CRT2Index , VCLKIndex ;
10552 USHORT modeflag , resinfo ;
10553 UCHAR *CHTVVCLKPtr = NULL ;
10554
10555 if ( ModeNo <= 0x13 )
10556 {
10557 modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
10558 resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
10559 CRT2Index = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
10560 }
10561 else
10562 {
10563 modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
10564 resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
10565 CRT2Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
10566 }
10567
10568 if ( pVBInfo->IF_DEF_LVDS == 0 )
10569 {
10570 CRT2Index = CRT2Index >> 6 ; /* for LCD */
10571 if ( ( ( pVBInfo->VBInfo & SetCRT2ToLCD ) | SetCRT2ToLCDA ) ) /*301b*/
10572 {
10573 if ( pVBInfo->LCDResInfo != Panel1024x768 )
10574 {
10575 VCLKIndex = LCDXlat2VCLK[ CRT2Index ] ;
10576 }
10577 else
10578 {
10579 VCLKIndex = LCDXlat1VCLK[ CRT2Index ] ;
10580 }
10581 }
10582 else /* for TV */
10583 {
10584 if ( pVBInfo->VBInfo & SetCRT2ToTV )
10585 {
10586 if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
10587 {
10588 if ( pVBInfo->SetFlag & RPLLDIV2XO )
10589 {
10590 VCLKIndex = HiTVVCLKDIV2 ;
10591
10592
10593 VCLKIndex += 25 ;
10594
10595 }
10596 else
10597 {
10598 VCLKIndex = HiTVVCLK ;
10599
10600
10601 VCLKIndex += 25 ;
10602
10603 }
10604
10605 if ( pVBInfo->SetFlag & TVSimuMode )
10606 {
10607 if( modeflag & Charx8Dot )
10608 {
10609 VCLKIndex = HiTVSimuVCLK ;
10610
10611
10612 VCLKIndex += 25 ;
10613
10614 }
10615 else
10616 {
10617 VCLKIndex = HiTVTextVCLK ;
10618
10619
10620 VCLKIndex += 25 ;
10621
10622 }
10623 }
10624
10625 if ( pVBInfo->VBType & VB_XGI301LV ) /* 301lv */
10626 {
10627 if ( !( pVBInfo->VBExtInfo == VB_YPbPr1080i ) )
10628 {
10629 VCLKIndex = YPbPr750pVCLK ;
10630 if ( !( pVBInfo->VBExtInfo == VB_YPbPr750p ) )
10631 {
10632 VCLKIndex = YPbPr525pVCLK ;
10633 if ( !( pVBInfo->VBExtInfo == VB_YPbPr525p ) )
10634 {
10635 VCLKIndex = YPbPr525iVCLK_2 ;
10636 if ( !( pVBInfo->SetFlag & RPLLDIV2XO ) )
10637 VCLKIndex = YPbPr525iVCLK ;
10638 }
10639 }
10640 }
10641 }
10642 }
10643 else
10644 {
10645 if ( pVBInfo->VBInfo & SetCRT2ToTV )
10646 {
10647 if ( pVBInfo->SetFlag & RPLLDIV2XO )
10648 {
10649 VCLKIndex = TVVCLKDIV2 ;
10650
10651
10652 VCLKIndex += 25 ;
10653
10654 }
10655 else
10656 {
10657 VCLKIndex = TVVCLK ;
10658
10659
10660 VCLKIndex += 25 ;
10661
10662 }
10663 }
10664 }
10665 }
10666 else
10667 { /* for CRT2 */
10668 VCLKIndex = ( UCHAR )XGINew_GetReg2( ( pVBInfo->P3ca + 0x02 ) ) ; /* Port 3cch */
10669 VCLKIndex = ( ( VCLKIndex >> 2 ) & 0x03 ) ;
10670 if ( ModeNo > 0x13 )
10671 {
10672 VCLKIndex = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ; /* di+Ext_CRTVCLK */
10673 VCLKIndex &= IndexMask ;
10674 }
10675 }
10676 }
10677 }
10678 else
10679 { /* LVDS */
10680 if ( ModeNo <= 0x13 )
10681 VCLKIndex = CRT2Index ;
10682 else
10683 VCLKIndex = CRT2Index ;
10684
10685 if ( pVBInfo->IF_DEF_CH7005 == 1 )
10686 {
10687 if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
10688 {
10689 VCLKIndex &= 0x1f ;
10690 tempbx = 0 ;
10691
10692 if ( pVBInfo->VBInfo & SetPALTV )
10693 tempbx += 2 ;
10694
10695 if ( pVBInfo->VBInfo & SetCHTVOverScan )
10696 tempbx += 1 ;
10697
10698 switch( tempbx )
10699 {
10700 case 0:
10701 CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC ;
10702 break ;
10703 case 1:
10704 CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC ;
10705 break;
10706 case 2:
10707 CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL ;
10708 break ;
10709 case 3:
10710 CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL ;
10711 break ;
10712 default:
10713 break ;
10714 }
10715
10716 VCLKIndex = CHTVVCLKPtr[ VCLKIndex ] ;
10717 }
10718 }
10719 else
10720 {
10721 VCLKIndex = VCLKIndex >> 6 ;
10722 if ( ( pVBInfo->LCDResInfo == Panel800x600 ) || ( pVBInfo->LCDResInfo == Panel320x480 ) )
10723 VCLKIndex = LVDSXlat1VCLK[ VCLKIndex ] ;
10724 else if ( ( pVBInfo->LCDResInfo == Panel1024x768 ) || ( pVBInfo->LCDResInfo == Panel1024x768x75 ) )
10725 VCLKIndex = LVDSXlat2VCLK[ VCLKIndex ] ;
10726 else
10727 VCLKIndex = LVDSXlat3VCLK[ VCLKIndex ] ;
10728 }
10729 }
10730 /* VCLKIndex = VCLKIndex&IndexMask ; */
10731
10732
10733
10734 return( VCLKIndex ) ;
10735}
10736
diff --git a/drivers/staging/xgifb/vb_setmode.h b/drivers/staging/xgifb/vb_setmode.h
new file mode 100644
index 000000000000..09753d706665
--- /dev/null
+++ b/drivers/staging/xgifb/vb_setmode.h
@@ -0,0 +1,40 @@
1#ifndef _VBSETMODE_
2#define _VBSETMODE_
3
4extern void InitTo330Pointer(UCHAR,PVB_DEVICE_INFO);
5extern void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
6extern void XGI_LockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
7extern void XGI_LongWait( PVB_DEVICE_INFO );
8extern void XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
9extern void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
10extern void XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
11extern void XGI_DisplayOff( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
12extern void XGI_DisplayOn( PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
13extern void XGI_GetVBType(PVB_DEVICE_INFO);
14extern void XGI_SenseCRT1(PVB_DEVICE_INFO );
15extern void XGI_GetVGAType(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
16extern void XGI_GetVBInfo(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
17extern void XGI_GetTVInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO );
18extern void XGI_SetCRT1Offset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
19extern void XGI_SetLCDAGroup(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
20extern void XGI_WaitDisply( PVB_DEVICE_INFO );
21extern USHORT XGI_GetResInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
22
23extern BOOLEAN XGISetModeNew( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT ModeNo ) ;
24
25extern BOOLEAN XGI_SearchModeID( USHORT ModeNo,USHORT *ModeIdIndex, PVB_DEVICE_INFO );
26extern BOOLEAN XGI_GetLCDInfo(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO );
27extern BOOLEAN XGI_BridgeIsOn( PVB_DEVICE_INFO );
28extern BOOLEAN XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO);
29extern USHORT XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO pXGIHWDE, USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO );
30
31extern void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
32extern void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
33extern void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
34extern void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
35extern void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
36extern BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
37extern void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
38extern USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo);
39
40#endif
diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h
new file mode 100644
index 000000000000..bb25c0e2785e
--- /dev/null
+++ b/drivers/staging/xgifb/vb_struct.h
@@ -0,0 +1,534 @@
1#ifndef _VB_STRUCT_
2#define _VB_STRUCT_
3
4#ifdef _INITNEW_
5#define EXTERN
6#else
7#define EXTERN extern
8#endif
9
10
11
12
13typedef struct _XGI_PanelDelayTblStruct
14{
15 UCHAR timer[2];
16} XGI_PanelDelayTblStruct;
17
18typedef struct _XGI_LCDDataStruct
19{
20 USHORT RVBHCMAX;
21 USHORT RVBHCFACT;
22 USHORT VGAHT;
23 USHORT VGAVT;
24 USHORT LCDHT;
25 USHORT LCDVT;
26} XGI_LCDDataStruct;
27
28
29typedef struct _XGI_LVDSCRT1HDataStruct
30{
31 UCHAR Reg[8];
32} XGI_LVDSCRT1HDataStruct;
33typedef struct _XGI_LVDSCRT1VDataStruct
34{
35 UCHAR Reg[7];
36} XGI_LVDSCRT1VDataStruct;
37
38
39typedef struct _XGI_TVDataStruct
40{
41 USHORT RVBHCMAX;
42 USHORT RVBHCFACT;
43 USHORT VGAHT;
44 USHORT VGAVT;
45 USHORT TVHDE;
46 USHORT TVVDE;
47 USHORT RVBHRS;
48 UCHAR FlickerMode;
49 USHORT HALFRVBHRS;
50 UCHAR RY1COE;
51 UCHAR RY2COE;
52 UCHAR RY3COE;
53 UCHAR RY4COE;
54} XGI_TVDataStruct;
55
56typedef struct _XGI_LVDSDataStruct
57{
58 USHORT VGAHT;
59 USHORT VGAVT;
60 USHORT LCDHT;
61 USHORT LCDVT;
62} XGI_LVDSDataStruct;
63
64typedef struct _XGI_LVDSDesStruct
65{
66 USHORT LCDHDES;
67 USHORT LCDVDES;
68} XGI_LVDSDesStruct;
69
70typedef struct _XGI_LVDSCRT1DataStruct
71{
72 UCHAR CR[15];
73} XGI_LVDSCRT1DataStruct;
74
75/*add for LCDA*/
76
77
78typedef struct _XGI_StStruct
79{
80 UCHAR St_ModeID;
81 USHORT St_ModeFlag;
82 UCHAR St_StTableIndex;
83 UCHAR St_CRT2CRTC;
84 UCHAR St_CRT2CRTC2;
85 UCHAR St_ResInfo;
86 UCHAR VB_StTVFlickerIndex;
87 UCHAR VB_StTVEdgeIndex;
88 UCHAR VB_StTVYFilterIndex;
89} XGI_StStruct;
90
91typedef struct _XGI_StandTableStruct
92{
93 UCHAR CRT_COLS;
94 UCHAR ROWS;
95 UCHAR CHAR_HEIGHT;
96 USHORT CRT_LEN;
97 UCHAR SR[4];
98 UCHAR MISC;
99 UCHAR CRTC[0x19];
100 UCHAR ATTR[0x14];
101 UCHAR GRC[9];
102} XGI_StandTableStruct;
103
104typedef struct _XGI_ExtStruct
105{
106 UCHAR Ext_ModeID;
107 USHORT Ext_ModeFlag;
108 USHORT Ext_ModeInfo;
109 USHORT Ext_Point;
110 USHORT Ext_VESAID;
111 UCHAR Ext_VESAMEMSize;
112 UCHAR Ext_RESINFO;
113 UCHAR VB_ExtTVFlickerIndex;
114 UCHAR VB_ExtTVEdgeIndex;
115 UCHAR VB_ExtTVYFilterIndex;
116 UCHAR REFindex;
117} XGI_ExtStruct;
118
119typedef struct _XGI_Ext2Struct
120{
121 USHORT Ext_InfoFlag;
122 UCHAR Ext_CRT1CRTC;
123 UCHAR Ext_CRTVCLK;
124 UCHAR Ext_CRT2CRTC;
125 UCHAR Ext_CRT2CRTC2;
126 UCHAR ModeID;
127 USHORT XRes;
128 USHORT YRes;
129 /* USHORT ROM_OFFSET; */
130} XGI_Ext2Struct;
131
132
133typedef struct _XGI_MCLKDataStruct
134{
135 UCHAR SR28,SR29,SR2A;
136 USHORT CLOCK;
137} XGI_MCLKDataStruct;
138
139typedef struct _XGI_ECLKDataStruct
140{
141 UCHAR SR2E,SR2F,SR30;
142 USHORT CLOCK;
143} XGI_ECLKDataStruct;
144
145typedef struct _XGI_VCLKDataStruct
146{
147 UCHAR SR2B,SR2C;
148 USHORT CLOCK;
149} XGI_VCLKDataStruct;
150
151typedef struct _XGI_VBVCLKDataStruct
152{
153 UCHAR Part4_A,Part4_B;
154 USHORT CLOCK;
155} XGI_VBVCLKDataStruct;
156
157typedef struct _XGI_StResInfoStruct
158{
159 USHORT HTotal;
160 USHORT VTotal;
161} XGI_StResInfoStruct;
162
163typedef struct _XGI_ModeResInfoStruct
164{
165 USHORT HTotal;
166 USHORT VTotal;
167 UCHAR XChar;
168 UCHAR YChar;
169} XGI_ModeResInfoStruct;
170
171typedef struct _XGI_LCDNBDesStruct
172{
173 UCHAR NB[12];
174} XGI_LCDNBDesStruct;
175 /*add for new UNIVGABIOS*/
176typedef struct _XGI_LCDDesStruct
177{
178 USHORT LCDHDES;
179 USHORT LCDHRS;
180 USHORT LCDVDES;
181 USHORT LCDVRS;
182} XGI_LCDDesStruct;
183
184typedef struct _XGI_LCDDataTablStruct
185{
186 UCHAR PANELID;
187 USHORT MASK;
188 USHORT CAP;
189 USHORT DATAPTR;
190} XGI_LCDDataTablStruct;
191
192typedef struct _XGI_TVTablDataStruct
193{
194 USHORT MASK;
195 USHORT CAP;
196 USHORT DATAPTR;
197} XGI_TVDataTablStruct;
198
199typedef struct _XGI330_LCDDesDataStruct
200{
201 USHORT LCDHDES;
202 USHORT LCDHRS;
203 USHORT LCDVDES;
204 USHORT LCDVRS;
205} XGI330_LCDDataDesStruct;
206
207
208typedef struct _XGI330_LVDSDataStruct
209{
210 USHORT VGAHT;
211 USHORT VGAVT;
212 USHORT LCDHT;
213 USHORT LCDVT;
214} XGI330_LVDSDataStruct;
215
216typedef struct _XGI330_LCDDesDataStruct2
217{
218 USHORT LCDHDES;
219 USHORT LCDHRS;
220 USHORT LCDVDES;
221 USHORT LCDVRS;
222 USHORT LCDHSync;
223 USHORT LCDVSync;
224} XGI330_LCDDataDesStruct2;
225
226typedef struct _XGI330_LCDDataStruct
227{
228 USHORT RVBHCMAX;
229 USHORT RVBHCFACT;
230 USHORT VGAHT;
231 USHORT VGAVT;
232 USHORT LCDHT;
233 USHORT LCDVT;
234} XGI330_LCDDataStruct;
235
236
237typedef struct _XGI330_TVDataStruct
238{
239 USHORT RVBHCMAX;
240 USHORT RVBHCFACT;
241 USHORT VGAHT;
242 USHORT VGAVT;
243 USHORT TVHDE;
244 USHORT TVVDE;
245 USHORT RVBHRS;
246 UCHAR FlickerMode;
247 USHORT HALFRVBHRS;
248} XGI330_TVDataStruct;
249
250typedef struct _XGI330_LCDDataTablStruct
251{
252 UCHAR PANELID;
253 USHORT MASK;
254 USHORT CAP;
255 USHORT DATAPTR;
256} XGI330_LCDDataTablStruct;
257
258typedef struct _XGI330_TVDataTablStruct
259{
260 USHORT MASK;
261 USHORT CAP;
262 USHORT DATAPTR;
263} XGI330_TVDataTablStruct;
264
265
266typedef struct _XGI330_CHTVDataStruct
267{
268 USHORT VGAHT;
269 USHORT VGAVT;
270 USHORT LCDHT;
271 USHORT LCDVT;
272} XGI330_CHTVDataStruct;
273
274typedef struct _XGI_TimingHStruct
275{
276 UCHAR data[8];
277} XGI_TimingHStruct;
278
279typedef struct _XGI_TimingVStruct
280{
281 UCHAR data[7];
282} XGI_TimingVStruct;
283
284typedef struct _XGI_CH7007TV_TimingHStruct
285{
286 UCHAR data[10];
287} XGI_CH7007TV_TimingHStruct;
288
289typedef struct _XGI_CH7007TV_TimingVStruct
290{
291 UCHAR data[10];
292} XGI_CH7007TV_TimingVStruct;
293
294typedef struct _XGI_XG21CRT1Struct
295{
296 UCHAR ModeID,CR02,CR03,CR15,CR16;
297} XGI_XG21CRT1Struct;
298
299typedef struct _XGI330_CHTVRegDataStruct
300{
301 UCHAR Reg[16];
302} XGI330_CHTVRegDataStruct;
303
304typedef struct _XGI330_LCDCapStruct
305{
306 UCHAR LCD_ID;
307 USHORT LCD_Capability;
308 UCHAR LCD_SetFlag;
309 UCHAR LCD_DelayCompensation;
310 UCHAR LCD_HSyncWidth;
311 UCHAR LCD_VSyncWidth;
312 UCHAR LCD_VCLK;
313 UCHAR LCDA_VCLKData1;
314 UCHAR LCDA_VCLKData2;
315 UCHAR LCUCHAR_VCLKData1;
316 UCHAR LCUCHAR_VCLKData2;
317 UCHAR PSC_S1;
318 UCHAR PSC_S2;
319 UCHAR PSC_S3;
320 UCHAR PSC_S4;
321 UCHAR PSC_S5;
322 UCHAR PWD_2B;
323 UCHAR PWD_2C;
324 UCHAR PWD_2D;
325 UCHAR PWD_2E;
326 UCHAR PWD_2F;
327 UCHAR Spectrum_31;
328 UCHAR Spectrum_32;
329 UCHAR Spectrum_33;
330 UCHAR Spectrum_34;
331} XGI330_LCDCapStruct;
332
333typedef struct _XGI21_LVDSCapStruct
334{
335 USHORT LVDS_Capability;
336 USHORT LVDSHT;
337 USHORT LVDSVT;
338 USHORT LVDSHDE;
339 USHORT LVDSVDE;
340 USHORT LVDSHFP;
341 USHORT LVDSVFP;
342 USHORT LVDSHSYNC;
343 USHORT LVDSVSYNC;
344 UCHAR VCLKData1;
345 UCHAR VCLKData2;
346 UCHAR PSC_S1;
347 UCHAR PSC_S2;
348 UCHAR PSC_S3;
349 UCHAR PSC_S4;
350 UCHAR PSC_S5;
351} XGI21_LVDSCapStruct;
352
353typedef struct _XGI_CRT1TableStruct
354{
355 UCHAR CR[16];
356} XGI_CRT1TableStruct;
357
358
359typedef struct _XGI330_VCLKDataStruct
360{
361 UCHAR SR2B,SR2C;
362 USHORT CLOCK;
363} XGI330_VCLKDataStruct;
364
365typedef struct _XGI301C_Tap4TimingStruct
366{
367 USHORT DE;
368 UCHAR Reg[64]; /* C0-FF */
369} XGI301C_Tap4TimingStruct;
370
371typedef struct _XGI_New_StandTableStruct
372{
373 UCHAR CRT_COLS;
374 UCHAR ROWS;
375 UCHAR CHAR_HEIGHT;
376 USHORT CRT_LEN;
377 UCHAR SR[4];
378 UCHAR MISC;
379 UCHAR CRTC[0x19];
380 UCHAR ATTR[0x14];
381 UCHAR GRC[9];
382} XGI_New_StandTableStruct;
383
384typedef UCHAR DRAM8Type[8];
385typedef UCHAR DRAM4Type[4];
386typedef UCHAR DRAM32Type[32];
387typedef UCHAR DRAM2Type[2];
388
389typedef struct _VB_DEVICE_INFO VB_DEVICE_INFO;
390typedef VB_DEVICE_INFO * PVB_DEVICE_INFO;
391
392struct _VB_DEVICE_INFO
393{
394 BOOLEAN ISXPDOS;
395 ULONG P3c4,P3d4,P3c0,P3ce,P3c2,P3cc;
396 ULONG P3ca,P3c6,P3c7,P3c8,P3c9,P3da;
397 ULONG Part0Port,Part1Port,Part2Port;
398 ULONG Part3Port,Part4Port,Part5Port;
399 USHORT RVBHCFACT,RVBHCMAX,RVBHRS;
400 USHORT VGAVT,VGAHT,VGAVDE,VGAHDE;
401 USHORT VT,HT,VDE,HDE;
402 USHORT LCDHRS,LCDVRS,LCDHDES,LCDVDES;
403
404 USHORT ModeType;
405 USHORT IF_DEF_LVDS,IF_DEF_TRUMPION,IF_DEF_DSTN;/* ,IF_DEF_FSTN; add for dstn */
406 USHORT IF_DEF_CRT2Monitor,IF_DEF_VideoCapture;
407 USHORT IF_DEF_LCDA,IF_DEF_CH7017,IF_DEF_YPbPr,IF_DEF_ScaleLCD,IF_DEF_OEMUtil,IF_DEF_PWD;
408 USHORT IF_DEF_ExpLink;
409 USHORT IF_DEF_CH7005,IF_DEF_HiVision;
410 USHORT IF_DEF_CH7007; /* Billy 2007/05/03 */
411 USHORT LCDResInfo,LCDTypeInfo, VBType;/*301b*/
412 USHORT VBInfo,TVInfo,LCDInfo, Set_VGAType;
413 USHORT VBExtInfo;/*301lv*/
414 USHORT SetFlag;
415 USHORT NewFlickerMode;
416 USHORT SelectCRT2Rate;
417
418 PUCHAR ROMAddr;
419 PUCHAR FBAddr;
420 ULONG BaseAddr;
421 ULONG RelIO;
422
423 DRAM4Type *CR6B;
424 DRAM4Type *CR6E;
425 DRAM32Type *CR6F;
426 DRAM2Type *CR89;
427
428 DRAM8Type *SR15; /* pointer : point to array */
429 DRAM8Type *CR40;
430 UCHAR *pSoftSetting;
431 UCHAR *pOutputSelect;
432
433 USHORT *pRGBSenseData;
434 USHORT *pRGBSenseData2; /*301b*/
435 USHORT *pVideoSenseData;
436 USHORT *pVideoSenseData2;
437 USHORT *pYCSenseData;
438 USHORT *pYCSenseData2;
439
440 UCHAR *pSR07;
441 UCHAR *CR49;
442 UCHAR *pSR1F;
443 UCHAR *AGPReg;
444 UCHAR *SR16;
445 UCHAR *pSR21;
446 UCHAR *pSR22;
447 UCHAR *pSR23;
448 UCHAR *pSR24;
449 UCHAR *SR25;
450 UCHAR *pSR31;
451 UCHAR *pSR32;
452 UCHAR *pSR33;
453 UCHAR *pSR36; /* alan 12/07/2006 */
454 UCHAR *pCRCF;
455 UCHAR *pCRD0; /* alan 12/07/2006 */
456 UCHAR *pCRDE; /* alan 12/07/2006 */
457 UCHAR *pCR8F; /* alan 12/07/2006 */
458 UCHAR *pSR40; /* alan 12/07/2006 */
459 UCHAR *pSR41; /* alan 12/07/2006 */
460 UCHAR *pDVOSetting;
461 UCHAR *pCR2E;
462 UCHAR *pCR2F;
463 UCHAR *pCR46;
464 UCHAR *pCR47;
465 UCHAR *pCRT2Data_1_2;
466 UCHAR *pCRT2Data_4_D;
467 UCHAR *pCRT2Data_4_E;
468 UCHAR *pCRT2Data_4_10;
469 XGI_MCLKDataStruct *MCLKData;
470 XGI_ECLKDataStruct *ECLKData;
471
472 UCHAR *XGI_TVDelayList;
473 UCHAR *XGI_TVDelayList2;
474 UCHAR *CHTVVCLKUNTSC;
475 UCHAR *CHTVVCLKONTSC;
476 UCHAR *CHTVVCLKUPAL;
477 UCHAR *CHTVVCLKOPAL;
478 UCHAR *NTSCTiming;
479 UCHAR *PALTiming;
480 UCHAR *HiTVExtTiming;
481 UCHAR *HiTVSt1Timing;
482 UCHAR *HiTVSt2Timing;
483 UCHAR *HiTVTextTiming;
484 UCHAR *YPbPr750pTiming;
485 UCHAR *YPbPr525pTiming;
486 UCHAR *YPbPr525iTiming;
487 UCHAR *HiTVGroup3Data;
488 UCHAR *HiTVGroup3Simu;
489 UCHAR *HiTVGroup3Text;
490 UCHAR *Ren525pGroup3;
491 UCHAR *Ren750pGroup3;
492 UCHAR *ScreenOffset;
493 UCHAR *pXGINew_DRAMTypeDefinition;
494 UCHAR *pXGINew_I2CDefinition ;
495 UCHAR *pXGINew_CR97 ;
496
497 XGI330_LCDCapStruct *LCDCapList;
498 XGI21_LVDSCapStruct *XG21_LVDSCapList;
499
500 XGI_TimingHStruct *TimingH;
501 XGI_TimingVStruct *TimingV;
502
503 XGI_StStruct *SModeIDTable;
504 XGI_StandTableStruct *StandTable;
505 XGI_ExtStruct *EModeIDTable;
506 XGI_Ext2Struct *RefIndex;
507 /* XGINew_CRT1TableStruct *CRT1Table; */
508 XGI_CRT1TableStruct *XGINEWUB_CRT1Table;
509 XGI_VCLKDataStruct *VCLKData;
510 XGI_VBVCLKDataStruct *VBVCLKData;
511 XGI_StResInfoStruct *StResInfo;
512 XGI_ModeResInfoStruct *ModeResInfo;
513 XGI_XG21CRT1Struct *UpdateCRT1;
514}; /* _VB_DEVICE_INFO */
515
516
517typedef struct
518{
519 USHORT Horizontal_ACTIVE;
520 USHORT Horizontal_FP;
521 USHORT Horizontal_SYNC;
522 USHORT Horizontal_BP;
523 USHORT Vertical_ACTIVE;
524 USHORT Vertical_FP;
525 USHORT Vertical_SYNC;
526 USHORT Vertical_BP;
527 double DCLK;
528 UCHAR FrameRate;
529 UCHAR Interlace;
530 USHORT Margin;
531} TimingInfo;
532
533#define _VB_STRUCT_
534#endif /* _VB_STRUCT_ */
diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h
new file mode 100644
index 000000000000..781caefc56b1
--- /dev/null
+++ b/drivers/staging/xgifb/vb_table.h
@@ -0,0 +1,4406 @@
1#define Tap4
2
3
4XGI_MCLKDataStruct XGI330New_MCLKData[]=
5{
6 { 0x5c,0x23,0x01,166},
7 { 0x5c,0x23,0x01,166},
8 { 0x7C,0x08,0x80,200},
9 { 0x79,0x06,0x80,250},
10 { 0x29,0x01,0x81,300},
11 { 0x29,0x01,0x81,300},
12 { 0x29,0x01,0x81,300},
13 { 0x29,0x01,0x81,300}
14};
15//yilin modify for xgi20
16XGI_MCLKDataStruct XGI340New_MCLKData[]=
17{
18 { 0x16,0x01,0x01,166},
19 { 0x19,0x02,0x01,124},
20 { 0x7C,0x08,0x01,200},
21 { 0x79,0x06,0x01,250},
22 { 0x29,0x01,0x81,301},
23 { 0x5c,0x23,0x01,166},
24 { 0x5c,0x23,0x01,166},
25 { 0x5c,0x23,0x01,166}
26};
27
28XGI_MCLKDataStruct XGI27New_MCLKData[]=
29{
30 { 0x5c,0x23,0x01,166},
31 { 0x19,0x02,0x01,124},
32 { 0x7C,0x08,0x80,200},
33 { 0x79,0x06,0x80,250},
34 { 0x29,0x01,0x81,300},
35 { 0x5c,0x23,0x01,166},
36 { 0x5c,0x23,0x01,166},
37 { 0x5c,0x23,0x01,166}
38};
39
40XGI_ECLKDataStruct XGI330_ECLKData[]=
41{
42 { 0x7c,0x08,0x01,200},
43 { 0x7c,0x08,0x01,200},
44 { 0x7C,0x08,0x80,200},
45 { 0x79,0x06,0x80,250},
46 { 0x29,0x01,0x81,300},
47 { 0x29,0x01,0x81,300},
48 { 0x29,0x01,0x81,300},
49 { 0x29,0x01,0x81,300}
50};
51//yilin modify for xgi20
52XGI_ECLKDataStruct XGI340_ECLKData[]=
53{
54 { 0x5c,0x23,0x01,166},
55 { 0x55,0x84,0x01,123},
56 { 0x7C,0x08,0x01,200},
57 { 0x79,0x06,0x01,250},
58 { 0x29,0x01,0x81,301},
59 { 0x5c,0x23,0x01,166},
60 { 0x5c,0x23,0x01,166},
61 { 0x5c,0x23,0x01,166}
62};
63
64
65
66UCHAR XGI340_SR13[4][8]={
67{0x35,0x45,0xb1,0x00,0x00,0x00,0x00,0x00},/* SR13 */
68{0x41,0x51,0x5c,0x00,0x00,0x00,0x00,0x00},/* SR14 */
69{0x31,0x42,0x42,0x00,0x00,0x00,0x00,0x00},/* SR18 */
70{0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00}/* SR1B */
71};
72
73UCHAR XGI340_cr41[24][8]=
74{{0x20,0x50,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
75{0xc4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
76{0xc4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
77{0xb5,0xa4,0xa4,0x00,0x00,0x00,0x00,0x00},
78{0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00},
79{0x90,0x90,0x24,0x00,0x00,0x00,0x00,0x00},/* 5 CR68 */
80{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 6 CR69 */
81{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 7 CR6A */
82{0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00},/* 8 CR6D */
83{0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x00},/* 9 CR80 */
84{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/* 10 CR81 */
85{0x88,0xa8,0x48,0x00,0x00,0x00,0x00,0x00},/* 11 CR82 */
86{0x44,0x44,0x77,0x00,0x00,0x00,0x00,0x00},/* 12 CR85 */
87{0x48,0x48,0x88,0x00,0x00,0x00,0x00,0x00},/* 13 CR86 */
88{0x54,0x54,0x44,0x00,0x00,0x00,0x00,0x00},/* 14 CR90 */
89{0x54,0x54,0x44,0x00,0x00,0x00,0x00,0x00},/* 15 CR91 */
90{0x0a,0x0a,0x07,0x00,0x00,0x00,0x00,0x00},/* 16 CR92 */
91{0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x00},/* 17 CR93 */
92{0x10,0x10,0x0A,0x00,0x00,0x00,0x00,0x00},/* 18 CR94 */
93{0x11,0x11,0x0a,0x00,0x00,0x00,0x00,0x00},/* 19 CR95 */
94{0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x00},/* 20 CR96 */
95{0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00},/* 21 CRC3 */
96{0x05,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/* 22 CRC4 */
97{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
98};
99
100
101UCHAR XGI27_cr41[24][8]=
102{
103{0x20,0x40,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
104{0xC4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
105{0xC4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
106{0xB5,0x13,0xa4,0x00,0x00,0x00,0x00,0x00},/* 3 CR40[7],CR99[2:0],CR45[3:0]*/
107{0xf0,0xf5,0xf0,0x00,0x00,0x00,0x00,0x00},/* 4 CR59 */
108{0x90,0x90,0x24,0x00,0x00,0x00,0x00,0x00},/* 5 CR68 */
109{0x77,0x67,0x44,0x00,0x00,0x00,0x00,0x00},/* 6 CR69 */
110{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 7 CR6A */
111{0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00},/* 8 CR6D */
112{0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x00},/* 9 CR80 */
113{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/* 10 CR81 */
114{0x88,0xcc,0x48,0x00,0x00,0x00,0x00,0x00},/* 11 CR82 */
115{0x44,0x88,0x77,0x00,0x00,0x00,0x00,0x00},/* 12 CR85 */
116{0x48,0x88,0x88,0x00,0x00,0x00,0x00,0x00},/* 13 CR86 */
117{0x54,0x32,0x44,0x00,0x00,0x00,0x00,0x00},/* 14 CR90 */
118{0x54,0x33,0x44,0x00,0x00,0x00,0x00,0x00},/* 15 CR91 */
119{0x0a,0x07,0x07,0x00,0x00,0x00,0x00,0x00},/* 16 CR92 */
120{0x44,0x63,0x44,0x00,0x00,0x00,0x00,0x00},/* 17 CR93 */
121{0x10,0x14,0x0A,0x00,0x00,0x00,0x00,0x00},/* 18 CR94 */
122{0x11,0x0B,0x0C,0x00,0x00,0x00,0x00,0x00},/* 19 CR95 */
123{0x05,0x22,0x05,0x00,0x00,0x00,0x00,0x00},/* 20 CR96 */
124{0xf0,0xf0,0x00,0x00,0x00,0x00,0x00,0x00},/* 21 CRC3 */
125{0x05,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/* 22 CRC4 */
126{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
127};
128
129
130#if 0
131UCHAR XGI27_cr41[24][8]=
132{
133{0x20,0x60,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
134{0x04,0x44,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
135{0x04,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
136{0xb5,0x03,0xa4,0x00,0x00,0x00,0x00,0x00},/* 3 CR40[7],CR99[2:0],CR45[3:0]*/
137{0xf0,0xf5,0xf0,0x00,0x00,0x00,0x00,0x00},/* 4 CR59 */
138{0xa4,0x1C,0x24,0x00,0x00,0x00,0x00,0x00},/* 5 CR68 */
139{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 6 CR69 */
140{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 7 CR6A */
141{0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00},/* 8 CR6D */
142{0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x00},/* 9 CR80 */
143{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/* 10 CR81 */
144{0x48,0xa8,0x48,0x00,0x00,0x00,0x00,0x00},/* 11 CR82 */
145{0x77,0x88,0x77,0x00,0x00,0x00,0x00,0x00},/* 12 CR85 */
146{0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00},/* 13 CR86 */
147{0x44,0x32,0x44,0x00,0x00,0x00,0x00,0x00},/* 14 CR90 */
148{0x44,0x33,0x44,0x00,0x00,0x00,0x00,0x00},/* 15 CR91 */
149{0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00},/* 16 CR92 */
150{0x44,0x63,0x44,0x00,0x00,0x00,0x00,0x00},/* 17 CR93 */
151{0x0A,0x14,0x0A,0x00,0x00,0x00,0x00,0x00},/* 18 CR94 */
152{0x0C,0x0B,0x0C,0x00,0x00,0x00,0x00,0x00},/* 19 CR95 */
153{0x05,0x22,0x05,0x00,0x00,0x00,0x00,0x00},/* 20 CR96 */
154{0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00},/* 21 CRC3 */
155{0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/* 22 CRC4 */
156{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
157};
158#endif
159UCHAR XGI340_CR6B[8][4]={
160{0xaa,0xaa,0xaa,0xaa},
161{0xaa,0xaa,0xaa,0xaa},
162{0xaa,0xaa,0xaa,0xaa},
163{0x00,0x00,0x00,0x00},
164{0x00,0x00,0x00,0x00},
165{0x00,0x00,0x00,0x00},
166{0x00,0x00,0x00,0x00},
167{0x00,0x00,0x00,0x00}
168};
169
170UCHAR XGI340_CR6E[8][4]={
171{0x00,0x00,0x00,0x00},
172{0x00,0x00,0x00,0x00},
173{0x00,0x00,0x00,0x00},
174{0x00,0x00,0x00,0x00},
175{0x00,0x00,0x00,0x00},
176{0x00,0x00,0x00,0x00},
177{0x00,0x00,0x00,0x00},
178{0x00,0x00,0x00,0x00}
179};
180
181UCHAR XGI340_CR6F[8][32]={
182{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
183{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
184{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
185{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
186{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
187{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
188{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
189{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
190};
191
192UCHAR XGI340_CR89[8][2]={
193{0x00,0x00},
194{0x00,0x00},
195{0x00,0x00},
196{0x00,0x00},
197{0x00,0x00},
198{0x00,0x00},
199{0x00,0x00},
200{0x00,0x00}
201};
202 /* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */
203UCHAR XGI340_AGPReg[12]={0x28,0x23,0x00,0x20,0x00,0x20,0x00,0x05,0xd0,0x10,0x10,0x00};
204
205UCHAR XGI340_SR16[4]={0x03,0x83,0x03,0x83};
206
207UCHAR XGI330_SR15_1[8][8]={
208{0x0,0x0,0x00,0x00,0x20,0x20,0x00,0x00},
209{0x5,0x15,0x15,0x15,0x15,0x15,0x00,0x00},
210{0xba,0xba,0xba,0xba,0xBA,0xBA,0x00,0x00},
211{0x55,0x57,0x57,0xAB,0xAB,0xAB,0x00,0x00},
212{0x60,0x34,0x34,0x34,0x34,0x34,0x00,0x00},
213{0x0,0x80,0x80,0x80,0x83,0x83,0x00,0x00},
214{0x50,0x50,0x50,0x3C,0x3C,0x3C,0x00,0x00},
215{0x0,0xa5,0xfb,0xf6,0xF6,0xF6,0x00,0x00}
216};
217
218UCHAR XGI330_cr40_1[15][8]={
219{0x66,0x40,0x40,0x28,0x24,0x24,0x00,0x00},
220{0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
221{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
222{0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00},
223{0x00,0xf0,0xf0,0xf0,0xF0,0xF0,0x00,0x00},
224{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
225{0x10,0x10,0x10,0x10,0x20,0x20,0x00,0x00},
226{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
227{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
228{0x88,0x88,0x88,0xAA,0xAC,0xAC,0x00,0x00},
229{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
230{0x00,0x00,0x00,0x00,0x77,0x77,0x00,0x00},
231{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
232{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
233{0x00,0xA2,0x00,0x00,0xA2,0xA2,0x00,0x00},
234};
235
236UCHAR XGI330_sr25[]={0x00,0x0};
237UCHAR XGI330_sr31=0xc0;
238UCHAR XGI330_sr32=0x11;
239UCHAR XGI330_SR33=0x00;
240UCHAR XG40_CRCF=0x13;
241UCHAR XG40_DRAMTypeDefinition=0xFF ;
242
243XGI_StStruct XGI330_SModeIDTable[]=
244{
245 {0x01,0x9208,0x01,0x00,0x10,0x00,0x00,0x01,0x00},
246 {0x01,0x1210,0x14,0x01,0x00,0x01,0x00,0x01,0x00},
247 {0x01,0x1010,0x17,0x02,0x11,0x00,0x00,0x01,0x01},
248 {0x03,0x8208,0x03,0x00,0x14,0x00,0x00,0x01,0x02},
249 {0x03,0x0210,0x16,0x01,0x04,0x01,0x00,0x01,0x02},
250 {0x03,0x0010,0x18,0x02,0x15,0x00,0x00,0x01,0x03},
251 {0x05,0x9209,0x05,0x00,0x10,0x00,0x00,0x00,0x04},
252 {0x06,0x8209,0x06,0x00,0x14,0x00,0x00,0x00,0x05},
253 {0x07,0x0000,0x07,0x03,0x05,0x03,0x00,0x01,0x03},
254 {0x07,0x0000,0x19,0x02,0x15,0x02,0x00,0x01,0x03},
255 {0x0d,0x920a,0x0d,0x00,0x10,0x00,0x00,0x00,0x04},
256 {0x0e,0x820a,0x0e,0x00,0x14,0x00,0x00,0x00,0x05},
257 {0x0f,0x0202,0x11,0x01,0x04,0x01,0x00,0x00,0x05},
258 {0x10,0x0212,0x12,0x01,0x04,0x01,0x00,0x00,0x05},
259 {0x11,0x0212,0x1a,0x04,0x24,0x04,0x00,0x00,0x05},
260 {0x12,0x0212,0x1b,0x04,0x24,0x04,0x00,0x00,0x05},
261 {0x13,0x021b,0x1c,0x00,0x14,0x00,0x00,0x00,0x04},
262 {0x12,0x0010,0x18,0x02,0x24,0x02,0x00,0x00,0x05},/* St_CRT2CRTC2 not sure */
263 {0x12,0x0210,0x18,0x01,0x24,0x01,0x00,0x00,0x05},/* St_CRT2CRTC2 not sure */
264 {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
265};
266
267
268XGI_ExtStruct XGI330_EModeIDTable[]=
269{
270 {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x0e},
271 {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x06},
272 {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x05},
273 {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x0e},
274 {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x3d},
275 {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x3e},
276 {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x3d},
277 {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x3e},
278 {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x3d},
279 {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x3e},
280 {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x00,0x16},
281 {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x16},
282 {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1e},
283 {0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x22}, /* mode 1600x1200 add CRT2MODE [2003/10/07] */
284 {0x3d,0x0e7d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x22}, /* mode 1600x1200 add CRT2MODE */
285 {0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x00},
286 {0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x00}, /* ModeIdIndex = 0x10 */
287 {0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x06},
288 {0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x06},
289 {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x0e},
290 {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x0e},
291 {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x16},
292 {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x00,0x16},
293 {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1e},
294 {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1e},
295 {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x02},
296 {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x03},
297 {0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x04},
298 {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x02},
299 {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x03},
300 {0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x04},
301 {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x00},
302 {0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f}, /* ModeIdIndex = 0x20 */
303 {0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f},
304 {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x05},
305 {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x06},
306 {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x0e},
307 {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x00,0x16},
308 {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1e},
309 {0x66,0x0eff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x22}, /* mode 1600x1200 add CRT2MODE */
310 {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},
311 {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},
312 {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},
313 {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},
314 {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
315 {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
316 {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
317 {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
318 {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* ModeIdIndex = 0x30 */
319 {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
320 {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
321 {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
322 {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
323 {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
324 {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
325 {0x7b,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x1d},
326 {0x7c,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x1d},
327 {0x7d,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x1d},
328 {0x20,0x0e3b,0x0D16,0x49e0,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
329 {0x21,0x0e7d,0x0D16,0x49e0,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
330 {0x22,0x0eff,0x0D16,0x49e0,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
331 {0x23,0x0e3b,0x0614,0x49d5,0x0000,0x08,0x14,0x00,0x00,0x00,0x41},
332 {0x24,0x0e7d,0x0614,0x49d5,0x0000,0x08,0x14,0x00,0x00,0x00,0x41},
333 {0x25,0x0eff,0x0614,0x49d5,0x0000,0x08,0x14,0x00,0x00,0x00,0x41},
334 {0x26,0x063b,0x0c15,0x49dc,0x0000,0x08,0x15,0x00,0x00,0x00,0x42}, /* ModeIdIndex = 0x40 */
335 {0x27,0x067d,0x0c15,0x49dc,0x0000,0x08,0x15,0x00,0x00,0x00,0x42},
336 {0x28,0x06ff,0x0c15,0x49dc,0x0000,0x08,0x15,0x00,0x00,0x00,0x42},
337 {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
338};
339
340XGI_StandTableStruct XGI330_StandTable[]=
341{
342/* MD_0_200 */
343 {
344 0x28,0x18,0x08,0x0800,
345 {0x09,0x03,0x00,0x02},
346 0x63,
347 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
348 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
349 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
350 0xff},
351 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
352 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
353 0x08,0x00,0x0f,0x00},
354 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
355 0xff}
356 },
357/* MD_1_200 */
358 {
359 0x28,0x18,0x08,0x0800,
360 {0x09,0x03,0x00,0x02},
361 0x63,
362 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
363 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
364 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
365 0xff},
366 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
367 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
368 0x08,0x00,0x0f,0x00},
369 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
370 0xff}
371 },
372/* MD_2_200 */
373 {
374 0x50,0x18,0x08,0x1000,
375 {0x01,0x03,0x00,0x02},
376 0x63,
377 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
378 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
379 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
380 0xff},
381 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
382 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
383 0x08,0x00,0x0f,0x00},
384 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
385 0xff}
386 },
387/* MD_3_200 */
388 {
389 0x50,0x18,0x08,0x1000,
390 {0x01,0x03,0x00,0x02},
391 0x63,
392 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
393 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
394 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
395 0xff},
396 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
397 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
398 0x08,0x00,0x0f,0x00},
399 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
400 0xff}
401 },
402/* MD_4 */
403 {
404 0x28,0x18,0x08,0x4000,
405 {0x09,0x03,0x00,0x02},
406 0x63,
407 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
408 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
409 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
410 0xff},
411 {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
412 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
413 0x01,0x00,0x03,0x00},
414 {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
415 0xff}
416 },
417/* MD_5 */
418 {
419 0x28,0x18,0x08,0x4000,
420 {0x09,0x03,0x00,0x02},
421 0x63,
422 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
423 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
424 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
425 0xff},
426 {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
427 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
428 0x01,0x00,0x03,0x00},
429 {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
430 0xff}
431 },
432/* MD_6 */
433 {
434 0x50,0x18,0x08,0x4000,
435 {0x01,0x01,0x00,0x06},
436 0x63,
437 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
438 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
439 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
440 0xff},
441 {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
442 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
443 0x01,0x00,0x01,0x00},
444 {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
445 0xff}
446 },
447/* MD_7 */
448 {
449 0x50,0x18,0x0e,0x1000,
450 {0x00,0x03,0x00,0x03},
451 0xa6,
452 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
453 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
454 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
455 0xff},
456 {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
457 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
458 0x0e,0x00,0x0f,0x08},
459 {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
460 0xff}
461 },
462/* MDA_DAC */
463 {
464 0x00,0x00,0x00,0x0000,
465 {0x00,0x00,0x00,0x15},
466 0x15,
467 {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
468 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
469 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
470 0x00},
471 {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
472 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
473 0x15,0x15,0x15,0x15},
474 {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
475 0x3f}
476 },
477/* CGA_DAC */
478 {
479 0x00,0x10,0x04,0x0114,
480 {0x11,0x09,0x15,0x00},
481 0x10,
482 {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
483 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
484 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
485 0x04},
486 {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
487 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
488 0x3e,0x2b,0x3b,0x2f},
489 {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
490 0x3f}
491 },
492/* EGA_DAC */
493 {
494 0x00,0x10,0x04,0x0114,
495 {0x11,0x05,0x15,0x20},
496 0x30,
497 {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
498 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
499 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
500 0x06},
501 {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
502 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
503 0x1e,0x0b,0x1b,0x0f},
504 {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
505 0x3f}
506 },
507/* VGA_DAC */
508 {
509 0x00,0x10,0x04,0x0114,
510 {0x11,0x09,0x15,0x2a},
511 0x3a,
512 {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
513 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
514 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
515 0x1f},
516 {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
517 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
518 0x1c,0x0e,0x11,0x15},
519 {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
520 0x04}
521 },
522 {
523 0x08,0x0c,0x10,0x0a08,
524 {0x0c,0x0e,0x10,0x0b},
525 0x0c,
526 {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
527 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
528 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
529 0x06},
530 {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
531 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
532 0x00,0x00,0x00,0x00},
533 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
534 0x00}
535 },
536/* MD_D */
537 {
538 0x28,0x18,0x08,0x2000,
539 {0x09,0x0f,0x00,0x06},
540 0x63,
541 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
542 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
543 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
544 0xff},
545 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
546 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
547 0x01,0x00,0x0f,0x00},
548 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
549 0xff}
550 },
551/* MD_E */
552 {
553 0x50,0x18,0x08,0x4000,
554 {0x01,0x0f,0x00,0x06},
555 0x63,
556 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
557 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
558 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
559 0xff},
560 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
561 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
562 0x01,0x00,0x0f,0x00},
563 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
564 0xff}
565 },
566/* ExtVGATable */
567 {
568 0x00,0x00,0x00,0x0000,
569 {0x01,0x0f,0x00,0x0e},
570 0x23,
571 {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
572 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
573 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
574 0xff},
575 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
576 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
577 0x01,0x00,0x00,0x00},
578 {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
579 0xff}
580 },
581/* ROM_SAVEPTR */
582 {
583 0x9f,0x3b,0x00,0x00c0,
584 {0x00,0x00,0x00,0x00},
585 0x00,
586 {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
587 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
588 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
589 0x00},
590 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
591 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
592 0x00,0x00,0x00,0x00},
593 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
594 0x00}
595 },
596/* MD_F */
597 {
598 0x50,0x18,0x0e,0x8000,
599 {0x01,0x0f,0x00,0x06},
600 0xa2,
601 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
602 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
603 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
604 0xff},
605 {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
606 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
607 0x0b,0x00,0x05,0x00},
608 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
609 0xff}
610 },
611/* MD_10 */
612 {
613 0x50,0x18,0x0e,0x8000,
614 {0x01,0x0f,0x00,0x06},
615 0xa3,
616 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
617 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
618 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
619 0xff},
620 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
621 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
622 0x01,0x00,0x0f,0x00},
623 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
624 0xff}
625 },
626/* MD_0_350 */
627 {
628 0x28,0x18,0x0e,0x0800,
629 {0x09,0x03,0x00,0x02},
630 0xa3,
631 {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
632 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
633 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
634 0xff},
635 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
636 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
637 0x08,0x00,0x0f,0x00},
638 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
639 0xff}
640 },
641/* MD_1_350 */
642 {
643 0x28,0x18,0x0e,0x0800,
644 {0x09,0x03,0x00,0x02},
645 0xa3,
646 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
647 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
648 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
649 0xff},
650 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
651 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
652 0x08,0x00,0x0f,0x00},
653 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
654 0xff}
655 },
656/* MD_2_350 */
657 {
658 0x50,0x18,0x0e,0x1000,
659 {0x01,0x03,0x00,0x02},
660 0xa3,
661 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
662 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
663 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
664 0xff},
665 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
666 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
667 0x08,0x00,0x0f,0x00},
668 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
669 0xff}
670 },
671/* MD_3_350 */
672 {
673 0x50,0x18,0x0e,0x1000,
674 {0x01,0x03,0x00,0x02},
675 0xa3,
676 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
677 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
678 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
679 0xff},
680 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
681 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
682 0x08,0x00,0x0f,0x00},
683 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
684 0xff}
685 },
686/* MD_0_1_400 */
687 {
688 0x28,0x18,0x10,0x0800,
689 {0x08,0x03,0x00,0x02},
690 0x67,
691 {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
692 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
693 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
694 0xff},
695 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
696 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
697 0x0c,0x00,0x0f,0x08},
698 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
699 0xff}
700 },
701/* MD_2_3_400 */
702 {
703 0x50,0x18,0x10,0x1000,
704 {0x00,0x03,0x00,0x02},
705 0x67,
706 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
707 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
708 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
709 0xff},
710 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
711 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
712 0x0c,0x00,0x0f,0x08},
713 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
714 0xff}
715 },
716/* MD_7_400 */
717 {
718 0x50,0x18,0x10,0x1000,
719 {0x00,0x03,0x00,0x02},
720 0x66,
721 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
722 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
723 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
724 0xff},
725 {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
726 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
727 0x0e,0x00,0x0f,0x08},
728 {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
729 0xff}
730 },
731/* MD_11 */
732 {
733 0x50,0x1d,0x10,0xa000,
734 {0x01,0x0f,0x00,0x06},
735 0xe3,
736 {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
737 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
738 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
739 0xff},
740 {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
741 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
742 0x01,0x00,0x0f,0x00},
743 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
744 0xff}
745 },
746/* ExtEGATable */
747 {
748 0x50,0x1d,0x10,0xa000,
749 {0x01,0x0f,0x00,0x06},
750 0xe3,
751 {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
752 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
753 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
754 0xff},
755 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
756 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
757 0x01,0x00,0x0f,0x00},
758 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
759 0xff}
760 },
761/* MD_13 */
762 {
763 0x28,0x18,0x08,0x2000,
764 {0x01,0x0f,0x00,0x0e},
765 0x63,
766 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
767 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
768 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
769 0xff},
770 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
771 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
772 0x41,0x00,0x0f,0x00},
773 {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
774 0xff}
775 }
776};
777
778XGI_TimingHStruct XGI_TimingH[]=
779{{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
780
781XGI_TimingVStruct XGI_TimingV[]=
782{{{0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
783
784XGI_XG21CRT1Struct XGI_UpdateCRT1Table[]=
785{
786 {0x01,0x27,0x91,0x8f,0xc0}, /* 00 */
787 {0x03,0x4f,0x83,0x8f,0xc0}, /* 01 */
788 {0x05,0x27,0x91,0x8f,0xc0}, /* 02 */
789 {0x06,0x4f,0x83,0x8f,0xc0}, /* 03 */
790 {0x07,0x4f,0x83,0x8f,0xc0}, /* 04 */
791 {0x0d,0x27,0x91,0x8f,0xc0}, /* 05 */
792 {0x0e,0x4f,0x83,0x8f,0xc0}, /* 06 */
793 {0x0f,0x4f,0x83,0x5d,0xc0}, /* 07 */
794 {0x10,0x4f,0x83,0x5d,0xc0}, /* 08 */
795 {0x11,0x4f,0x83,0xdf,0x0c}, /* 09 */
796 {0x12,0x4f,0x83,0xdf,0x0c}, /* 10 */
797 {0x13,0x4f,0x83,0x8f,0xc0}, /* 11 */
798 {0x2e,0x4f,0x83,0xdf,0x0c}, /* 12 */
799 {0x2e,0x4f,0x87,0xdf,0xc0}, /* 13 */
800 {0x2f,0x4f,0x83,0x8f,0xc0}, /* 14 */
801 {0x50,0x27,0x91,0xdf,0x0c}, /* 15 */
802 {0x59,0x27,0x91,0x8f,0xc0} /* 16 */
803};
804
805XGI_CRT1TableStruct XGI_CRT1Table[]=
806{
807 {{0x2d,0x28,0x90,0x2c,0x90,0x00,0x04,0x00,
808 0xbf,0x1f,0x9c,0x8e,0x96,0xb9,0x30}}, /* 0x0 */
809 {{0x2d,0x28,0x90,0x2c,0x90,0x00,0x04,0x00,
810 0x0b,0x3e,0xe9,0x8b,0xe7,0x04,0x00}}, /* 0x1 */
811 {{0x3D,0x31,0x81,0x37,0x1F,0x00,0x05,0x00,
812 0x72,0xF0,0x58,0x8C,0x57,0x73,0xA0}}, /* 0x2 */
813 {{0x4F,0x3F,0x93,0x45,0x0D,0x00,0x01,0x00,
814 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90}}, /* 0x3 */
815 {{0x5F,0x50,0x82,0x55,0x81,0x00,0x05,0x00,
816 0xBF,0x1F,0x9C,0x8E,0x96,0xB9,0x30}}, /* 0x4 */
817 {{0x5F,0x50,0x82,0x55,0x81,0x00,0x05,0x00,
818 0x0B,0x3E,0xE9,0x8B,0xE7,0x04,0x00}}, /* 0x5 */
819 {{0x63,0x50,0x86,0x56,0x9B,0x00,0x01,0x00,
820 0x06,0x3E,0xE8,0x8B,0xE7,0xFF,0x10}}, /* 0x6 */
821 {{0x64,0x4F,0x88,0x55,0x9D,0x00,0x01,0x00,
822 0xF2,0x1F,0xE0,0x83,0xDF,0xF3,0x10}}, /* 0x7 */
823 {{0x63,0x4F,0x87,0x5A,0x81,0x00,0x05,0x00,
824 0xFB,0x1F,0xE0,0x83,0xDF,0xFC,0x10}}, /* 0x8 */
825 {{0x65,0x4F,0x89,0x58,0x80,0x00,0x05,0x60,
826 0xFB,0x1F,0xE0,0x83,0xDF,0xFC,0x80}}, /* 0x9 */
827 {{0x65,0x4F,0x89,0x58,0x80,0x00,0x05,0x60,
828 0x01,0x3E,0xE0,0x83,0xDF,0x02,0x80}}, /* 0xa */
829 {{0x67,0x4F,0x8B,0x58,0x81,0x00,0x05,0x60,
830 0x0D,0x3E,0xE0,0x83,0xDF,0x0E,0x90}}, /* 0xb */
831 {{0x65,0x4F,0x89,0x57,0x9F,0x00,0x01,0x00,
832 0xFB,0x1F,0xE6,0x8A,0xDF,0xFC,0x10}}, /* 0xc */
833 {{0x7B,0x63,0x9F,0x6A,0x93,0x00,0x05,0x00, /* ; 0D (800x600,56Hz) */
834 0x6F,0xF0,0x58,0x8A,0x57,0x70,0xA0}}, /* ; (VCLK 36.0MHz) */
835 {{0x7F,0x63,0x83,0x6C,0x1C,0x00,0x06,0x00, /* ; 0E (800x600,60Hz) */
836 0x72,0xF0,0x58,0x8C,0x57,0x73,0xA0}}, /* ; (VCLK 40.0MHz) */
837 {{0x7D,0x63,0x81,0x6E,0x1D,0x00,0x06,0x00, /* ; 0F (800x600,72Hz) */
838 0x98,0xF0,0x7C,0x82,0x57,0x99,0x80}}, /* ; (VCLK 50.0MHz) */
839 {{0x7F,0x63,0x83,0x69,0x13,0x00,0x06,0x00, /* ; 10 (800x600,75Hz) */
840 0x6F,0xF0,0x58,0x8B,0x57,0x70,0xA0}}, /* ; (VCLK 49.5MHz) */
841 {{0x7E,0x63,0x82,0x6B,0x13,0x00,0x06,0x00, /* ; 11 (800x600,85Hz) */
842 0x75,0xF0,0x58,0x8B,0x57,0x76,0xA0}}, /* ; (VCLK 56.25MHz) */
843 {{0x81,0x63,0x85,0x6D,0x18,0x00,0x06,0x60, /* ; 12 (800x600,100Hz) */
844 0x7A,0xF0,0x58,0x8B,0x57,0x7B,0xA0}}, /* ; (VCLK 75.8MHz) */
845 {{0x83,0x63,0x87,0x6E,0x19,0x00,0x06,0x60, /* ; 13 (800x600,120Hz) */
846 0x81,0xF0,0x58,0x8B,0x57,0x82,0xA0}}, /* ; (VCLK 79.411MHz) */
847 {{0x85,0x63,0x89,0x6F,0x1A,0x00,0x06,0x60, /* ; 14 (800x600,160Hz) */
848 0x91,0xF0,0x58,0x8B,0x57,0x92,0xA0}}, /* ; (VCLK 105.822MHz) */
849 {{0x99,0x7F,0x9D,0x84,0x1A,0x00,0x02,0x00,
850 0x96,0x1F,0x7F,0x83,0x7F,0x97,0x10}}, /* 0x15 */
851 {{0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00,
852 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90}}, /* 0x16 */
853 {{0xA1,0x7F,0x85,0x86,0x97,0x00,0x02,0x00,
854 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90}}, /* 0x17 */
855 {{0x9F,0x7F,0x83,0x85,0x91,0x00,0x02,0x00,
856 0x1E,0xF5,0x00,0x83,0xFF,0x1F,0x90}}, /* 0x18 */
857 {{0xA7,0x7F,0x8B,0x89,0x95,0x00,0x02,0x00,
858 0x26,0xF5,0x00,0x83,0xFF,0x27,0x90}}, /* 0x19 */
859 {{0xA9,0x7F,0x8D,0x8C,0x9A,0x00,0x02,0x62,
860 0x2C,0xF5,0x00,0x83,0xFF,0x2D,0x14}}, /* 0x1a */
861 {{0xAB,0x7F,0x8F,0x8D,0x9B,0x00,0x02,0x62,
862 0x35,0xF5,0x00,0x83,0xFF,0x36,0x14}}, /* 0x1b */
863 {{0xCF,0x9F,0x93,0xB2,0x01,0x00,0x03,0x00,
864 0x14,0xBA,0x00,0x83,0xFF,0x15,0x00}}, /* 0x1c */
865 {{0xCE,0x9F,0x92,0xA9,0x17,0x00,0x07,0x00,
866 0x28,0x5A,0x00,0x83,0xFF,0x29,0x89}}, /* 0x1d */
867 {{0xCE,0x9F,0x92,0xA5,0x17,0x00,0x07,0x00,
868 0x28,0x5A,0x00,0x83,0xFF,0x29,0x89}}, /* 0x1e */
869 {{0xD3,0x9F,0x97,0xAB,0x1F,0x00,0x07,0x00,
870 0x2E,0x5A,0x00,0x83,0xFF,0x2F,0x89}}, /* 0x1f */
871 {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
872 0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x20 */
873 {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
874 0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x21 */
875 {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
876 0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x22 */
877 {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
878 0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x23 */
879 {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
880 0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x24 */
881 {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
882 0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x25 */
883 {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
884 0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x26 */
885 {{0x40,0xEF,0x84,0x03,0x1D,0x41,0x01,0x00,
886 0xDA,0x1F,0xA0,0x83,0x9F,0xDB,0x1F}}, /* 0x27 */
887 {{0x43,0xEF,0x87,0x06,0x00,0x41,0x05,0x62,
888 0xD4,0x1F,0xA0,0x83,0x9F,0xD5,0x9F}}, /* 0x28 */
889 {{0x45,0xEF,0x89,0x07,0x01,0x41,0x05,0x62,
890 0xD9,0x1F,0xA0,0x83,0x9F,0xDA,0x9F}}, /* 0x29 */
891 {{0x40,0xEF,0x84,0x03,0x1D,0x41,0x01,0x00,
892 0xDA,0x1F,0xA0,0x83,0x9F,0xDB,0x1F}}, /* 0x2a */
893 {{0x40,0xEF,0x84,0x03,0x1D,0x41,0x01,0x00,
894 0xDA,0x1F,0xA0,0x83,0x9F,0xDB,0x1F}}, /* 0x2b */
895 {{0x40,0xEF,0x84,0x03,0x1D,0x41,0x01,0x00,
896 0xDA,0x1F,0xA0,0x83,0x9F,0xDB,0x1F}}, /* 0x2c */
897 {{0x59,0xFF,0x9D,0x17,0x13,0x41,0x05,0x44,
898 0x33,0xBA,0x00,0x83,0xFF,0x34,0x0F}}, /* 0x2d */
899 {{0x5B,0xFF,0x9F,0x18,0x14,0x41,0x05,0x44,
900 0x38,0xBA,0x00,0x83,0xFF,0x39,0x0F}}, /* 0x2e */
901 {{0x5B,0xFF,0x9F,0x18,0x14,0x41,0x05,0x44,
902 0x3D,0xBA,0x00,0x83,0xFF,0x3E,0x0F}}, /* 0x2f */
903 {{0x5D,0xFF,0x81,0x19,0x95,0x41,0x05,0x44,
904 0x41,0xBA,0x00,0x84,0xFF,0x42,0x0F}}, /* 0x30 */
905 {{0x55,0xFF,0x99,0x0D,0x0C,0x41,0x05,0x00,
906 0x3E,0xBA,0x00,0x84,0xFF,0x3F,0x0F}}, /* 0x31 */
907 {{0x7F,0x63,0x83,0x6C,0x1C,0x00,0x06,0x00,
908 0x72,0xBA,0x27,0x8B,0xDF,0x73,0x80}}, /* 0x32 */
909 {{0x7F,0x63,0x83,0x69,0x13,0x00,0x06,0x00,
910 0x6F,0xBA,0x26,0x89,0xDF,0x6F,0x80}}, /* 0x33 */
911 {{0x7F,0x63,0x82,0x6B,0x13,0x00,0x06,0x00,
912 0x75,0xBA,0x29,0x8C,0xDF,0x75,0x80}}, /* 0x34 */
913 {{0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00,
914 0x24,0xF1,0xAF,0x85,0x3F,0x25,0xB0}}, /* 0x35 */
915 {{0x9F,0x7F,0x83,0x85,0x91,0x00,0x02,0x00,
916 0x1E,0xF1,0xAD,0x81,0x3F,0x1F,0xB0}}, /* 0x36 */
917 {{0xA7,0x7F,0x88,0x89,0x15,0x00,0x02,0x00,
918 0x26,0xF1,0xB1,0x85,0x3F,0x27,0xB0}}, /* 0x37 */
919 {{0xCE,0x9F,0x92,0xA9,0x17,0x00,0x07,0x00,
920 0x28,0xC4,0x7A,0x8E,0xCF,0x29,0xA1}}, /* 0x38 */
921 {{0xCE,0x9F,0x92,0xA5,0x17,0x00,0x07,0x00,
922 0x28,0xD4,0x7A,0x8E,0xCF,0x29,0xA1}}, /* 0x39 */
923 {{0xD3,0x9F,0x97,0xAB,0x1F,0x00,0x07,0x00,
924 0x2E,0xD4,0x7D,0x81,0xCF,0x2F,0xA1}}, /* 0x3a */
925 {{0xDC,0x9F,0x00,0xAB,0x19,0x00,0x07,0x00,
926 0xE6,0xEF,0xC0,0xC3,0xBF,0xE7,0x90}}, /* 0x3b */
927 {{0x6B,0x59,0x8F,0x5E,0x8C,0x00,0x05,0x00,
928 0x0B,0x3E,0xE9,0x8B,0xE7,0x04,0x00}}, /* 0x3c */
929 {{0x7B,0x63,0x9F,0x6A,0x93,0x00,0x05,0x00,
930 0x6F,0xF0,0x58,0x8A,0x57,0x70,0xA0}}, /* 0x3d */
931 {{0x86,0x6A,0x8a,0x74,0x06,0x00,0x02,0x00,
932 0x8c,0x15,0x4f,0x83,0xef,0x8d,0x30}}, /* 0x3e */
933 {{0x81,0x6A,0x85,0x70,0x00,0x00,0x02,0x00,
934 0x0f,0x3e,0xeb,0x8e,0xdf,0x10,0x00}}, /* 0x3f */
935 {{0xCE,0x9F,0x92,0xA9,0x17,0x00,0x07,0x00,
936 0x20,0xF5,0x03,0x88,0xFF,0x21,0x90}}, /* 0x40 */
937 {{0xE6,0xAE,0x8A,0xBD,0x90,0x00,0x03,0x00,
938 0x3D,0x10,0x1A,0x8D,0x19,0x3E,0x2F}}, /* 0x41 */
939 {{0xB9,0x8F,0x9D,0x9B,0x8A,0x00,0x06,0x00,
940 0x7D,0xFF,0x60,0x83,0x5F,0x7E,0x90}}, /* 0x42 */
941 {{0xC3,0x8F,0x87,0x9B,0x0B,0x00,0x07,0x00,
942 0x82,0xFF,0x60,0x83,0x5F,0x83,0x90}}, /* 0x43 */
943 {{0xAD,0x7F,0x91,0x8E,0x9C,0x00,0x02,0x82,
944 0x49,0xF5,0x00,0x83,0xFF,0x4A,0x90}}, /* 0x44 */
945 {{0xCD,0x9F,0x91,0xA7,0x19,0x00,0x07,0x60,
946 0xE6,0xFF,0xC0,0x83,0xBF,0xE7,0x90}}, /* 0x45 */
947 {{0xD3,0x9F,0x97,0xAB,0x1F,0x00,0x07,0x60,
948 0xF1,0xFF,0xC0,0x83,0xBF,0xF2,0x90}}, /* 0x46 */
949 {{0xD7,0x9F,0x9B,0xAC,0x1E,0x00,0x07,0x00,
950 0x03,0xDE,0xC0,0x84,0xBF,0x04,0x90}} /* 0x47 */
951};
952
953XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = {
954 /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
955 {{ 0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 00 (640x200,640x400) */
956 {{ 0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 01 (640x350) */
957 {{ 0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 02 (720x400) */
958 {{ 0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 03 (720x350) */
959 {{ 0x6A,0x77,0xBB,0x6E,0x84,0x2E,0x02,0x5A,0x04,0x00,0x80,0x20,0x7E,0x80,0x97,0x00 }},/* 04 (640x480) ;;5/6/02 */
960 {{ 0xCF,0x77,0xB7,0xC8,0x84,0x3B,0x02,0x5A,0x04,0x00,0x80,0x19,0x88,0xAE,0xA3,0x00 }},/* 05 (800x600) ;;1/12/02 */
961 {{ 0xEE,0x77,0xBB,0x66,0x87,0x32,0x01,0x5A,0x04,0x00,0x80,0x1B,0xD4,0x2F,0x6F,0x00 }}/* 06 (1024x768) ;;5/6/02 */
962 };
963
964XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[]= {
965 /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
966 {{ 0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 00 (640x200,640x400) */
967 {{ 0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 01 (640x350) */
968 {{ 0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 02 (720x400) */
969 {{ 0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 03 (720x350) */
970 {{ 0x69,0x77,0xBB,0x6E,0x84,0x1E,0x00,0x5A,0x04,0x00,0x80,0x25,0x1A,0x80,0x26,0x00 }},/* 04 (640x480) ;;5/6/02 */
971 {{ 0xCE,0x77,0xB7,0xB6,0x83,0x2C,0x02,0x5A,0x04,0x00,0x80,0x1C,0x00,0x82,0x97,0x00 }},/* 05 (800x600) ;;5/6/02 */
972 {{ 0xED,0x77,0xBB,0x66,0x8C,0x21,0x02,0x5A,0x04,0x00,0x80,0x1F,0xA0,0x7E,0x73,0x00 }}/* 06 (1024x768) ;;5/6/02 */
973 };
974
975XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[]= {
976 /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
977 {{ 0x41,0x7F,0xB7,0x34,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* ; 00 (640x200,640x400) */
978 {{ 0x41,0x7F,0xB7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* ; 01 (640x350) */
979 {{ 0x41,0x7F,0xB7,0x34,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* ; 02 (720x400) */
980 {{ 0x41,0x7F,0xB7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* ; 03 (720x350) */
981 {{ 0x61,0x7F,0xB7,0x99,0x84,0x35,0x04,0x5A,0x05,0x00,0x80,0x26,0x2A,0x55,0x5D,0x00 }},/* ; 04 (640x480) */
982 {{ 0xC3,0x7F,0xB7,0x7A,0x84,0x40,0x02,0x5A,0x05,0x00,0x80,0x1F,0x84,0x3D,0x28,0x00 }},/* ; 05 (800x600) ;;1/12/02 */
983 {{ 0xE5,0x7F,0xB7,0x1D,0xA7,0x3E,0x04,0x5A,0x05,0x00,0x80,0x20,0x3E,0xE4,0x22,0x00 }}/* ; 06 (1024x768) ;;1/12/02 */
984 };
985
986XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[]={
987 /* Index:000,0x01,0x02,0x04,0x03,0x05,0x06,0x07,0x08,0x15,0x1F,0x0C,0x0D,0x0E,0x0F,0x10h */
988 {{ 0x41,0x7F,0xB7,0x36,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 00 (640x200,640x400) */
989 {{ 0x41,0x7F,0xB7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 01 (640x350) */
990 {{ 0x41,0x7F,0xB7,0x36,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 02 (720x400) */
991 {{ 0x41,0x7F,0xB7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 03 (720x350) */
992 {{ 0x61,0x7F,0xB7,0x99,0x84,0x35,0x04,0x5A,0x05,0x00,0x80,0x26,0x2A,0x55,0x5D,0x00 }},/* 04 (640x480) */
993 {{ 0xC1,0x7F,0xB7,0x4D,0x8C,0x1E,0x31,0x5A,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00 }},/* 05 (800x600) ;;1/12/02 */
994 {{ 0xE4,0x7F,0xB7,0x1E,0xAF,0x29,0x37,0x5A,0x05,0x00,0x80,0x25,0x8C,0xB2,0x2A,0x00 }}/* 06 (1024x768) ;;1/12/02 */
995 };
996
997UCHAR XGI_CH7017LV1024x768[]={0x60,0x02,0x00,0x07,0x40,0xED,0xA3,
998 0xC8,0xC7,0xAC,0xE0,0x02};
999UCHAR XGI_CH7017LV1400x1050[]={0x60,0x03,0x11,0x00,0x40,0xE3,0xAD,
1000 0xDB,0xF6,0xAC,0xE0,0x02};
1001
1002
1003/*add for new UNIVGABIOS*/
1004XGI330_LCDDataStruct XGI_StLCD1024x768Data[]=
1005{
1006 { 62, 25, 800, 546,1344, 806},
1007 { 32, 15, 930, 546,1344, 806},
1008 { 62, 25, 800, 546,1344, 806}, /* chiawen for dot9 -> dot8 */
1009 { 104, 45, 945, 496,1344, 806},
1010 { 62, 25, 800, 546,1344, 806},
1011 { 31, 18,1008, 624,1344, 806},
1012 { 1, 1,1344, 806,1344, 806}
1013};
1014
1015XGI330_LCDDataStruct XGI_ExtLCD1024x768Data[]=
1016{
1017 { 42, 25,1536, 419,1344, 806}, /* { 12, 5, 896, 512,1344, 806}, // alan 09/12/2003 */
1018 { 48, 25,1536, 369,1344, 806}, /* { 12, 5, 896, 510,1344, 806}, // alan 09/12/2003 */
1019 { 42, 25,1536, 419,1344, 806}, /* { 32, 15,1008, 505,1344, 806}, // alan 09/12/2003 */
1020 { 48, 25,1536, 369,1344, 806}, /* { 32, 15,1008, 514,1344, 806}, // alan 09/12/2003 */
1021 { 12, 5, 896, 500,1344, 806},
1022 { 42, 25,1024, 625,1344, 806},
1023 { 1, 1,1344, 806,1344, 806},
1024 { 12, 5, 896, 500,1344, 806},
1025 { 42, 25,1024, 625,1344, 806},
1026 { 1, 1,1344, 806,1344, 806},
1027 { 12, 5, 896, 500,1344, 806},
1028 { 42, 25,1024, 625,1344, 806},
1029 { 1, 1,1344, 806,1344, 806}
1030};
1031
1032/*XGI330_LCDDataStruct XGI_St2LCD1024x768Data[]=
1033{
1034 { 62, 25, 800, 546,1344, 806},
1035 { 32, 15, 930, 546,1344, 806},
1036 { 62, 25, 800, 546,1344, 806},
1037 { 104, 45, 945, 496,1344, 806},
1038 { 62, 25, 800, 546,1344, 806},
1039 { 31, 18,1008, 624,1344, 806},
1040 { 1, 1,1344, 806,1344, 806}
1041};*/
1042
1043XGI330_LCDDataStruct XGI_CetLCD1024x768Data[]=
1044{
1045 { 1,1,1344,806,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1046 { 1,1,1344,806,1344,806 }, /* 01 (320x350,640x350) */
1047 { 1,1,1344,806,1344,806 }, /* 02 (360x400,720x400) */
1048 { 1,1,1344,806,1344,806 }, /* 03 (720x350) */
1049 { 1,1,1344,806,1344,806 }, /* 04 (640x480x60Hz) */
1050 { 1,1,1344,806,1344,806 }, /* 05 (800x600x60Hz) */
1051 { 1,1,1344,806,1344,806 } /* 06 (1024x768x60Hz) */
1052};
1053
1054XGI330_LCDDataStruct XGI_StLCD1280x1024Data[]=
1055{
1056 { 22, 5, 800, 510,1650,1088},
1057 { 22, 5, 800, 510,1650,1088},
1058 { 176, 45, 900, 510,1650,1088},
1059 { 176, 45, 900, 510,1650,1088},
1060 { 22, 5, 800, 510,1650,1088},
1061 { 13, 5,1024, 675,1560,1152},
1062 { 16, 9,1266, 804,1688,1072},
1063 { 1, 1,1688,1066,1688,1066}
1064};
1065
1066XGI330_LCDDataStruct XGI_ExtLCD1280x1024Data[]=
1067{
1068 { 211, 60,1024, 501,1688,1066},
1069 { 211, 60,1024, 508,1688,1066},
1070 { 211, 60,1024, 501,1688,1066},
1071 { 211, 60,1024, 508,1688,1066},
1072 { 211, 60,1024, 500,1688,1066},
1073 { 211, 75,1024, 625,1688,1066},
1074 { 211, 120,1280, 798,1688,1066},
1075 { 1, 1,1688,1066,1688,1066}
1076};
1077
1078XGI330_LCDDataStruct XGI_St2LCD1280x1024Data[]=
1079{
1080 { 22, 5, 800, 510,1650,1088},
1081 { 22, 5, 800, 510,1650,1088},
1082 { 176, 45, 900, 510,1650,1088},
1083 { 176, 45, 900, 510,1650,1088},
1084 { 22, 5, 800, 510,1650,1088},
1085 { 13, 5,1024, 675,1560,1152},
1086 { 16, 9,1266, 804,1688,1072},
1087 { 1, 1,1688,1066,1688,1066}
1088};
1089
1090XGI330_LCDDataStruct XGI_CetLCD1280x1024Data[]=
1091{
1092 { 1,1,1688,1066,1688,1066 }, /* 00 (320x200,320x400,640x200,640x400) */
1093 { 1,1,1688,1066,1688,1066 }, /* 01 (320x350,640x350) */
1094 { 1,1,1688,1066,1688,1066 }, /* 02 (360x400,720x400) */
1095 { 1,1,1688,1066,1688,1066 }, /* 03 (720x350) */
1096 { 1,1,1688,1066,1688,1066 }, /* 04 (640x480x60Hz) */
1097 { 1,1,1688,1066,1688,1066 }, /* 05 (800x600x60Hz) */
1098 { 1,1,1688,1066,1688,1066 }, /* 06 (1024x768x60Hz) */
1099 { 1,1,1688,1066,1688,1066 }, /* 07 (1280x1024x60Hz) */
1100 { 1,1,1688,1066,1688,1066 } /* 08 (1400x1050x60Hz) */
1101};
1102
1103XGI330_LCDDataStruct XGI_StLCD1400x1050Data[]=
1104{
1105 { 211,100,2100,408,1688,1066 }, /* 00 (320x200,320x400,640x200,640x400) */
1106 { 211,64,1536,358,1688,1066 }, /* 01 (320x350,640x350) */
1107 { 211,100,2100,408,1688,1066 }, /* 02 (360x400,720x400) */
1108 { 211,64,1536,358,1688,1066 }, /* 03 (720x350) */
1109 { 211,48,840,488,1688,1066 }, /* 04 (640x480x60Hz) */
1110 { 211,72,1008,609,1688,1066 }, /* 05 (800x600x60Hz) */
1111 { 211,128,1400,776,1688,1066 }, /* 06 (1024x768x60Hz) */
1112 { 1,1,1688,1066,1688,1066 }, /* 07 (1280x1024x60Hz w/o Scaling) */
1113 { 1,1,1688,1066,1688,1066 } /* 08 (1400x1050x60Hz) */
1114};
1115
1116XGI330_LCDDataStruct XGI_ExtLCD1400x1050Data[]=
1117{
1118 { 211,100,2100,408,1688,1066 }, /* 00 (320x200,320x400,640x200,640x400) */
1119 { 211,64,1536,358,1688,1066 }, /* 01 (320x350,640x350) */
1120 { 211,100,2100,408,1688,1066 }, /* 02 (360x400,720x400) */
1121 { 211,64,1536,358,1688,1066 }, /* 03 (720x350) */
1122 { 211,48,840,488,1688,1066 }, /* 04 (640x480x60Hz) */
1123 { 211,72,1008,609,1688,1066 }, /* 05 (800x600x60Hz) */
1124 { 211,128,1400,776,1688,1066 }, /* 06 (1024x768x60Hz) */
1125 { 1,1,1688,1066,1688,1066 }, /* 07 (1280x1024x60Hz w/o Scaling) */
1126 { 1,1,1688,1066,1688,1066 } /* 08 (1400x1050x60Hz) */
1127};
1128
1129XGI330_LCDDataStruct XGI_ExtLCD1600x1200Data[]=
1130{
1131 { 4,1,1620,420,2160,1250 }, /* { 3,1,2160,425,2160,1250 }, // 00 (320x200,320x400,640x200,640x400) // alan 10/14/2003 */
1132 { 27,7,1920,375,2160,1250 }, /* 01 (320x350,640x350) */
1133 { 4,1,1620,420,2160,1250 }, /* { 3,1,2160,425,2160,1250 }, // 02 (360x400,720x400) // alan 10/14/2003 */
1134 { 27,7,1920,375,2160,1250 }, /* 03 (720x350) */
1135 { 27,4,800,500,2160,1250 }, /* 04 (640x480x60Hz) */
1136 { 4,1,1080,625,2160,1250 }, /* 05 (800x600x60Hz) */
1137 { 5,2,1350,800,2160,1250 }, /* 06 (1024x768x60Hz) */
1138 { 27,16,1500,1064,2160,1250 }, /* 07 (1280x1024x60Hz) */
1139 { 9,7,1920,1106,2160,1250 }, /* 08 (1400x1050x60Hz) */
1140 { 1,1,2160,1250,2160,1250 } /* 09 (1600x1200x60Hz) ;302lv */
1141};
1142
1143XGI330_LCDDataStruct XGI_StLCD1600x1200Data[]=
1144{
1145 { 27,4,800,500,2160,1250 },/* 00 (320x200,320x400,640x200,640x400) */
1146 { 27,4,800,500,2160,1250 },/* 01 (320x350,640x350) */
1147 { 27,4,800,500,2160,1250 },/* 02 (360x400,720x400) */
1148 { 27,4,800,500,2160,1250 },/* 03 (720x350) */
1149 { 27,4,800,500,2160,1250 },/* 04 (320x240,640x480) */
1150 { 4,1,1080,625,2160,1250 },/* 05 (400x300,800x600) */
1151 { 5,2,1350,800,2160,1250 },/* 06 (512x384,1024x768) */
1152 { 135,88,1600,1100,2160,1250 },/* 07 (1280x1024) */
1153 { 1,1,1800,1500,2160,1250 },/* 08 (1400x1050) */
1154 { 1,1,2160,1250,2160,1250 } /* 09 (1600x1200) */
1155};
1156
1157XGI330_LCDDataStruct XGI_CetLCD1400x1050Data[]=
1158{
1159 { 1,1,1688,1066,1688,1066 }, /* 00 (320x200,320x400,640x200,640x400) */
1160 { 1,1,1688,1066,1688,1066 }, /* 01 (320x350,640x350) */
1161 { 1,1,1688,1066,1688,1066 }, /* 02 (360x400,720x400) */
1162 { 1,1,1688,1066,1688,1066 }, /* 03 (720x350) */
1163 { 1,1,1688,1066,1688,1066 }, /* 04 (640x480x60Hz) */
1164 { 1,1,1688,1066,1688,1066 }, /* 05 (800x600x60Hz) */
1165 { 1,1,1688,1066,1688,1066 }, /* 06 (1024x768x60Hz) */
1166 { 1,1,1688,1066,1688,1066 }, /* 07 (1280x1024x60Hz) */
1167 { 1,1,1688,1066,1688,1066 } /* 08 (1400x1050x60Hz) */
1168};
1169
1170XGI330_LCDDataStruct XGI_NoScalingData[]=
1171{
1172 { 1, 1, 800, 449, 800, 449},
1173 { 1, 1, 800, 449, 800, 449},
1174 { 1, 1, 900, 449, 900, 449},
1175 { 1, 1, 900, 449, 900, 449},
1176 { 1, 1, 800, 525, 800, 525},
1177 { 1, 1,1056, 628,1056, 628},
1178 { 1, 1,1344, 806,1344, 806},
1179 { 1, 1,1688,1066,1688,1066}
1180};
1181
1182XGI330_LCDDataStruct XGI_ExtLCD1024x768x75Data[]=
1183{
1184 {42,25,1536,419,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1185 {48,25,1536,369,1344,806 }, /* ; 01 (320x350,640x350) */
1186 {42,25,1536,419,1344,806 }, /* ; 02 (360x400,720x400) */
1187 {48,25,1536,369,1344,806 }, /* ; 03 (720x350) */
1188 {8,5,1312,500,1312,800 }, /* ; 04 (640x480x75Hz) */
1189 {41,25,1024,625,1312,800 }, /* ; 05 (800x600x75Hz) */
1190 {1,1,1312,800,1312,800 } /* ; 06 (1024x768x75Hz) */
1191};
1192
1193XGI330_LCDDataStruct XGI_StLCD1024x768x75Data[]=
1194{
1195 {42,25,1536,419,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1196 {48,25,1536,369,1344,806 }, /* ; 01 (320x350,640x350) */
1197 {42,25,1536,419,1344,806 }, /* ; 02 (360x400,720x400) */
1198 {48,25,1536,369,1344,806 }, /* ; 03 (720x350) */
1199 {8,5,1312,500,1312,800 }, /* ; 04 (640x480x75Hz) */
1200 {41,25,1024,625,1312,800 }, /* ; 05 (800x600x75Hz) */
1201 {1,1,1312,800,1312,800 } /* ; 06 (1024x768x75Hz) */
1202};
1203
1204XGI330_LCDDataStruct XGI_CetLCD1024x768x75Data[]=
1205{
1206 {1,1,1312,800,1312,800}, /* ; 00 (320x200,320x400,640x200,640x400) */
1207 {1,1,1312,800,1312,800}, /* ; 01 (320x350,640x350) */
1208 {1,1,1312,800,1312,800}, /* ; 02 (360x400,720x400) */
1209 {1,1,1312,800,1312,800}, /* ; 03 (720x350) */
1210 {1,1,1312,800,1312,800}, /* ; 04 (640x480x75Hz) */
1211 {1,1,1312,800,1312,800}, /* ; 05 (800x600x75Hz) */
1212 {1,1,1312,800,1312,800} /* ; 06 (1024x768x75Hz) */
1213};
1214
1215XGI330_LCDDataStruct XGI_ExtLCD1280x1024x75Data[]=
1216{
1217 {211,60,1024,501,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1218 {211,60,1024,508,1688,1066 }, /* ; 01 (320x350,640x350) */
1219 {211,60,1024,501,1688,1066 }, /* ; 02 (360x400,720x400) */
1220 {211,60,1024,508,1688,1066 }, /* ; 03 (720x350) */
1221 {211,45,768,498,1688,1066 }, /* ; 04 (640x480x75Hz) */
1222 {211,75,1024,625,1688,1066 }, /* ; 05 (800x600x75Hz) */
1223 {211,120,1280,798,1688,1066 }, /* ; 06 (1024x768x75Hz) */
1224 {1,1,1688,1066,1688,1066 } /* ; 07 (1280x1024x75Hz) */
1225};
1226
1227XGI330_LCDDataStruct XGI_StLCD1280x1024x75Data[]=
1228{
1229 {211,60,1024,501,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1230 {211,60,1024,508,1688,1066 }, /* ; 01 (320x350,640x350) */
1231 {211,60,1024,501,1688,1066 }, /* ; 02 (360x400,720x400) */
1232 {211,60,1024,508,1688,1066 }, /* ; 03 (720x350) */
1233 {211,45,768,498,1688,1066 }, /* ; 04 (640x480x75Hz) */
1234 {211,75,1024,625,1688,1066 }, /* ; 05 (800x600x75Hz) */
1235 {211,120,1280,798,1688,1066}, /* ; 06 (1024x768x75Hz) */
1236 {1,1,1688,1066,1688,1066 } /* ; 07 (1280x1024x75Hz) */
1237};
1238
1239XGI330_LCDDataStruct XGI_CetLCD1280x1024x75Data[]=
1240{
1241 {1,1,1688,1066,1688,1066}, /* ; 00 (320x200,320x400,640x200,640x400) */
1242 {1,1,1688,1066,1688,1066}, /* ; 01 (320x350,640x350) */
1243 {1,1,1688,1066,1688,1066}, /* ; 02 (360x400,720x400) */
1244 {1,1,1688,1066,1688,1066}, /* ; 03 (720x350) */
1245 {1,1,1688,1066,1688,1066}, /* ; 04 (640x480x75Hz) */
1246 {1,1,1688,1066,1688,1066}, /* ; 05 (800x600x75Hz) */
1247 {1,1,1688,1066,1688,1066}, /* ; 06 (1024x768x75Hz) */
1248 {1,1,1688,1066,1688,1066} /* ; 07 (1280x1024x75Hz) */
1249};
1250
1251XGI330_LCDDataStruct XGI_NoScalingDatax75[]=
1252{
1253 {1,1,800,449,800,449 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1254 {1,1,800,449,800,449 }, /* ; 01 (320x350,640x350) */
1255 {1,1,900,449,900,449 }, /* ; 02 (360x400,720x400) */
1256 {1,1,900,449,900,449 }, /* ; 03 (720x350) */
1257 {1,1,840,500,840,500 }, /* ; 04 (640x480x75Hz) */
1258 {1,1,1056,625,1056,625 }, /* ; 05 (800x600x75Hz) */
1259 {1,1,1312,800,1312,800 }, /* ; 06 (1024x768x75Hz) */
1260 {1,1,1688,1066,1688,1066}, /* ; 07 (1280x1024x75Hz) */
1261 {1,1,1688,1066,1688,1066}, /* ; 08 (1400x1050x75Hz) ;;[ycchen] 12/19/02 */
1262 {1,1,2160,1250,2160,1250}, /* ; 09 (1600x1200x75Hz) */
1263 {1,1,1688,806,1688,806 } /* ; 0A (1280x768x75Hz) */
1264};
1265
1266XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768Data[]=
1267{
1268 { 9,1057,0, 771 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1269 { 9,1057,0, 771 }, /* ; 01 (320x350,640x350) */
1270 { 9,1057,0, 771 }, /* ; 02 (360x400,720x400) */
1271 { 9,1057,0, 771 }, /* ; 03 (720x350) */
1272 { 9,1057,0, 771 }, /* ; 04 (640x480x60Hz) */
1273 { 9,1057,0, 771 }, /* ; 05 (800x600x60Hz) */
1274 { 9,1057,805, 770 } /* ; 06 (1024x768x60Hz) */
1275};
1276
1277XGI330_LCDDataDesStruct XGI_StLCDDes1024x768Data[]=
1278{
1279 { 9,1057,737,703 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1280 { 9,1057,686,651 }, /* ; 01 (320x350,640x350) */
1281 { 9,1057,737,703 }, /* ; 02 (360x400,720x400) */
1282 { 9,1057,686,651 }, /* ; 03 (720x350) */
1283 { 9,1057,776,741 }, /* ; 04 (640x480x60Hz) */
1284 { 9,1057, 0 ,771 }, /* ; 05 (800x600x60Hz) */
1285 { 9,1057,805,770 } /* ; 06 (1024x768x60Hz) */
1286};
1287
1288XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768Data[]=
1289{
1290 { 1152,856,622,587 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1291 { 1152,856,597,562 }, /* ; 01 (320x350,640x350) */
1292 { 1152,856,622,587 }, /* ; 02 (360x400,720x400) */
1293 { 1152,856,597,562 }, /* ; 03 (720x350) */
1294 { 1152,856,662,627 }, /* ; 04 (640x480x60Hz) */
1295 { 1232,936,722,687 }, /* ; 05 (800x600x60Hz) */
1296 { 0,1048,805,770 } /* ; 06 (1024x768x60Hz) */
1297};
1298
1299XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[]=
1300{
1301 { 18,1346,981,940 },/* 00 (320x200,320x400,640x200,640x400) */
1302 { 18,1346,926,865 },/* 01 (320x350,640x350) */
1303 { 18,1346,981,940 },/* 02 (360x400,720x400) */
1304 { 18,1346,926,865 },/* 03 (720x350) */
1305 { 18,1346,0,1025 },/* 04 (640x480x60Hz) */
1306 { 18,1346,0,1025 },/* 05 (800x600x60Hz) */
1307 { 18,1346,1065,1024 },/* 06 (1024x768x60Hz) */
1308 { 18,1346,1065,1024 }/* 07 (1280x1024x60Hz) */
1309};
1310
1311XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[]=
1312{
1313 { 18,1346,970,907 },/* 00 (320x200,320x400,640x200,640x400) */
1314 { 18,1346,917,854 },/* 01 (320x350,640x350) */
1315 { 18,1346,970,907 },/* 02 (360x400,720x400) */
1316 { 18,1346,917,854 },/* 03 (720x350) */
1317 { 18,1346,0,1025 },/* 04 (640x480x60Hz) */
1318 { 18,1346,0,1025 },/* 05 (800x600x60Hz) */
1319 { 18,1346,1065,1024 },/* 06 (1024x768x60Hz) */
1320 { 18,1346,1065,1024 }/* 07 (1280x1024x60Hz) */
1321};
1322
1323XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024Data[]=
1324{
1325 { 1368,1008,752,711 }, /* 00 (320x200,320x400,640x200,640x400) */
1326 { 1368,1008,729,688 }, /* 01 (320x350,640x350) */
1327 { 1368,1008,752,711 }, /* 02 (360x400,720x400) */
1328 { 1368,1008,729,688 }, /* 03 (720x350) */
1329 { 1368,1008,794,753 }, /* 04 (640x480x60Hz) */
1330 { 1448,1068,854,813 }, /* 05 (800x600x60Hz) */
1331 { 1560,1200,938,897 }, /* 06 (1024x768x60Hz) */
1332 { 18,1346,1065,1024 } /* 07 (1280x1024x60Hz) */
1333};
1334
1335XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024Data[]=
1336{
1337 { 9,1337,981,940 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1338 { 9,1337,926,884 }, /* ; 01 (320x350,640x350) alan, 2003/09/30 */
1339 { 9,1337,981,940 }, /* ; 02 (360x400,720x400) */
1340 { 9,1337,926,884 }, /* ; 03 (720x350) alan, 2003/09/30 */
1341 { 9,1337,0,1025 }, /* ; 04 (640x480x60Hz) */
1342 { 9,1337,0,1025 }, /* ; 05 (800x600x60Hz) */
1343 { 9,1337,1065,1024 }, /* ; 06 (1024x768x60Hz) */
1344 { 9,1337,1065,1024 } /* ; 07 (1280x1024x60Hz) */
1345};
1346
1347XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024Data[]=
1348{
1349 { 9,1337,970,907 }, /* ; 00 (320x200,320x400,640x200,640x400) */
1350 { 9,1337,917,854 }, /* ; 01 (320x350,640x350) */
1351 { 9,1337,970,907 }, /* ; 02 (360x400,720x400) */
1352 { 9,1337,917,854 }, /* ; 03 (720x350) */
1353 { 9,1337,0,1025 }, /* ; 04 (640x480x60Hz) */
1354 { 9,1337,0,1025 }, /* ; 05 (800x600x60Hz) */
1355 { 9,1337,1065,1024 }, /* ; 06 (1024x768x60Hz) */
1356 { 9,1337,1065,1024 } /* ; 07 (1280x1024x60Hz) */
1357};
1358
1359XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024Data[]=
1360{
1361 { 1368,1008,752,711 }, /* 00 (320x200,320x400,640x200,640x400) */
1362 { 1368,1008,729,688 }, /* 01 (320x350,640x350) */
1363 { 1368,1008,752,711 }, /* 02 (360x400,720x400) */
1364 { 1368,1008,729,688 }, /* 03 (720x350) */
1365 { 1368,1008,794,753 }, /* 04 (640x480x60Hz) */
1366 { 1448,1068,854,813 }, /* 05 (800x600x60Hz) */
1367 { 1560,1200,938,897 }, /* 06 (1024x768x60Hz) */
1368 { 9,1337,1065,1024 } /* 07 (1280x1024x60Hz) */
1369};
1370
1371XGI330_LCDDataDesStruct XGI_StLCDDLDes1400x1050Data[]=
1372{
1373 { 18,1464,0,1051 }, /* 00 (320x200,320x400,640x200,640x400) */
1374 { 18,1464,0,1051 }, /* 01 (320x350,640x350) */
1375 { 18,1464,0,1051 }, /* 02 (360x400,720x400) */
1376 { 18,1464,0,1051 }, /* 03 (720x350) */
1377 { 18,1464,0,1051 }, /* 04 (640x480x60Hz) */
1378 { 18,1464,0,1051 }, /* 05 (800x600x60Hz) */
1379 { 18,1464,0,1051 }, /* 06 (1024x768x60Hz) */
1380 { 1646,1406,1053,1038 }, /* 07 (1280x1024x60Hz) */
1381 { 18,1464,0,1051 } /* 08 (1400x1050x60Hz) */
1382};
1383
1384XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1400x1050Data[]=
1385{
1386 { 18,1464,0,1051 }, /* 00 (320x200,320x400,640x200,640x400) */
1387 { 18,1464,0,1051 }, /* 01 (320x350,640x350) */
1388 { 18,1464,0,1051 }, /* 02 (360x400,720x400) */
1389 { 18,1464,0,1051 }, /* 03 (720x350) */
1390 { 18,1464,0,1051 }, /* 04 (640x480x60Hz) */
1391 { 18,1464,0,1051 }, /* 05 (800x600x60Hz) */
1392 { 18,1464,0,1051 }, /* 06 (1024x768x60Hz) */
1393 { 1646,1406,1053,1038 }, /* 07 (1280x1024x60Hz) */
1394 { 18,1464,0,1051 } /* 08 (1400x1050x60Hz) */
1395};
1396
1397XGI330_LCDDataDesStruct XGI_StLCDDes1400x1050Data[]=
1398{
1399 { 9,1455,0,1051 },/* 00 (320x200,320x400,640x200,640x400) */
1400 { 9,1455,0,1051 },/* 01 (320x350,640x350) */
1401 { 9,1455,0,1051 },/* 02 (360x400,720x400) */
1402 { 9,1455,0,1051 },/* 03 (720x350) */
1403 { 9,1455,0,1051 },/* 04 (640x480x60Hz) */
1404 { 9,1455,0,1051 },/* 05 (800x600x60Hz) */
1405 { 9,1455,0,1051 },/* 06 (1024x768x60Hz) */
1406 { 1637,1397,1053,1038 },/* 07 (1280x1024x60Hz) */
1407 { 9,1455,0,1051 } /* 08 (1400x1050x60Hz) */
1408};
1409
1410XGI330_LCDDataDesStruct XGI_ExtLCDDes1400x1050Data[]=
1411{
1412 { 9,1455,0,1051 },/* 00 (320x200,320x400,640x200,640x400) */
1413 { 9,1455,0,1051 },/* 01 (320x350,640x350) */
1414 { 9,1455,0,1051 },/* 02 (360x400,720x400) */
1415 { 9,1455,0,1051 },/* 03 (720x350) */
1416 { 9,1455,0,1051 },/* 04 (640x480x60Hz) */
1417 { 9,1455,0,1051 },/* 05 (800x600x60Hz) */
1418 { 9,1455,0,1051 },/* 06 (1024x768x60Hz) */
1419 { 1637,1397,1053,1038 },/* 07 (1280x1024x60Hz) */
1420 { 9,1455,0,1051 } /* 08 (1400x1050x60Hz) */
1421};
1422
1423XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data[]=
1424{
1425 { 1308,1068,781,766 }, /* 00 (320x200,320x400,640x200,640x400) */
1426 { 1308,1068,781,766 }, /* 01 (320x350,640x350) */
1427 { 1308,1068,781,766 }, /* 02 (360x400,720x400) */
1428 { 1308,1068,781,766 }, /* 03 (720x350) */
1429 { 1308,1068,781,766 }, /* 04 (640x480x60Hz) */
1430 { 1388,1148,841,826 }, /* 05 (800x600x60Hz) */
1431 { 1490,1250,925,910 }, /* 06 (1024x768x60Hz) */
1432 { 1646,1406,1053,1038 }, /* 07 (1280x1024x60Hz) */
1433 { 18,1464,0,1051 } /* 08 (1400x1050x60Hz) */
1434};
1435
1436XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data2[]=
1437{
1438 { 0,1448,0,1051 }, /* 00 (320x200,320x400,640x200,640x400) */
1439 { 0,1448,0,1051 }, /* 01 (320x350,640x350) */
1440 { 0,1448,0,1051 }, /* 02 (360x400,720x400) */
1441 { 0,1448,0,1051 }, /* 03 (720x350) */
1442 { 0,1448,0,1051 } /* 04 (640x480x60Hz) */
1443};
1444
1445
1446
1447XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1600x1200Data[]=
1448{
1449 { 18,1682,0,1201 }, /* 00 (320x200,320x400,640x200,640x400) */
1450 { 18,1682,0,1201 }, /* 01 (320x350,640x350) */
1451 { 18,1682,0,1201 }, /* 02 (360x400,720x400) */
1452 { 18,1682,0,1201 }, /* 03 (720x350) */
1453 { 18,1682,0,1201 }, /* 04 (640x480x60Hz) */
1454 { 18,1682,0,1201 }, /* 05 (800x600x60Hz) */
1455 { 18,1682,0,1201 }, /* 06 (1024x768x60Hz) */
1456 { 18,1682,0,1201 }, /* 07 (1280x1024x60Hz) */
1457 { 18,1682,0,1201 }, /* 08 (1400x1050x60Hz) */
1458 { 18,1682,0,1201 } /* 09 (1600x1200x60Hz) */
1459};
1460
1461XGI330_LCDDataDesStruct XGI_StLCDDLDes1600x1200Data[]=
1462{
1463 { 18,1682,1150,1101 }, /* 00 (320x200,320x400,640x200,640x400) */
1464 { 18,1682,1083,1034 }, /* 01 (320x350,640x350) */
1465 { 18,1682,1150,1101 }, /* 02 (360x400,720x400) */
1466 { 18,1682,1083,1034 }, /* 03 (720x350) */
1467 { 18,1682,0,1201 }, /* 04 (640x480x60Hz) */
1468 { 18,1682,0,1201 }, /* 05 (800x600x60Hz) */
1469 { 18,1682,0,1201 }, /* 06 (1024x768x60Hz) */
1470 { 18,1682,1232,1183 }, /* 07 (1280x1024x60Hz) */
1471 { 18,1682,0,1201 }, /* 08 (1400x1050x60Hz) */
1472 { 18,1682,0,1201 } /* 09 (1600x1200x60Hz) */
1473};
1474
1475XGI330_LCDDataDesStruct XGI_ExtLCDDes1600x1200Data[]=
1476{
1477 { 9,1673,0,1201 },/* 00 (320x200,320x400,640x200,640x400) */
1478 { 9,1673,0,1201 },/* 01 (320x350,640x350) */
1479 { 9,1673,0,1201 },/* 02 (360x400,720x400) */
1480 { 9,1673,0,1201 },/* 03 (720x350) */
1481 { 9,1673,0,1201 },/* 04 (640x480x60Hz) */
1482 { 9,1673,0,1201 },/* 05 (800x600x60Hz) */
1483 { 9,1673,0,1201 },/* 06 (1024x768x60Hz) */
1484 { 9,1673,0,1201 },/* 07 (1280x1024x60Hz) */
1485 { 9,1673,0,1201 },/* 08 (1400x1050x60Hz) */
1486 { 9,1673,0,1201 } /* 09 (1600x1200x60Hz) */
1487};
1488
1489XGI330_LCDDataDesStruct XGI_StLCDDes1600x1200Data[]=
1490{
1491 { 9,1673,1150,1101 },/* 00 (320x200,320x400,640x200,640x400) */
1492 { 9,1673,1083,1034 },/* 01 (320x350,640x350) */
1493 { 9,1673,1150,1101 },/* 02 (360x400,720x400) */
1494 { 9,1673,1083,1034 },/* 03 (720x350) */
1495 { 9,1673,0,1201 },/* 04 (640x480x60Hz) */
1496 { 9,1673,0,1201 },/* 05 (800x600x60Hz) */
1497 { 9,1673,0,1201 },/* 06 (1024x768x60Hz) */
1498 { 9,1673,1232,1183 },/* 07 (1280x1024x60Hz) */
1499 { 9,1673,0,1201 },/* 08 (1400x1050x60Hz) */
1500 { 9,1673,0,1201 } /* 09 (1600x1200x60Hz) */
1501};
1502
1503XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[]=
1504{
1505 { 9,657,448,405,96,2 }, /* 00 (320x200,320x400,640x200,640x400) */
1506 { 9,657,448,355,96,2 }, /* 01 (320x350,640x350) */
1507 { 9,657,448,405,96,2 }, /* 02 (360x400,720x400) */
1508 { 9,657,448,355,96,2 }, /* 03 (720x350) */
1509 { 9,657,1,483,96,2 }, /* 04 (640x480x60Hz) */
1510 { 9,849,627,600,128,4 }, /* 05 (800x600x60Hz) */
1511 { 9,1057,805,770,0136,6 }, /* 06 (1024x768x60Hz) */
1512 { 9,1337,0,1025,112,3 }, /* 07 (1280x1024x60Hz) */
1513 { 9,1457,0,1051,112,3 }, /* 08 (1400x1050x60Hz) }, //;[ycchen] 12/19/02 */
1514 { 9,1673,0,1201,192,3 }, /* 09 (1600x1200x60Hz) */
1515 { 9,1337,0,771,112,6 } /* 0A (1280x768x60Hz) */
1516};
1517
1518XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768x75Data[]= /* ;;1024x768x75Hz */
1519{
1520 {9,1049,0,769}, /* ; 00 (320x200,320x400,640x200,640x400) */
1521 {9,1049,0,769}, /* ; 01 (320x350,640x350) */
1522 {9,1049,0,769}, /* ; 02 (360x400,720x400) */
1523 {9,1049,0,769}, /* ; 03 (720x350) */
1524 {9,1049,0,769}, /* ; 04 (640x480x75Hz) */
1525 {9,1049,0,769}, /* ; 05 (800x600x75Hz) */
1526 {9,1049,0,769} /* ; 06 (1024x768x75Hz) */
1527};
1528
1529XGI330_LCDDataDesStruct XGI_StLCDDes1024x768x75Data[]=
1530{
1531 {9,1049,0,769}, /* ; 00 (320x200,320x400,640x200,640x400) */
1532 {9,1049,0,769}, /* ; 01 (320x350,640x350) */
1533 {9,1049,0,769}, /* ; 02 (360x400,720x400) */
1534 {9,1049,0,769}, /* ; 03 (720x350) */
1535 {9,1049,0,769}, /* ; 04 (640x480x75Hz) */
1536 {9,1049,0,769}, /* ; 05 (800x600x75Hz) */
1537 {9,1049,0,769} /* ; 06 (1024x768x75Hz) */
1538};
1539
1540XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768x75Data[]= /* ;;1024x768x75Hz */
1541{
1542 {1152,856,622,587}, /* ; 00 (320x200,320x400,640x200,640x400) */
1543 {1152,856,597,562}, /* ; 01 (320x350,640x350) */
1544 {1192,896,622,587}, /* ; 02 (360x400,720x400) */
1545 {1192,896,597,562}, /* ; 03 (720x350) */
1546 {1129,857,656,625}, /* ; 04 (640x480x75Hz) */
1547 {1209,937,716,685}, /* ; 05 (800x600x75Hz) */
1548 {9,1049,0,769} /* ; 06 (1024x768x75Hz) */
1549};
1550
1551XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024x75Data[]= /* ;;1280x1024x75Hz */
1552{
1553 {18,1314,0,1025 },/* ; 00 (320x200,320x400,640x200,640x400) */
1554 {18,1314,0,1025 },/* ; 01 (320x350,640x350) */
1555 {18,1314,0,1025 },/* ; 02 (360x400,720x400) */
1556 {18,1314,0,1025 },/* ; 03 (720x350) */
1557 {18,1314,0,1025 },/* ; 04 (640x480x60Hz) */
1558 {18,1314,0,1025 },/* ; 05 (800x600x60Hz) */
1559 {18,1314,0,1025 },/* ; 06 (1024x768x60Hz) */
1560 {18,1314,0,1025 }/* ; 07 (1280x1024x60Hz) */
1561};
1562
1563XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024x75Data[]=
1564{
1565 {18,1314,0,1025 },/* ; 00 (320x200,320x400,640x200,640x400) */
1566 {18,1314,0,1025 },/* ; 01 (320x350,640x350) */
1567 {18,1314,0,1025 },/* ; 02 (360x400,720x400) */
1568 {18,1314,0,1025 },/* ; 03 (720x350) */
1569 {18,1314,0,1025 },/* ; 04 (640x480x60Hz) */
1570 {18,1314,0,1025 },/* ; 05 (800x600x60Hz) */
1571 {18,1314,0,1025 },/* ; 06 (1024x768x60Hz) */
1572 {18,1314,0,1025 }/* ; 07 (1280x1024x60Hz) */
1573};
1574
1575XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024x75Data[]= /* 1280x1024x75Hz */
1576{
1577 {1368,1008,752,711}, /* ; 00 (320x200,320x400,640x200,640x400) */
1578 {1368,1008,729,688}, /* ; 01 (320x350,640x350) */
1579 {1408,1048,752,711}, /* ; 02 (360x400,720x400) */
1580 {1408,1048,729,688}, /* ; 03 (720x350) */
1581 {1377,985,794,753}, /* ; 04 (640x480x75Hz) */
1582 {1457,1065,854,813}, /* ; 05 (800x600x75Hz) */
1583 {1569,1177,938,897}, /* ; 06 (1024x768x75Hz) */
1584 {18,1314,0,1025} /* ; 07 (1280x1024x75Hz) */
1585};
1586
1587XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024x75Data[]= /* ;;1280x1024x75Hz */
1588{
1589 {9,1305,0,1025},/* ; 00 (320x200,320x400,640x200,640x400) */
1590 {9,1305,0,1025},/* ; 01 (320x350,640x350) */
1591 {9,1305,0,1025},/* ; 02 (360x400,720x400) */
1592 {9,1305,0,1025},/* ; 03 (720x350) */
1593 {9,1305,0,1025},/* ; 04 (640x480x60Hz) */
1594 {9,1305,0,1025},/* ; 05 (800x600x60Hz) */
1595 {9,1305,0,1025},/* ; 06 (1024x768x60Hz) */
1596 {9,1305,0,1025} /* ; 07 (1280x1024x60Hz) */
1597};
1598
1599XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024x75Data[]=
1600{
1601 {9,1305,0,1025},/* ; 00 (320x200,320x400,640x200,640x400) */
1602 {9,1305,0,1025},/* ; 01 (320x350,640x350) */
1603 {9,1305,0,1025},/* ; 02 (360x400,720x400) */
1604 {9,1305,0,1025},/* ; 03 (720x350) */
1605 {9,1305,0,1025},/* ; 04 (640x480x60Hz) */
1606 {9,1305,0,1025},/* ; 05 (800x600x60Hz) */
1607 {9,1305,0,1025},/* ; 06 (1024x768x60Hz) */
1608 {9,1305,0,1025} /* ; 07 (1280x1024x60Hz) */
1609};
1610
1611XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024x75Data[]= /* 1280x1024x75Hz */
1612{
1613 {1368,1008,752,711}, /* ; 00 (320x200,320x400,640x200,640x400) */
1614 {1368,1008,729,688}, /* ; 01 (320x350,640x350) */
1615 {1408,1048,752,711}, /* ; 02 (360x400,720x400) */
1616 {1408,1048,729,688}, /* ; 03 (720x350) */
1617 {1377,985,794,753}, /* ; 04 (640x480x75Hz) */
1618 {1457,1065,854,813}, /* ; 05 (800x600x75Hz) */
1619 {1569,1177,938,897}, /* ; 06 (1024x768x75Hz) */
1620 {9,1305,0,1025} /* ; 07 (1280x1024x75Hz) */
1621};
1622
1623XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[]= /* Scaling LCD 75Hz */
1624{
1625 {9,657,448,405,96,2}, /* ; 00 (320x200,320x400,640x200,640x400) */
1626 {9,657,448,355,96,2}, /* ; 01 (320x350,640x350) */
1627 {9,738,448,405,108,2}, /* ; 02 (360x400,720x400) */
1628 {9,738,448,355,108,2}, /* ; 03 (720x350) */
1629 {9,665,0,481,64,3}, /* ; 04 (640x480x75Hz) */
1630 {9,825,0,601,80,3}, /* ; 05 (800x600x75Hz) */
1631 {9,1049,0,769,96,3}, /* ; 06 (1024x768x75Hz) */
1632 {9,1305,0,1025,144,3}, /* ; 07 (1280x1024x75Hz) */
1633 {9,1457,0,1051,112,3}, /* ; 08 (1400x1050x60Hz) ;;[ycchen] 12/19/02 */
1634 {9,1673,0,1201,192,3}, /* ; 09 (1600x1200x75Hz) */
1635 {9,1337,0,771,112,6} /* ; 0A (1280x768x60Hz) */
1636};
1637
1638XGI330_TVDataStruct XGI_StPALData[]=
1639{
1640 { 1, 1, 864, 525,1270, 400, 100, 0, 760},
1641 { 1, 1, 864, 525,1270, 350, 100, 0, 760},
1642 { 1, 1, 864, 525,1270, 400, 0, 0, 720},
1643 { 1, 1, 864, 525,1270, 350, 0, 0, 720},
1644 { 1, 1, 864, 525,1270, 480, 50, 0, 760},
1645 { 1, 1, 864, 525,1270, 600, 50, 0, 0}
1646};
1647
1648XGI330_TVDataStruct XGI_ExtPALData[]=
1649{
1650 { 2, 1,1080, 463,1270, 500, 50, 0, 50},
1651 { 15, 7,1152, 413,1270, 500, 50, 0, 50},
1652 { 2, 1,1080, 463,1270, 500, 50, 0, 50},
1653 { 15, 7,1152, 413,1270, 500, 50, 0, 50},
1654 { 2, 1, 900, 543,1270, 500, 0, 0, 50},
1655 { 4, 3,1080, 663,1270, 500, 438, 0, 438},
1656 { 1, 1,1125, 831,1270, 500, 686, 0, 686}, /*301b*/
1657 { 3, 2,1080, 619,1270, 540, 438, 0, 438}
1658};
1659
1660XGI330_TVDataStruct XGI_StNTSCData[]=
1661{
1662 { 1, 1, 858, 525,1270, 400, 50, 0, 760},
1663 { 1, 1, 858, 525,1270, 350, 50, 0, 640},
1664 { 1, 1, 858, 525,1270, 400, 0, 0, 720},
1665 { 1, 1, 858, 525,1270, 350, 0, 0, 720},
1666 { 1, 1, 858, 525,1270, 480, 0, 0, 760}
1667};
1668
1669XGI330_TVDataStruct XGI_ExtNTSCData[]=
1670{
1671 { 9, 5, 1001, 453,1270, 420, 171, 0, 171},
1672 { 12, 5, 858, 403,1270, 420, 171, 0, 171},
1673 { 9, 5, 1001, 453,1270, 420, 171, 0, 171},
1674 { 12, 5, 858, 403,1270, 420, 171, 0, 171},
1675 { 143, 80, 836, 523,1270, 420, 224, 0, 0},
1676 { 143, 120,1008, 643,1270, 420, 0, 1, 0},
1677 { 1, 1,1120, 821,1516, 420, 0, 1, 0}, /*301b*/
1678 { 2, 1, 858, 503,1584, 480, 0, 1, 0},
1679 { 3, 2,1001, 533,1270, 420, 0, 0, 0}
1680};
1681
1682XGI330_TVDataStruct XGI_St1HiTVData[]=
1683{
1684 { 1,1,892,563,690,800,0,0,0 }, /* 00 (320x200,320x400,640x200,640x400) */
1685 { 1,1,892,563,690,700,0,0,0 }, /* 01 (320x350,640x350) */
1686 { 1,1,1000,563,785,800,0,0,0 }, /* 02 (360x400,720x400) */
1687 { 1,1,1000,563,785,700,0,0,0 }, /* 03 (720x350) */
1688 { 1,1,892,563,690,960,0,0,0 }, /* 04 (320x240,640x480) */
1689 { 8,5,1050,683,1648,960,0x150,1,0 } /* 05 (400x300,800x600) */
1690};
1691
1692XGI330_TVDataStruct XGI_St2HiTVData[]=
1693{
1694 { 3,1,840,483,1648,960,0x032,0,0 }, /* 00 (320x200,320x400,640x200,640x400) */
1695 { 1,1,892,563,690,700,0,0,0 }, /* 01 (320x350,640x350) */
1696 { 3,1,840,483,1648,960,0x032,0,0 }, /* 02 (360x400,720x400) */
1697 { 1,1,1000,563,785,700,0,0,0 }, /* 03 (720x350) */
1698 { 5,2,840,563,1648,960,0x08D,1,0 }, /* 04 (320x240,640x480) */
1699 { 8,5,1050,683,1648,960,0x17C,1,0 } /* 05 (400x300,800x600) */
1700
1701};
1702
1703XGI330_TVDataStruct XGI_ExtHiTVData[]=
1704{
1705 { 6,1,840,563,1632,960,0,0,0 }, /* 00 (320x200,320x400,640x200,640x400) */
1706 { 3,1,960,563,1632,960,0,0,0 }, /* 01 (320x350,640x350) */
1707 { 3,1,840,483,1632,960,0,0,0 }, /* 02 (360x400,720x400) */
1708 { 3,1,960,563,1632,960,0,0,0 }, /* 03 (720x350) */
1709 { 5,1,840,563,1648,960,0x166,1,0 }, /* 04 (320x240,640x480) */
1710 { 16,5,1050,683,1648,960,0x143,1,0 }, /* 05 (400x300,800x600) */
1711 { 25,12,1260,851,1648,960,0x032,0,0 }, /* 06 (512x384,1024x768) */
1712 { 5,4,1575,1124,1648,960,0x128,0,0 }, /* 07 (1280x1024) */
1713 { 4,1,1050,563,1548,960,0x143,1,0 }, /* 08 (800x480) */
1714 { 5,2,1400,659,1648,960,0x032,0,0 }, /* 09 (1024x576) */
1715 { 8,5,1750,803,1648,960,0x128,0,0 } /* 0A (1280x720) */
1716
1717};
1718
1719XGI330_TVDataStruct XGI_ExtYPbPr525iData[]=
1720{
1721 { 9, 5, 1001, 453,1270, 420, 171, 0, 171},
1722 { 12, 5, 858, 403,1270, 420, 171, 0, 171},
1723 { 9, 5, 1001, 453,1270, 420, 171, 0, 171},
1724 { 12, 5, 858, 403,1270, 420, 171, 0, 171},
1725 { 143, 80, 836, 523,1250, 420, 224, 0, 0},
1726 { 143, 120,1008, 643,1250, 420, 0, 1, 0},
1727 { 1, 1,1120, 821,1516, 420, 0, 1, 0}, /*301b*/
1728 { 2, 1, 858, 503,1584, 480, 0, 1, 0},
1729 { 3, 2,1001, 533,1250, 420, 0, 0, 0}
1730};
1731
1732XGI330_TVDataStruct XGI_StYPbPr525iData[]=
1733{
1734 { 1, 1, 858, 525,1270, 400, 50, 0, 760},
1735 { 1, 1, 858, 525,1270, 350, 50, 0, 640},
1736 { 1, 1, 858, 525,1270, 400, 0, 0, 720},
1737 { 1, 1, 858, 525,1270, 350, 0, 0, 720},
1738 { 1, 1, 858, 525,1270, 480, 0, 0, 760},
1739};
1740
1741XGI330_TVDataStruct XGI_ExtYPbPr525pData[]=
1742{
1743 { 9, 5, 1001, 453,1270, 420, 171, 0, 171},
1744 { 12, 5, 858, 403,1270, 420, 171, 0, 171},
1745 { 9, 5, 1001, 453,1270, 420, 171, 0, 171},
1746 { 12, 5, 858, 403,1270, 420, 171, 0, 171},
1747 { 143, 80, 836, 523,1270, 420, 224, 0, 0},
1748 { 143, 120,1008, 643,1270, 420, 0, 1, 0},
1749 { 1, 1,1120, 821,1516, 420, 0, 1, 0}, /*301b*/
1750 { 2, 1, 858, 503,1584, 480, 0, 1, 0},
1751 { 3, 2,1001, 533,1270, 420, 0, 0, 0}
1752 };
1753
1754XGI330_TVDataStruct XGI_StYPbPr525pData[]=
1755{
1756 { 1, 1,1716, 525,1270, 400, 50, 0, 760},
1757 { 1, 1,1716, 525,1270, 350, 50, 0, 640},
1758 { 1, 1,1716, 525,1270, 400, 0, 0, 720},
1759 { 1, 1,1716, 525,1270, 350, 0, 0, 720},
1760 { 1, 1,1716, 525,1270, 480, 0, 0, 760},
1761};
1762
1763XGI330_TVDataStruct XGI_ExtYPbPr750pData[]=
1764{
1765 { 3, 1, 935, 470,1130, 680, 50, 0, 0}, /* 00 (320x200,320x400,640x200,640x400) */
1766 { 24, 7, 935, 420,1130, 680, 50, 0, 0}, /* 01 (320x350,640x350) */
1767 { 3, 1, 935, 470,1130, 680, 50, 0, 0}, /* 02 (360x400,720x400) */
1768 { 24, 7, 935, 420,1130, 680, 50, 0, 0}, /* 03 (720x350) */
1769 { 2, 1,1100, 590,1130, 640, 50, 0, 0}, /* 04 (320x240,640x480) */
1770 { 3, 2,1210, 690,1130, 660, 50, 0, 0}, /* 05 (400x300,800x600) */
1771 { 1, 1,1375, 878,1130, 640, 638, 0, 0}, /* 06 (1024x768) */
1772 { 2, 1, 858, 503,1130, 480, 0, 1, 0}, /* 07 (720x480) */
1773 { 5, 4,1815, 570,1130, 660, 50, 0, 0},
1774 { 5, 3,1100, 686,1130, 640, 50, 1, 0},
1775 { 10, 9,1320, 830,1130, 640, 50, 0, 0}
1776};
1777
1778XGI330_TVDataStruct XGI_StYPbPr750pData[]=
1779{
1780 { 1, 1,1650, 750,1280, 400, 50, 0, 760},
1781 { 1, 1,1650, 750,1280, 350, 50, 0, 640},
1782 { 1, 1,1650, 750,1280, 400, 0, 0, 720},
1783 { 1, 1,1650, 750,1280, 350, 0, 0, 720},
1784 { 1, 1,1650, 750,1280, 480, 0, 0, 760},
1785};
1786
1787UCHAR XGI330_NTSCTiming[] = {
1788 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
1789 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
1790 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
1791 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
1792 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
1793 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
1794 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
1795 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00};
1796
1797UCHAR XGI330_PALTiming[] = {
1798 0x21,0x5A,0x35,0x6e,0x04,0x38,0x3d,0x70,
1799 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
1800 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
1801 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
1802 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
1803 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
1804 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
1805 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00};
1806
1807UCHAR XGI330_HiTVExtTiming[] =
1808{
1809 0x2D,0x60,0x2C,0x5F,0x08,0x31,0x3A,0x64,
1810 0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
1811 0x06,0x14,0x3E,0x35,0x6D,0x00,0xC5,0x3F,
1812 0x64,0x90,0x33,0x8C,0x18,0x36,0x3E,0x13,
1813 0x2A,0xDE,0x2A,0x44,0x40,0x2A,0x44,0x40,
1814 0x8E,0x8E,0x82,0x07,0x0B,
1815 0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
1816 0x60,0x14,0x3D,0x63,0x4F,
1817 0x27,0x00,0xfc,0xff,0x6a,0x00
1818
1819};
1820
1821UCHAR XGI330_HiTVSt1Timing[] =
1822{
1823 0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x65,
1824 0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
1825 0x06,0x14,0x3E,0x35,0x6D,0x00,0xC5,0x3F,
1826 0x65,0x90,0x7B,0xA8,0x03,0xF0,0x87,0x03,
1827 0x11,0x15,0x11,0xCF,0x10,0x11,0xCF,0x10,
1828 0x35,0x35,0x3B,0x69,0x1D,
1829 0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
1830 0x60,0x04,0x86,0xAF,0x5D,
1831 0x0E,0x00,0xfc,0xff,0x2d,0x00
1832};
1833
1834UCHAR XGI330_HiTVSt2Timing[] =
1835{
1836 0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x64,
1837 0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
1838 0x06,0x14,0x3E,0x35,0x6D,0x00,0xC5,0x3F,
1839 0x64,0x90,0x33,0x8C,0x18,0x36,0x3E,0x13,
1840 0x2A,0xDE,0x2A,0x44,0x40,0x2A,0x44,0x40,
1841 0x8E,0x8E,0x82,0x07,0x0B,
1842 0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
1843 0x60,0x14,0x3D,0x63,0x4F,
1844 0x27,0x00,0xFC,0xff,0x6a,0x00
1845};
1846
1847UCHAR XGI330_HiTVTextTiming[] =
1848{
1849 0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x65,
1850 0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
1851 0x06,0x14,0x3E,0x35,0x6D,0x00,0xC5,0x3F,
1852 0x65,0x90,0xE7,0xBC,0x03,0x0C,0x97,0x03,
1853 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
1854 0xC8,0xC8,0x3B,0xD2,0x26,
1855 0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
1856 0x60,0x04,0x96,0x72,0x5C,
1857 0x11,0x00,0xFC,0xFF,0x32,0x00
1858};
1859
1860UCHAR XGI330_YPbPr750pTiming[] =
1861{
1862 0x30,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
1863 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
1864 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
1865 0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
1866 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
1867 0x4b,0x4b,0x6f,0x2f,0x63,
1868 0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
1869 0x60,0x14,0x73,0x00,0x40,
1870 0x11,0x00,0xfc,0xff,0x32,0x00
1871};
1872
1873UCHAR XGI330_YPbPr525pTiming[] =
1874{
1875 0x3E,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
1876 0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
1877 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
1878 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
1879 0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
1880 0x51,0x5e,0x60,0x49,0x7d,
1881 0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
1882 0x60,0x14,0x4B,0x43,0x41,
1883 0x11,0x00,0xFC,0xFF,0x32,0x00
1884};
1885
1886UCHAR XGI330_YPbPr525iTiming[] =
1887{
1888 0x1B,0x21,0x03,0x09,0x05,0x06,0x0C,0x0C,
1889 0x94,0x49,0x01,0x0A,0x06,0x0D,0x04,0x0A,
1890 0x06,0x14,0x0D,0x04,0x0A,0x00,0x85,0x1B,
1891 0x0C,0x50,0x00,0x97,0x00,0xDA,0x4A,0x17,
1892 0x7D,0x05,0x4B,0x00,0x00,0xE2,0x00,0x02,
1893 0x03,0x0A,0x65,0x9D,0x08,
1894 0x92,0x8F,0x40,0x60,0x80,0x14,0x90,0x8C,
1895 0x60,0x14,0x4B,0x00,0x40,
1896 0x44,0x00,0xDB,0x02,0x3B,0x00
1897
1898};
1899
1900UCHAR XGI330_HiTVGroup3Data[] =
1901{
1902 0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0x5F,
1903 0x05,0x21,0xB2,0xB2,0x55,0x77,0x2A,0xA6,
1904 0x25,0x2F,0x47,0xFA,0xC8,0xFF,0x8E,0x20,
1905 0x8C,0x6E,0x60,0x2E,0x58,0x48,0x72,0x44,
1906 0x56,0x36,0x4F,0x6E,0x3F,0x80,0x00,0x80,
1907 0x4F,0x7F,0x03,0xA8,0x7D,0x20,0x1A,0xA9,
1908 0x14,0x05,0x03,0x7E,0x64,0x31,0x14,0x75,
1909 0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
1910};
1911
1912UCHAR XGI330_HiTVGroup3Simu[] =
1913{
1914 0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0x95,
1915 0xDB,0x20,0xB8,0xB8,0x55,0x47,0x2A,0xA6,
1916 0x25,0x2F,0x47,0xFA,0xC8,0xFF,0x8E,0x20,
1917 0x8C,0x6E,0x60,0x15,0x26,0xD3,0xE4,0x11,
1918 0x56,0x36,0x4F,0x6E,0x3F,0x80,0x00,0x80,
1919 0x67,0x36,0x01,0x47,0x0E,0x10,0xBE,0xB4,
1920 0x01,0x05,0x03,0x7E,0x65,0x31,0x14,0x75,
1921 0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
1922};
1923
1924UCHAR XGI330_HiTVGroup3Text[] =
1925{
1926 0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0xA7,
1927 0xF5,0x20,0xCE,0xCE,0x55,0x47,0x2A,0xA6,
1928 0x25,0x2F,0x47,0xFA,0xC8,0xFF,0x8E,0x20,
1929 0x8C,0x6E,0x60,0x18,0x2C,0x0C,0x20,0x22,
1930 0x56,0x36,0x4F,0x6E,0x3F,0x80,0x00,0x80,
1931 0x93,0x3C,0x01,0x50,0x2F,0x10,0xF4,0xCA,
1932 0x01,0x05,0x03,0x7E,0x65,0x31,0x14,0x75,
1933 0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
1934};
1935
1936UCHAR XGI330_Ren525pGroup3[] =
1937{
1938 0x00,0x14,0x15,0x25,0x55,0x15,0x0b,0x13,
1939 0xB1,0x41,0x62,0x62,0xFF,0xF4,0x45,0xa6,
1940 0x25,0x2F,0x67,0xF6,0xbf,0xFF,0x8E,0x20,
1941 0xAC,0xDA,0x60,0xFe,0x6A,0x9A,0x06,0x10,
1942 0xd1,0x04,0x18,0x0a,0xFF,0x80,0x00,0x80,
1943 0x3c,0x77,0x00,0xEF,0xE0,0x10,0xB0,0xE0,
1944 0x10,0x4F,0x0F,0x0F,0x05,0x0F,0x08,0x6E,
1945 0x1a,0x1F,0x25,0x2a,0x4C,0xAA,0x01
1946};
1947
1948UCHAR XGI330_Ren750pGroup3[] =
1949{
1950 0x00,0x14,0x15,0x25,0x55,0x15,0x0b,0x7a,
1951 0x54,0x41,0xE7,0xE7,0xFF,0xF4,0x45,0xa6,
1952 0x25,0x2F,0x67,0xF6,0xbf,0xFF,0x8E,0x20,
1953 0xAC,0x6A,0x60,0x2b,0x52,0xCD,0x61,0x10,
1954 0x51,0x04,0x18,0x0a,0x1F,0x80,0x00,0x80,
1955 0xFF,0xA4,0x04,0x2B,0x94,0x21,0x72,0x94,
1956 0x26,0x05,0x01,0x0F,0xed,0x0F,0x0A,0x64,
1957 0x18,0x1D,0x23,0x28,0x4C,0xAA,0x01
1958};
1959
1960XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[]=
1961{
1962{{0x00,0x00}},
1963{{0x00,0x00}},
1964{{0x00,0x00}},
1965{{0x00,0x00}},
1966{{0x00,0x00}},
1967{{0x00,0x00}},
1968{{0x00,0x00}},
1969{{0x00,0x00}},
1970{{0x00,0x00}},
1971{{0x00,0x00}},
1972{{0x00,0x00}},
1973{{0x00,0x00}},
1974{{0x00,0x00}},
1975{{0x00,0x00}},
1976{{0x00,0x00}},
1977{{0x00,0x00}}
1978};
1979
1980XGI330_LVDSDataStruct XGI330_LVDS320x480Data_1[]=
1981{
1982 {848, 433,400,525},
1983 {848, 389,400,525},
1984 {848, 433,400,525},
1985 {848, 389,400,525},
1986 {848, 518,400, 525},
1987 {1056, 628,400,525},
1988 {400, 525,400,525},
1989 {800, 449,1000, 644},
1990 {800, 525,1000, 635}
1991};
1992
1993XGI330_LVDSDataStruct XGI330_LVDS800x600Data_1[]=
1994{
1995 {848, 433,1060, 629},
1996 {848, 389,1060, 629},
1997 {848, 433,1060, 629},
1998 {848, 389,1060, 629},
1999 {848, 518,1060, 629},
2000 {1056, 628,1056, 628},
2001 {1056, 628,1056, 628},
2002 {800, 449,1000, 644},
2003 {800, 525,1000, 635}
2004};
2005
2006XGI330_LVDSDataStruct XGI330_LVDS800x600Data_2[]=
2007{
2008 {1056, 628,1056, 628},
2009 {1056, 628,1056, 628},
2010 {1056, 628,1056, 628},
2011 {1056, 628,1056, 628},
2012 {1056, 628,1056, 628},
2013 {1056, 628,1056, 628},
2014 {1056, 628,1056, 628},
2015 {800, 449,1000, 644},
2016 {800, 525,1000, 635}
2017};
2018
2019XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1[]=
2020{
2021 { 960 , 438 , 1344 , 806 } , /* 00 (320x200,320x400,640x200,640x400) */
2022 { 960 , 388 , 1344 , 806 } , /* 01 (320x350,640x350) */
2023 { 1040, 438 , 1344 , 806 } , /* 02 (360x400,720x400) */
2024 { 1040, 388 , 1344 , 806 } , /* 03 (720x350) */
2025 { 960 , 518 , 1344 , 806 } , /* 04 (320x240,640x480) */
2026 {1120 , 638 , 1344 , 806 } , /* 05 (400x300,800x600) */
2027 {1344 , 806 , 1344 , 806 } /* 06 (512x384,1024x768) */
2028};
2029
2030
2031XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2[]=
2032{
2033 {1344, 806,1344, 806},
2034 {1344, 806,1344, 806},
2035 {1344, 806,1344, 806},
2036 {1344, 806,1344, 806},
2037 {1344, 806,1344, 806},
2038 {1344, 806,1344, 806},
2039 {1344, 806,1344, 806},
2040 {800, 449,1280, 801},
2041 {800, 525,1280, 813}
2042};
2043
2044XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1[]=
2045{
2046 {1048, 442,1688, 1066},
2047 {1048, 392,1688, 1066},
2048 {1048, 442,1688, 1066},
2049 {1048, 392,1688, 1066},
2050 {1048, 522,1688, 1066},
2051 {1208, 642,1688, 1066},
2052 {1432, 810,1688, 1066},
2053 {1688, 1066,1688, 1066}
2054};
2055
2056XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2[]=
2057{
2058 {1344, 806,1344, 806},
2059 {1344, 806,1344, 806},
2060 {1344, 806,1344, 806},
2061 {1344, 806,1344, 806},
2062 {1344, 806,1344, 806},
2063 {1344, 806,1344, 806},
2064 {1344, 806,1344, 806},
2065 {800, 449,1280, 801},
2066 {800, 525,1280, 813}
2067};
2068/*
2069XGI330_LVDSDataStruct XGI_LVDS1280x768Data_1[]=
2070{
2071 {768,438,1408,806},
2072 {768,388,1408,806},
2073 {768,438,1408,806},
2074 {768,388,1408,806},
2075 {768,518,1408,806},
2076 {928,638,1408,806},
2077 {1408,806,1408,806},
2078 {1408,806,1408,806},
2079 {1408,806,1408,806}
2080};
2081
2082XGI330_LVDSDataStruct XGI_LVDS1280x768Data_2[]=
2083{
2084 {1408, 806,1408, 806},
2085 {1408, 806,1408, 806},
2086 {1408, 806,1408, 806},
2087 {1408, 806,1408, 806},
2088 {1408, 806,1408, 806},
2089 {1408, 806,1408, 806},
2090 {1408, 806,1408, 806},
2091 {1408, 806,1408, 806},
2092 {1408, 806,1408, 806}
2093};
2094
2095XGI330_LVDSDataStruct XGI_LVDS1280x768NData_1[]=
2096{
2097 {704, 438,1344, 806},
2098 {704, 388,1344, 806},
2099 {704, 438,1344, 806},
2100 {704, 388,1344, 806},
2101 {704, 518,1344, 806},
2102 {864, 638,1344, 806},
2103 {1088, 806,1344, 806},
2104 {1344, 806,1344, 806},
2105 {1344, 806,1344, 806}
2106};
2107
2108XGI330_LVDSDataStruct XGI_LVDS1280x768NData_2[]=
2109{
2110 {1344, 806,1344, 806},
2111 {1344, 806,1344, 806},
2112 {1344, 806,1344, 806},
2113 {1344, 806,1344, 806},
2114 {1344, 806,1344, 806},
2115 {1344, 806,1344, 806},
2116 {1344, 806,1344, 806},
2117 {1344, 806,1344, 806},
2118 {1344, 806,1344, 806}
2119};
2120
2121XGI330_LVDSDataStruct XGI_LVDS1280x768SData_1[]=
2122{
2123 {1048,438,1688,806},
2124 {1048,388,1688,806},
2125 {1148,438,1688,806},
2126 {1148,388,1688,806},
2127 {1048,518,1688,806},
2128 {1208,638,1688,806},
2129 {1432,806,1688,806},
2130 {1688,806,1688,806},
2131 {1688,806,1688,806}
2132};
2133
2134XGI330_LVDSDataStruct XGI_LVDS1280x768SData_2[]=
2135{
2136 {1688,806,1688,806},
2137 {1688,806,1688,806},
2138 {1688,806,1688,806},
2139 {1688,806,1688,806},
2140 {1688,806,1688,806},
2141 {1688,806,1688,806},
2142 {1688,806,1688,806},
2143 {1688,806,1688,806},
2144 {1688,806,1688,806}
2145};
2146*/
2147XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_1[]=
2148{
2149 {928,416,1688,1066},
2150 {928,366,1688,1066},
2151 {928,416,1688,1066},
2152 {928,366,1688,1066},
2153 {928,496,1688,1066},
2154 {1088,616,1688,1066},
2155 {1312,784,1688,1066},
2156 {1568,1040,1688,1066},
2157 {1688,1066,1688,1066}
2158};
2159
2160XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_2[]=
2161{
2162 {1688,1066,1688,1066},
2163 {1688,1066,1688,1066},
2164 {1688,1066,1688,1066},
2165 {1688,1066,1688,1066},
2166 {1688,1066,1688,1066},
2167 {1688,1066,1688,1066},
2168 {1688,1066,1688,1066},
2169 {1688,1066,1688,1066},
2170 {1688,1066,1688,1066}
2171};
2172
2173XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[]=
2174{ /* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */
2175 { 1088,520,2048,1320 },/* 00 (320x200,320x400,640x200,640x400) */
2176 { 1088,470,2048,1320 },/* 01 (320x350,640x350) */
2177 { 1088,520,2048,1320 },/* 02 (360x400,720x400) */
2178 { 1088,470,2048,1320 },/* 03 (720x350) */
2179 { 1088,600,2048,1320 },/* 04 (320x240,640x480) */
2180 { 1248,720,2048,1320 },/* 05 (400x300,800x600) */
2181 { 1472,888,2048,1320 },/* 06 (512x384,1024x768) */
2182 { 1728,1144,2048,1320 },/* 07 (640x512,1280x1024) */
2183 { 1848,1170,2048,1320 },/* 08 (1400x1050) */
2184 { 2048,1320,2048,1320 } /* 09 (1600x1200) */
2185};
2186
2187XGI330_LVDSDataStruct XGI_LVDSNoScalingData[]=
2188{
2189 { 800,449,800,449 }, /* 00 (320x200,320x400,640x200,640x400) */
2190 { 800,449,800,449 }, /* 01 (320x350,640x350) */
2191 { 800,449,800,449 }, /* 02 (360x400,720x400) */
2192 { 800,449,800,449 }, /* 03 (720x350) */
2193 { 800,525,800,525 }, /* 04 (640x480x60Hz) */
2194 { 1056,628,1056,628 }, /* 05 (800x600x60Hz) */
2195 { 1344,806,1344,806 }, /* 06 (1024x768x60Hz) */
2196 { 1688,1066,1688,1066 }, /* 07 (1280x1024x60Hz) */
2197 { 1688,1066,1688,1066 }, /* 08 (1400x1050x60Hz) ;;[ycchen] 12/19/02 */
2198 { 2160,1250,2160,1250 }, /* 09 (1600x1200x60Hz) */
2199 { 1688,806,1688,806 } /* 0A (1280x768x60Hz) */
2200};
2201
2202XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[]=
2203{
2204 {960,438,1312,800 }, /* 00 (320x200,320x400,640x200,640x400) */
2205 {960,388,1312,800 }, /* 01 (320x350,640x350) */
2206 {1040,438,1312,800 }, /* 02 (360x400,720x400) */
2207 {1040,388,1312,800 }, /* 03 (720x350) */
2208 {928,512,1312,800 }, /* 04 (320x240,640x480) */
2209 {1088,632,1312,800 }, /* 05 (400x300,800x600) */
2210 {1312,800,1312,800 }, /* 06 (512x384,1024x768) */
2211};
2212
2213
2214XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[]=
2215{
2216 {1312,800,1312,800}, /* ; 00 (320x200,320x400,640x200,640x400) */
2217 {1312,800,1312,800}, /* ; 01 (320x350,640x350) */
2218 {1312,800,1312,800}, /* ; 02 (360x400,720x400) */
2219 {1312,800,1312,800}, /* ; 03 (720x350) */
2220 {1312,800,1312,800}, /* ; 04 (320x240,640x480) */
2221 {1312,800,1312,800}, /* ; 05 (400x300,800x600) */
2222 {1312,800,1312,800}, /* ; 06 (512x384,1024x768) */
2223};
2224
2225XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[]=
2226{
2227 {1048,442,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
2228 {1048,392,1688,1066 }, /* ; 01 (320x350,640x350) */
2229 {1128,442,1688,1066 }, /* ; 02 (360x400,720x400) */
2230 {1128,392,1688,1066 }, /* ; 03 (720x350) */
2231 {1048,522,1688,1066 }, /* ; 04 (320x240,640x480) */
2232 {1208,642,1688,1066 }, /* ; 05 (400x300,800x600) */
2233 {1432,810,1688,1066 }, /* ; 06 (512x384,1024x768) */
2234 {1688,1066,1688,1066 }, /* ; 06; 07 (640x512,1280x1024) */
2235};
2236
2237XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[]=
2238{
2239 {1688,1066,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
2240 {1688,1066,1688,1066 }, /* ; 01 (320x350,640x350) */
2241 {1688,1066,1688,1066 }, /* ; 02 (360x400,720x400) */
2242 {1688,1066,1688,1066 }, /* ; 03 (720x350) */
2243 {1688,1066,1688,1066 }, /* ; 04 (320x240,640x480) */
2244 {1688,1066,1688,1066 }, /* ; 05 (400x300,800x600) */
2245 {1688,1066,1688,1066 }, /* ; 06 (512x384,1024x768) */
2246 {1688,1066,1688,1066 }, /* ; 06; 07 (640x512,1280x1024) */
2247};
2248
2249XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[]=
2250{
2251 {800,449,800,449 }, /* ; 00 (320x200,320x400,640x200,640x400) */
2252 {800,449,800,449 }, /* ; 01 (320x350,640x350) */
2253 {900,449,900,449 }, /* ; 02 (360x400,720x400) */
2254 {900,449,900,449 }, /* ; 03 (720x350) */
2255 {800,500,800,500 }, /* ; 04 (640x480x75Hz) */
2256 {1056,625,1056,625 }, /* ; 05 (800x600x75Hz) */
2257 {1312,800,1312,800 }, /* ; 06 (1024x768x75Hz) */
2258 {1688,1066,1688,1066 }, /* ; 07 (1280x1024x75Hz) */
2259 {1688,1066,1688,1066 }, /* ; 08 (1400x1050x75Hz) ;;[ycchen] 12/19/02 */
2260 {2160,1250,2160,1250 }, /* ; 09 (1600x1200x75Hz) */
2261 {1688,806,1688,806 }, /* ; 0A (1280x768x75Hz) */
2262};
2263
2264XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[]=
2265{
2266 { 0,1048, 0, 771 }, /* 00 (320x200,320x400,640x200,640x400) */
2267 { 0,1048, 0, 771 }, /* 01 (320x350,640x350) */
2268 { 0,1048, 0, 771 }, /* 02 (360x400,720x400) */
2269 { 0,1048, 0, 771 }, /* 03 (720x350) */
2270 { 0,1048, 0, 771 }, /* 04 (640x480x60Hz) */
2271 { 0,1048, 0, 771 }, /* 05 (800x600x60Hz) */
2272 { 0,1048, 805, 770 } /* 06 (1024x768x60Hz) */
2273} ;
2274
2275XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[]=
2276{
2277 { 1142, 856, 622, 587 }, /* 00 (320x200,320x400,640x200,640x400) */
2278 { 1142, 856, 597, 562 }, /* 01 (320x350,640x350) */
2279 { 1142, 856, 622, 587 }, /* 02 (360x400,720x400) */
2280 { 1142, 856, 597, 562 }, /* 03 (720x350) */
2281 { 1142,1048, 722, 687 }, /* 04 (640x480x60Hz) */
2282 { 1232, 936, 722, 687 }, /* 05 (800x600x60Hz) */
2283 { 0,1048, 805, 771 } /* 06 (1024x768x60Hz) */
2284};
2285
2286XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[]=
2287{
2288 { 320, 24, 622, 587 }, /* 00 (320x200,320x400,640x200,640x400) */
2289 { 320, 24, 597, 562 }, /* 01 (320x350,640x350) */
2290 { 320, 24, 622, 587 }, /* 02 (360x400,720x400) */
2291 { 320, 24, 597, 562 }, /* 03 (720x350) */
2292 { 320, 24, 722, 687 } /* 04 (640x480x60Hz) */
2293};
2294
2295XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[]=
2296{
2297 { 0,1328, 0, 1025 }, /* 00 (320x200,320x400,640x200,640x400) */
2298 { 0,1328, 0, 1025 }, /* 01 (320x350,640x350) */
2299 { 0,1328, 0, 1025 }, /* 02 (360x400,720x400) */
2300 { 0,1328, 0, 1025 }, /* 03 (720x350) */
2301 { 0,1328, 0, 1025 }, /* 04 (640x480x60Hz) */
2302 { 0,1328, 0, 1025 }, /* 05 (800x600x60Hz) */
2303 { 0,1328, 0, 1025 }, /* 06 (1024x768x60Hz) */
2304 { 0,1328, 1065, 1024 } /* 07 (1280x1024x60Hz) */
2305};
2306
2307 /* The Display setting for DE Mode Panel */
2308XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[]=
2309{
2310 { 1368,1008,752,711 }, /* 00 (320x200,320x400,640x200,640x400) */
2311 { 1368,1008,729,688 }, /* 01 (320x350,640x350) */
2312 { 1408,1048,752,711 }, /* 02 (360x400,720x400) */
2313 { 1408,1048,729,688 }, /* 03 (720x350) */
2314 { 1368,1008,794,753 }, /* 04 (640x480x60Hz) */
2315 { 1448,1068,854,813 }, /* 05 (800x600x60Hz) */
2316 { 1560,1200,938,897 }, /* 06 (1024x768x60Hz) */
2317 { 0000,1328,0,1025 } /* 07 (1280x1024x60Hz) */
2318};
2319
2320XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[]=
2321{
2322 { 0,1448,0,1051 }, /* 00 (320x200,320x400,640x200,640x400) */
2323 { 0,1448,0,1051 }, /* 01 (320x350,640x350) */
2324 { 0,1448,0,1051 }, /* 02 (360x400,720x400) */
2325 { 0,1448,0,1051 }, /* 03 (720x350) */
2326 { 0,1448,0,1051 }, /* 04 (640x480x60Hz) */
2327 { 0,1448,0,1051 }, /* 05 (800x600x60Hz) */
2328 { 0,1448,0,1051 }, /* 06 (1024x768x60Hz) */
2329 { 0,1448,0,1051 }, /* 07 (1280x1024x60Hz) */
2330 { 0,1448,0,1051 } /* 08 (1400x1050x60Hz) */
2331};
2332
2333XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[]=
2334{
2335 { 1308,1068, 781, 766 }, /* 00 (320x200,320x400,640x200,640x400) */
2336 { 1308,1068, 781, 766 }, /* 01 (320x350,640x350) */
2337 { 1308,1068, 781, 766 }, /* 02 (360x400,720x400) */
2338 { 1308,1068, 781, 766 }, /* 03 (720x350) */
2339 { 1308,1068, 781, 766 }, /* 04 (640x480x60Hz) */
2340 { 1388,1148, 841, 826 }, /* 05 (800x600x60Hz) */
2341 { 1490,1250, 925, 910 }, /* 06 (1024x768x60Hz) */
2342 { 1608,1368,1053,1038 }, /* 07 (1280x1024x60Hz) */
2343 { 0,1448,0,1051 } /* 08 (1400x1050x60Hz) */
2344};
2345
2346XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[]=
2347{
2348 { 0,1664,0,1201 }, /* 00 (320x200,320x400,640x200,640x400) */
2349 { 0,1664,0,1201 }, /* 01 (320x350,640x350) */
2350 { 0,1664,0,1201 }, /* 02 (360x400,720x400) */
2351 { 0,1664,0,1201 }, /* 03 (720x350) */
2352 { 0,1664,0,1201 }, /* 04 (640x480x60Hz) */
2353 { 0,1664,0,1201 }, /* 05 (800x600x60Hz) */
2354 { 0,1664,0,1201 }, /* 06 (1024x768x60Hz) */
2355 { 0,1664,0,1201 }, /* 07 (1280x1024x60Hz) */
2356 { 0,1664,0,1201 }, /* 08 (1400x1050x60Hz) */
2357 { 0,1664,0,1201 } /* 09 (1600x1200x60Hz) */
2358};
2359
2360
2361
2362XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[]=
2363{
2364 { 0, 648, 448, 405, 96, 2 }, /* 00 (320x200,320x400,640x200,640x400) */
2365 { 0, 648, 448, 355, 96, 2 }, /* 01 (320x350,640x350) */
2366 { 0, 648, 448, 405, 96, 2 }, /* 02 (360x400,720x400) */
2367 { 0, 648, 448, 355, 96, 2 }, /* 03 (720x350) */
2368 { 0, 648, 1, 483, 96, 2 }, /* 04 (640x480x60Hz) */
2369 { 0, 840, 627, 600, 128, 4 }, /* 05 (800x600x60Hz) */
2370 { 0,1048, 805, 770, 136, 6 }, /* 06 (1024x768x60Hz) */
2371 { 0,1328,0,1025, 112, 3 }, /* 07 (1280x1024x60Hz) */
2372 { 0,1438,0,1051, 112, 3 }, /* 08 (1400x1050x60Hz) ;;[ycchen] 12/19/02 */
2373 { 0,1664,0,1201, 192, 3 }, /* 09 (1600x1200x60Hz) */
2374 { 0,1328,0,0771, 112, 6 } /* 0A (1280x768x60Hz) */
2375};
2376
2377XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[]= /* ; 1024x768 Full-screen */
2378{
2379 {0,1040,0,769}, /* ; 00 (320x200,320x400,640x200,640x400) */
2380 {0,1040,0,769}, /* ; 01 (320x350,640x350) */
2381 {0,1040,0,769}, /* ; 02 (360x400,720x400) */
2382 {0,1040,0,769}, /* ; 03 (720x350) */
2383 {0,1040,0,769}, /* ; 04 (640x480x75Hz) */
2384 {0,1040,0,769}, /* ; 05 (800x600x75Hz) */
2385 {0,1040,0,769} /* ; 06 (1024x768x75Hz) */
2386};
2387
2388XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[]= /* ; 1024x768 center-screen (Enh. Mode) */
2389{
2390 {1142, 856,622,587 }, /* 00 (320x200,320x400,640x200,640x400) */
2391 {1142, 856,597,562 }, /* 01 (320x350,640x350) */
2392 {1142, 856,622,587 }, /* 02 (360x400,720x400) */
2393 {1142, 856,597,562 }, /* 03 (720x350) */
2394 {1142,1048,722,687 }, /* 04 (640x480x60Hz) */
2395 {1232, 936,722,687 }, /* 05 (800x600x60Hz) */
2396 { 0,1048,805,771 } /* 06 (1024x768x60Hz) */
2397};
2398
2399XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[]= /* ; 1024x768 center-screen (St.Mode) */
2400{
2401 {320,24,622,587 }, /* ; 00 (320x200,320x400,640x200,640x400) */
2402 {320,24,597,562 }, /* ; 01 (320x350,640x350) */
2403 {320,24,622,587 }, /* ; 02 (360x400,720x400) */
2404 {320,24,597,562 }, /* ; 03 (720x350) */
2405 {320,24,722,687 } /* ; 04 (640x480x60Hz) */
2406};
2407
2408XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[]=
2409{
2410 {0,1296,0,1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
2411 {0,1296,0,1025}, /* ; 01 (320x350,640x350) */
2412 {0,1296,0,1025}, /* ; 02 (360x400,720x400) */
2413 {0,1296,0,1025}, /* ; 03 (720x350) */
2414 {0,1296,0,1025}, /* ; 04 (640x480x75Hz) */
2415 {0,1296,0,1025}, /* ; 05 (800x600x75Hz) */
2416 {0,1296,0,1025}, /* ; 06 (1024x768x75Hz) */
2417 {0,1296,0,1025} /* ; 07 (1280x1024x75Hz) */
2418};
2419
2420/* The Display setting for DE Mode Panel */
2421XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[]= /* [ycchen] 02/18/03 Set DE as default */
2422{
2423 {1368,976,752,711 }, /* ; 00 (320x200,320x400,640x200,640x400) */
2424 {1368,976,729,688 }, /* ; 01 (320x350,640x350) */
2425 {1408,976,752,711 }, /* ; 02 (360x400,720x400) */
2426 {1408,976,729,688 }, /* ; 03 (720x350) */
2427 {1368,976,794,753 }, /* ; 04 (640x480x75Hz) */
2428 {1448,1036,854,813}, /* ; 05 (800x600x75Hz) */
2429 {1560,1168,938,897}, /* ; 06 (1024x768x75Hz) */
2430 {0,1296,0,1025 } /* ; 07 (1280x1024x75Hz) */
2431};
2432
2433XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[]= /* Scaling LCD 75Hz */
2434{
2435 { 0,648,448,405,96,2 }, /* ; 00 (320x200,320x400,640x200,640x400) */
2436 { 0,648,448,355,96,2 }, /* ; 01 (320x350,640x350) */
2437 { 0,729,448,405,108,2 }, /* ; 02 (360x400,720x400) */
2438 { 0,729,448,355,108,2 }, /* ; 03 (720x350) */
2439 { 0,656,0,481,64,3 }, /* ; 04 (640x480x75Hz) */
2440 { 0,816,0,601,80,3 }, /* ; 05 (800x600x75Hz) */
2441 { 0,1040,0,769,96,3 }, /* ; 06 (1024x768x75Hz) */
2442 { 0,1296,0,1025,144,3 }, /* ; 07 (1280x1024x75Hz) */
2443 { 0,1448,0,1051,112,3 }, /* ; 08 (1400x1050x75Hz) ;;[ycchen] 12/19/02 */
2444 { 0,1664,0,1201,192,3 }, /* ; 09 (1600x1200x75Hz) */
2445 { 0,1328,0,771,112,6 } /* ; 0A (1280x768x75Hz) */
2446};
2447
2448XGI330_LVDSDataStruct XGI330_LVDS640x480Data_1[]=
2449{
2450 {800, 449, 800, 449},
2451 {800, 449, 800, 449},
2452 {800, 449, 800, 449},
2453 {800, 449, 800, 449},
2454 {800, 525, 800, 525},
2455 {1056, 628,1056, 628},
2456 {1056, 628,1056, 628},
2457 {1056, 628,1056, 628},
2458 {1056, 628,1056, 628}
2459};
2460
2461XGI330_CHTVDataStruct XGI_CHTVUNTSCData[]=
2462{
2463 {840, 600, 840, 600},
2464 {840, 600, 840, 600},
2465 {840, 600, 840, 600},
2466 {840, 600, 840, 600},
2467 {784, 600, 784, 600},
2468 {1064, 750,1064, 750}
2469};
2470
2471XGI330_CHTVDataStruct XGI_CHTVONTSCData[]=
2472{
2473 {840, 525, 840, 525},
2474 {840, 525, 840, 525},
2475 {840, 525, 840, 525},
2476 {840, 525, 840, 525},
2477 {784, 525, 784, 525},
2478 {1040, 700,1040, 700}
2479};
2480
2481XGI330_CHTVDataStruct XGI_CHTVUPALData[]=
2482{
2483 {1008, 625,1008, 625},
2484 {1008, 625,1008, 625},
2485 {1008, 625,1008, 625},
2486 {1008, 625,1008, 625},
2487 {840, 750, 840, 750},
2488 {936, 836, 936, 836}
2489};
2490
2491XGI330_CHTVDataStruct XGI_CHTVOPALData[]=
2492{
2493 {1008, 625,1008, 625},
2494 {1008, 625,1008, 625},
2495 {1008, 625,1008, 625},
2496 {1008, 625,1008, 625},
2497 {840, 625, 840, 625},
2498 {960, 750, 960, 750}
2499};
2500
2501XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[]=
2502{
2503 /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2504 {{ 0x4B,0x27,0x8F,0x32,0x1B,0x00,0x45,0x00 }}, /* 00 (320x) */
2505 {{ 0x4B,0x27,0x8F,0x2B,0x03,0x00,0x44,0x00 }}, /* 01 (360x) */
2506 {{ 0x55,0x31,0x99,0x46,0x1D,0x00,0x55,0x00 }}, /* 02 (400x) */
2507 {{ 0x63,0x3F,0x87,0x4A,0x93,0x00,0x01,0x00 }}, /* 03 (512x) */
2508 {{ 0x73,0x4F,0x97,0x55,0x86,0x00,0x05,0x00 }}, /* 04 (640x) */
2509 {{ 0x73,0x4F,0x97,0x55,0x86,0x00,0x05,0x00 }}, /* 05 (720x) */
2510 {{ 0x87,0x63,0x8B,0x69,0x1A,0x00,0x26,0x00 }}, /* 06 (800x) */
2511 {{ 0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* 07 (1024x) */
2512};
2513
2514XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[]=
2515{
2516 /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2517 {{ 0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }}, /* 00 (320x) */
2518 {{ 0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }}, /* 01 (360x) */
2519 {{ 0x60,0x31,0x84,0x3A,0x88,0x00,0x01,0x00 }}, /* 02 (400x) */
2520 {{ 0x6E,0x3F,0x92,0x48,0x96,0x00,0x01,0x00 }}, /* 03 (512x) */
2521 {{ 0x7E,0x4F,0x82,0x58,0x06,0x00,0x06,0x00 }}, /* 04 (640x) */
2522 {{ 0x7E,0x4F,0x82,0x58,0x06,0x00,0x06,0x00 }}, /* 05 (720x) */
2523 {{ 0x92,0x63,0x96,0x6C,0x1A,0x00,0x06,0x00 }}, /* 06 (800x) */
2524 {{ 0xAE,0x7F,0x92,0x88,0x96,0x00,0x02,0x00 }}, /* 07 (1024x) */
2525 {{ 0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* 08 (1280x) */
2526};
2527
2528XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[]=
2529{
2530 /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2531 {{ 0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }}, /* 00 (320x) */
2532 {{ 0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }}, /* 01 (360x) */
2533 {{ 0x63,0x31,0x87,0x3D,0x8E,0x00,0x01,0x00 }}, /* 02 (400x) */
2534 {{ 0x63,0x3F,0x87,0x45,0x96,0x00,0x01,0x00 }}, /* 03 (512x) */
2535 {{ 0xA3,0x4F,0x87,0x6E,0x9F,0x00,0x06,0x00 }}, /* 04 (640x) */
2536 {{ 0xA3,0x4F,0x87,0x6E,0x9F,0x00,0x06,0x00 }}, /* 05 (720x) */
2537 {{ 0xA3,0x63,0x87,0x78,0x89,0x00,0x02,0x00 }}, /* 06 (800x) */
2538 {{ 0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* 07 (1024x) */
2539};
2540
2541XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[]=
2542{
2543 /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2544 {{ 0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }}, /* 00 (320x) */
2545 {{ 0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }}, /* 01 (360x) */
2546 {{ 0x7E,0x40,0x84,0x49,0x91,0x00,0x01,0x00 }}, /* 02 (400x) */
2547 {{ 0x7E,0x47,0x93,0x50,0x9E,0x00,0x01,0x00 }}, /* 03 (512x) */
2548 {{ 0xCE,0x77,0x8A,0x80,0x8E,0x00,0x02,0x00 }}, /* 04 (640x) */
2549 {{ 0xCE,0x77,0x8A,0x80,0x8E,0x00,0x02,0x00 }}, /* 05 (720x) */
2550 {{ 0xCE,0x81,0x94,0x8A,0x98,0x00,0x02,0x00 }}, /* 06 (800x) */
2551 {{ 0xCE,0x8F,0x82,0x98,0x06,0x00,0x07,0x00 }}, /* 07 (1024x) */
2552 {{ 0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* 08 (1280x) */
2553};
2554
2555XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[]=
2556{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2557 {{ 0x47,0x27,0x8B,0x2C,0x1A,0x00,0x05,0x00 }}, /* 00 (320x) */
2558 {{ 0x47,0x27,0x8B,0x30,0x1E,0x00,0x05,0x00 }}, /* 01 (360x) */
2559 {{ 0x51,0x31,0x95,0x36,0x04,0x00,0x01,0x00 }}, /* 02 (400x) */
2560 {{ 0x5F,0x3F,0x83,0x44,0x92,0x00,0x01,0x00 }}, /* 03 (512x) */
2561 {{ 0x6F,0x4F,0x93,0x54,0x82,0x00,0x05,0x00 }}, /* 04 (640x) */
2562 {{ 0x6F,0x4F,0x93,0x54,0x82,0x00,0x05,0x00 }}, /* 05 (720x) */
2563 {{ 0x83,0x63,0x87,0x68,0x16,0x00,0x06,0x00 }}, /* 06 (800x) */
2564 {{ 0x9F,0x7F,0x83,0x84,0x92,0x00,0x02,0x00 }}, /* 07 (1024x) */
2565 {{ 0xBF,0x9F,0x83,0xA4,0x12,0x00,0x07,0x00 }}, /* 08 (1280x) */
2566 {{ 0xCE,0xAE,0x92,0xB3,0x01,0x00,0x03,0x00 }} /* 09 (1400x) */
2567};
2568
2569XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[]=
2570{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2571 {{ 0x76,0x3F,0x83,0x45,0x8C,0x00,0x41,0x00 }}, /* 00 (320x) */
2572 {{ 0x76,0x3F,0x83,0x45,0x8C,0x00,0x41,0x00 }}, /* 01 (360x) */
2573 {{ 0x76,0x31,0x9A,0x48,0x9F,0x00,0x41,0x00 }}, /* 02 (400x) */
2574 {{ 0x76,0x3F,0x9A,0x4F,0x96,0x00,0x41,0x00 }}, /* 03 (512x) */
2575 {{ 0xCE,0x7E,0x82,0x87,0x9E,0x00,0x02,0x00 }}, /* 04 (640x) */
2576 {{ 0xCE,0x7E,0x82,0x87,0x9E,0x00,0x02,0x00 }}, /* 05 (720x) */
2577 {{ 0xCE,0x63,0x92,0x96,0x04,0x00,0x07,0x00 }}, /* 06 (800x) */
2578 {{ 0xCE,0x7F,0x92,0xA4,0x12,0x00,0x07,0x00 }}, /* 07 (1024x) */
2579 {{ 0xCE,0x9F,0x92,0xB4,0x02,0x00,0x03,0x00 }}, /* 08 (1280x) */
2580 {{ 0xCE,0xAE,0x92,0xBC,0x0A,0x00,0x03,0x00 }} /* 09 (1400x) */
2581};
2582
2583XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[]=
2584/* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */
2585{ /* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2586 {{ 0x5B,0x27,0x9F,0x32,0x0A,0x00,0x01,0x00 }},/* 00 (320x) */
2587 {{ 0x5B,0x27,0x9F,0x32,0x0A,0x00,0x01,0x00 }},/* 01 (360x) */
2588 {{ 0x65,0x31,0x89,0x3C,0x94,0x00,0x01,0x00 }},/* 02 (400x) */
2589 {{ 0x73,0x3F,0x97,0x4A,0x82,0x00,0x05,0x00 }},/* 03 (512x) */
2590 {{ 0x83,0x4F,0x87,0x51,0x09,0x00,0x06,0x00 }},/* 04 (640x) */
2591 {{ 0x83,0x4F,0x87,0x51,0x09,0x00,0x06,0x00 }},/* 05 (720x) */
2592 {{ 0x97,0x63,0x9B,0x65,0x1D,0x00,0x06,0xF0 }},/* 06 (800x) */
2593 {{ 0xB3,0x7F,0x97,0x81,0x99,0x00,0x02,0x00 }},/* 07 (1024x) */
2594 {{ 0xD3,0x9F,0x97,0xA1,0x19,0x00,0x07,0x00 }},/* 08 (1280x) */
2595 {{ 0xE2,0xAE,0x86,0xB9,0x91,0x00,0x03,0x00 }},/* 09 (1400x) */
2596 {{ 0xFB,0xC7,0x9F,0xC9,0x81,0x00,0x07,0x00 }} /* 0A (1600x) */
2597};
2598
2599XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[]=
2600{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
2601 {{ 0x97,0x1F,0x60,0x87,0x5D,0x83,0x10 }}, /* 00 (x350) */
2602 {{ 0xB4,0x1F,0x92,0x89,0x8F,0xB5,0x30 }}, /* 01 (x400) */
2603 {{ 0x04,0x3E,0xE2,0x89,0xDF,0x05,0x00 }}, /* 02 (x480) */
2604 {{ 0x7C,0xF0,0x5A,0x8F,0x57,0x7D,0xA0 }}, /* 03 (x600) */
2605 {{ 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90 }} /* 04 (x768) */
2606};
2607
2608XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[]=
2609{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
2610 {{ 0x24,0xBB,0x31,0x87,0x5D,0x25,0x30 }}, /* 00 (x350) */
2611 {{ 0x24,0xBB,0x4A,0x80,0x8F,0x25,0x30 }}, /* 01 (x400) */
2612 {{ 0x24,0xBB,0x72,0x88,0xDF,0x25,0x30 }}, /* 02 (x480) */
2613 {{ 0x24,0xF1,0xAE,0x84,0x57,0x25,0xB0 }}, /* 03 (x600) */
2614 {{ 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90 }} /* 04 (x768) */
2615};
2616
2617XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[]=
2618{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
2619 {{ 0x86,0x1F,0x5E,0x82,0x5D,0x87,0x00 }}, /* 00 (x350) */
2620 {{ 0xB8,0x1F,0x90,0x84,0x8F,0xB9,0x30 }}, /* 01 (x400) */
2621 {{ 0x08,0x3E,0xE0,0x84,0xDF,0x09,0x00 }}, /* 02 (x480) */
2622 {{ 0x80,0xF0,0x58,0x8C,0x57,0x81,0xA0 }}, /* 03 (x600) */
2623 {{ 0x28,0xF5,0x00,0x84,0xFF,0x29,0x90 }}, /* 04 (x768) */
2624 {{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* 05 (x1024) */
2625};
2626
2627XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[]=
2628{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
2629 {{ 0x28,0xD2,0xAF,0x83,0xAE,0xD8,0xA1 }}, /* 00 (x350) */
2630 {{ 0x28,0xD2,0xC8,0x8C,0xC7,0xF2,0x81 }}, /* 01 (x400) */
2631 {{ 0x28,0xD2,0xF0,0x84,0xEF,0x1A,0xB1 }}, /* 02 (x480) */
2632 {{ 0x28,0xDE,0x2C,0x8F,0x2B,0x56,0x91 }}, /* 03 (x600) */
2633 {{ 0x28,0xDE,0x80,0x83,0x7F,0xAA,0x91 }}, /* 04 (x768) */
2634 {{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* 05 (x1024) */
2635};
2636
2637XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[]=
2638{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
2639 {{ 0x6C,0x1F,0x60,0x84,0x5D,0x6D,0x10 }}, /* 00 (x350) */
2640 {{ 0x9E,0x1F,0x93,0x86,0x8F,0x9F,0x30 }}, /* 01 (x400) */
2641 {{ 0xEE,0x1F,0xE2,0x86,0xDF,0xEF,0x10 }}, /* 02 (x480) */
2642 {{ 0x66,0xF0,0x5A,0x8e,0x57,0x67,0xA0 }}, /* 03 (x600) */
2643 {{ 0x0E,0xF5,0x02,0x86,0xFF,0x0F,0x90 }}, /* 04 (x768) */
2644 {{ 0x0E,0x5A,0x02,0x86,0xFF,0x0F,0x89 }}, /* 05 (x1024) */
2645 {{ 0x28,0x10,0x1A,0x80,0x19,0x29,0x0F }} /* 06 (x1050) */
2646};
2647
2648XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[]=
2649{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
2650 {{ 0x28,0x92,0xB6,0x83,0xB5,0xCF,0x81 }}, /* 00 (x350) */
2651 {{ 0x28,0x92,0xD5,0x82,0xD4,0xEE,0x81 }}, /* 01 (x400) */
2652 {{ 0x28,0x92,0xFD,0x8A,0xFC,0x16,0xB1 }}, /* 02 (x480) */
2653 {{ 0x28,0xD4,0x39,0x86,0x57,0x29,0x81 }}, /* 03 (x600) */
2654 {{ 0x28,0xD4,0x8D,0x9A,0xFF,0x29,0xA1 }}, /* 04 (x768) */
2655 {{ 0x28,0x5A,0x0D,0x9A,0xFF,0x29,0xA9 }}, /* 05 (x1024) */
2656 {{ 0x28,0x10,0x1A,0x87,0x19,0x29,0x8F }} /* 06 (x1050) */
2657};
2658
2659XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[]=
2660{
2661 /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
2662 {{ 0xd4,0x1F,0x81,0x84,0x5D,0xd5,0x10 }}, /* 00 (x350) */
2663 {{ 0x06,0x3e,0xb3,0x86,0x8F,0x07,0x20 }}, /* 01 (x400) */
2664 {{ 0x56,0xba,0x03,0x86,0xDF,0x57,0x00 }}, /* 02 (x480) */
2665 {{ 0xce,0xF0,0x7b,0x8e,0x57,0xcf,0xa0 }}, /* 03 (x600) */
2666 {{ 0x76,0xF5,0x23,0x86,0xFF,0x77,0x90 }}, /* 04 (x768) */
2667 {{ 0x76,0x5A,0x23,0x86,0xFF,0x77,0x89 }}, /* 05 (x1024) */
2668 {{ 0x90,0x10,0x1A,0x8E,0x19,0x91,0x2F }}, /* 06 (x1050) */
2669 {{ 0x26,0x11,0xd3,0x86,0xaF,0x27,0x3f }} /* 07 (x1200) */
2670};
2671
2672XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[]=
2673{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2674 {{ 0x4B,0x27,0x8F,0x32,0x1B,0x00,0x45,0x00 }},/* ; 00 (320x) */
2675 {{ 0x4B,0x27,0x8F,0x2B,0x03,0x00,0x44,0x00 }},/* ; 01 (360x) */
2676 {{ 0x55,0x31,0x99,0x46,0x1D,0x00,0x55,0x00 }},/* ; 02 (400x) */
2677 {{ 0x63,0x3F,0x87,0x4A,0x93,0x00,0x01,0x00 }},/* ; 03 (512x) */
2678 {{ 0x6F,0x4F,0x93,0x54,0x80,0x00,0x05,0x00 }},/* ; 04 (640x) */
2679 {{ 0x6F,0x4F,0x93,0x54,0x80,0x00,0x05,0x00 }},/* ; 05 (720x) */
2680 {{ 0x83,0x63,0x87,0x68,0x14,0x00,0x26,0x00 }},/* ; 06 (800x) */
2681 {{ 0x9F,0x7F,0x83,0x85,0x91,0x00,0x02,0x00 }} /* ; 07 (1024x) */
2682};
2683
2684XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[]=
2685{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
2686 {{ 0x97,0x1F,0x60,0x87,0x5D,0x83,0x10 }},/* ; 00 (x350) */
2687 {{ 0xB4,0x1F,0x92,0x89,0x8F,0xB5,0x30 }},/* ; 01 (x400) */
2688 {{ 0xFE,0x1F,0xE0,0x84,0xDF,0xFF,0x10 }},/* ; 02 (x480) */
2689 {{ 0x76,0xF0,0x58,0x8C,0x57,0x77,0xA0 }},/* ; 03 (x600) */
2690 {{ 0x1E,0xF5,0x00,0x83,0xFF,0x1F,0x90 }} /* ; 04 (x768) */
2691};
2692
2693XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[]=
2694{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2695 {{ 0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }},/* ; 00 (320x) */
2696 {{ 0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }},/* ; 01 (360x) */
2697 {{ 0x63,0x31,0x87,0x3D,0x8E,0x00,0x01,0x00 }},/* ; 02 (400x) */
2698 {{ 0x63,0x3F,0x87,0x45,0x96,0x00,0x01,0x00 }},/* ; 03 (512x) */
2699 {{ 0xA3,0x4F,0x87,0x6E,0x9F,0x00,0x06,0x00 }},/* ; 04 (640x) */
2700 {{ 0xA3,0x4F,0x87,0x6E,0x9F,0x00,0x06,0x00 }},/* ; 05 (720x) */
2701 {{ 0xA3,0x63,0x87,0x78,0x89,0x00,0x02,0x00 }},/* ; 06 (800x) */
2702 {{ 0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* ; 07 (1024x) */
2703};
2704
2705XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[]=
2706{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
2707 {{ 0x24,0xBB,0x31,0x87,0x5D,0x25,0x30 }},/* ; 00 (x350) */
2708 {{ 0x24,0xBB,0x4A,0x80,0x8F,0x25,0x30 }},/* ; 01 (x400) */
2709 {{ 0x24,0xBB,0x72,0x88,0xDF,0x25,0x30 }},/* ; 02 (x480) */
2710 {{ 0x24,0xF1,0xAE,0x84,0x57,0x25,0xB0 }},/* ; 03 (x600) */
2711 {{ 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90 }} /* ; 04 (x768) */
2712};
2713
2714XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[]=
2715{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2716 {{ 0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }},/* ; 00 (320x) */
2717 {{ 0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }},/* ; 01 (360x) */
2718 {{ 0x60,0x31,0x84,0x3A,0x88,0x00,0x01,0x00 }},/* ; 02 (400x) */
2719 {{ 0x6E,0x3F,0x92,0x48,0x96,0x00,0x01,0x00 }},/* ; 03 (512x) */
2720 {{ 0x7E,0x4F,0x82,0x54,0x06,0x00,0x06,0x00 }},/* ; 04 (640x) */
2721 {{ 0x7E,0x4F,0x82,0x54,0x06,0x00,0x06,0x00 }},/* ; 05 (720x) */
2722 {{ 0x92,0x63,0x96,0x68,0x1A,0x00,0x06,0x00 }},/* ; 06 (800x) */
2723 {{ 0xAE,0x7F,0x92,0x84,0x96,0x00,0x02,0x00 }},/* ; 07 (1024x) */
2724 {{ 0xCE,0x9F,0x92,0xA5,0x17,0x00,0x07,0x00 }} /* ; 08 (1280x) */
2725};
2726
2727XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[]=
2728{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
2729 {{ 0x86,0xD1,0xBC,0x80,0xBB,0xE5,0x00 }},/* ; 00 (x350) */
2730 {{ 0xB8,0x1F,0x90,0x84,0x8F,0xB9,0x30 }},/* ; 01 (x400) */
2731 {{ 0x08,0x3E,0xE0,0x84,0xDF,0x09,0x00 }},/* ; 02 (x480) */
2732 {{ 0x80,0xF0,0x58,0x8C,0x57,0x81,0xA0 }},/* ; 03 (x600) */
2733 {{ 0x28,0xF5,0x00,0x84,0xFF,0x29,0x90 }},/* ; 04 (x768) */
2734 {{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* ; 05 (x1024) */
2735};
2736
2737XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[]=
2738{
2739 /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
2740 {{ 0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }},/* ; 00 (320x) */
2741 {{ 0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }},/* ; 01 (360x) */
2742 {{ 0x7E,0x40,0x84,0x49,0x91,0x00,0x01,0x00 }},/* ; 02 (400x) */
2743 {{ 0x7E,0x47,0x93,0x50,0x9E,0x00,0x01,0x00 }},/* ; 03 (512x) */
2744 {{ 0xCE,0x77,0x8A,0x80,0x8E,0x00,0x02,0x00 }},/* ; 04 (640x) */
2745 {{ 0xCE,0x77,0x8A,0x80,0x8E,0x00,0x02,0x00 }},/* ; 05 (720x) */
2746 {{ 0xCE,0x81,0x94,0x8A,0x98,0x00,0x02,0x00 }},/* ; 06 (800x) */
2747 {{ 0xCE,0x8F,0x82,0x98,0x06,0x00,0x07,0x00 }},/* ; 07 (1024x) */
2748 {{ 0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* ; 08 (1280x) */
2749};
2750
2751XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[]=
2752{
2753 /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
2754 {{ 0x28,0xD2,0xAF,0x83,0xAE,0xD8,0xA1 }},/* ; 00 (x350) */
2755 {{ 0x28,0xD2,0xC8,0x8C,0xC7,0xF2,0x81 }},/* ; 01 (x400) */
2756 {{ 0x28,0xD2,0xF0,0x84,0xEF,0x1A,0xB1 }},/* ; 02 (x480) */
2757 {{ 0x28,0xDE,0x2C,0x8F,0x2B,0x56,0x91 }},/* ; 03 (x600) */
2758 {{ 0x28,0xDE,0x80,0x83,0x7F,0xAA,0x91 }},/* ; 04 (x768) */
2759 {{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* ; 05 (x1024) */
2760};
2761
2762XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UNTSC[]=
2763{
2764 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2765 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
2766 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2767 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,0x00 }},
2768 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2769 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
2770 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2771 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,0x00 }},
2772 {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
2773 0x18,0x84,0xdf,0x57,0x00,0x00,0x01,0x00 }},
2774 {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
2775 0x90,0x8c,0x57,0xed,0x20,0x00,0x06,0x01 }}
2776};
2777
2778XGI_LVDSCRT1DataStruct XGI_CHTVCRT1ONTSC[]=
2779{
2780 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
2781 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
2782 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
2783 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,0x00 }},
2784 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
2785 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
2786 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
2787 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,0x00 }},
2788 {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
2789 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,0x00 }},
2790 {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
2791 0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,0x01 }}
2792};
2793
2794XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UPAL[]=
2795{
2796 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2797 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
2798 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2799 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
2800 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2801 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
2802 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2803 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
2804 {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
2805 0x50,0x84,0xdf,0xed,0x00,0x00,0x05,0x00 }},
2806 {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
2807 0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,0x01 }}
2808};
2809
2810XGI_LVDSCRT1DataStruct XGI_CHTVCRT1OPAL[]=
2811{
2812 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2813 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
2814 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2815 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
2816 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2817 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
2818 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2819 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
2820 {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
2821 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,0x00 }},
2822 {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
2823 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,0x01 }}
2824};
2825
2826/*add for new UNIVGABIOS*/
2827XGI330_LCDDataTablStruct XGI_LCDDataTable[]=
2828{
2829 {Panel1024x768,0x0019,0x0001,0}, /* XGI_ExtLCD1024x768Data */
2830 {Panel1024x768,0x0019,0x0000,1}, /* XGI_StLCD1024x768Data */
2831 {Panel1024x768,0x0018,0x0010,2}, /* XGI_CetLCD1024x768Data */
2832 {Panel1280x1024,0x0019,0x0001,3}, /* XGI_ExtLCD1280x1024Data */
2833 {Panel1280x1024,0x0019,0x0000,4}, /* XGI_StLCD1280x1024Data */
2834 {Panel1280x1024,0x0018,0x0010,5}, /* XGI_CetLCD1280x1024Data */
2835 {Panel1400x1050,0x0019,0x0001,6}, /* XGI_ExtLCD1400x1050Data */
2836 {Panel1400x1050,0x0019,0x0000,7}, /* XGI_StLCD1400x1050Data */
2837 {Panel1400x1050,0x0018,0x0010,8}, /* XGI_CetLCD1400x1050Data */
2838 {Panel1600x1200,0x0019,0x0001,9}, /* XGI_ExtLCD1600x1200Data */
2839 {Panel1600x1200,0x0019,0x0000,10}, /* XGI_StLCD1600x1200Data */
2840 {PanelRef60Hz,0x0008,0x0008,11}, /* XGI_NoScalingData */
2841 {Panel1024x768x75,0x0019,0x0001,12}, /* XGI_ExtLCD1024x768x75Data */
2842 {Panel1024x768x75,0x0019,0x0000,13}, /* XGI_StLCD1024x768x75Data */
2843 {Panel1024x768x75,0x0018,0x0010,14}, /* XGI_CetLCD1024x768x75Data */
2844 {Panel1280x1024x75,0x0019,0x0001,15}, /* XGI_ExtLCD1280x1024x75Data */
2845 {Panel1280x1024x75,0x0019,0x0000,16}, /* XGI_StLCD1280x1024x75Data */
2846 {Panel1280x1024x75,0x0018,0x0010,17}, /* XGI_CetLCD1280x1024x75Data */
2847 {PanelRef75Hz,0x0008,0x0008,18}, /* XGI_NoScalingDatax75 */
2848 {0xFF,0x0000,0x0000,0} /* End of table */
2849};
2850
2851XGI330_LCDDataTablStruct XGI_LCDDesDataTable[]=
2852{
2853 {Panel1024x768,0x0019,0x0001,0}, /* XGI_ExtLCDDes1024x768Data */
2854 {Panel1024x768,0x0019,0x0000,1}, /* XGI_StLCDDes1024x768Data */
2855 {Panel1024x768,0x0018,0x0010,2}, /* XGI_CetLCDDes1024x768Data */
2856 {Panel1280x1024,0x0019,0x0001,3}, /* XGI_ExtLCDDes1280x1024Data */
2857 {Panel1280x1024,0x0019,0x0000,4}, /* XGI_StLCDDes1280x1024Data */
2858 {Panel1280x1024,0x0018,0x0010,5}, /* XGI_CetLCDDes1280x1024Data */
2859 {Panel1400x1050,0x0019,0x0001,6}, /* XGI_ExtLCDDes1400x1050Data */
2860 {Panel1400x1050,0x0019,0x0000,7}, /* XGI_StLCDDes1400x1050Data */
2861 {Panel1400x1050,0x0418,0x0010,8}, /* XGI_CetLCDDes1400x1050Data */
2862 {Panel1400x1050,0x0418,0x0410,9}, /* XGI_CetLCDDes1400x1050Data2 */
2863 {Panel1600x1200,0x0019,0x0001,10}, /* XGI_ExtLCDDes1600x1200Data */
2864 {Panel1600x1200,0x0019,0x0000,11}, /* XGI_StLCDDes1600x1200Data */
2865 {PanelRef60Hz,0x0008,0x0008,12}, /* XGI_NoScalingDesData */
2866 {Panel1024x768x75,0x0019,0x0001,13}, /* XGI_ExtLCDDes1024x768x75Data */
2867 {Panel1024x768x75,0x0019,0x0000,14}, /* XGI_StLCDDes1024x768x75Data */
2868 {Panel1024x768x75,0x0018,0x0010,15}, /* XGI_CetLCDDes1024x768x75Data */
2869 {Panel1280x1024x75,0x0019,0x0001,16}, /* XGI_ExtLCDDes1280x1024x75Data */
2870 {Panel1280x1024x75,0x0019,0x0000,17}, /* XGI_StLCDDes1280x1024x75Data */
2871 {Panel1280x1024x75,0x0018,0x0010,18}, /* XGI_CetLCDDes1280x1024x75Data */
2872 {PanelRef75Hz,0x0008,0x0008,19}, /* XGI_NoScalingDesDatax75 */
2873 {0xFF,0x0000,0x0000,0}
2874};
2875
2876XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[]=
2877{
2878 {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDSCRT11024x768_1_H */
2879 {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDSCRT11024x768_2_H */
2880 {Panel1280x1024,0x0018,0x0000,2}, /* XGI_LVDSCRT11280x1024_1_H */
2881 {Panel1280x1024,0x0018,0x0010,3}, /* XGI_LVDSCRT11280x1024_2_H */
2882 {Panel1400x1050,0x0018,0x0000,4}, /* XGI_LVDSCRT11400x1050_1_H */
2883 {Panel1400x1050,0x0018,0x0010,5}, /* XGI_LVDSCRT11400x1050_2_H */
2884 {Panel1600x1200,0x0018,0x0000,6}, /* XGI_LVDSCRT11600x1200_1_H */
2885 {Panel1024x768x75,0x0018,0x0000,7}, /* XGI_LVDSCRT11024x768_1_Hx75 */
2886 {Panel1024x768x75,0x0018,0x0010,8}, /* XGI_LVDSCRT11024x768_2_Hx75 */
2887 {Panel1280x1024x75,0x0018,0x0000,9}, /* XGI_LVDSCRT11280x1024_1_Hx75 */
2888 {Panel1280x1024x75,0x0018,0x0010,10}, /* XGI_LVDSCRT11280x1024_2_Hx75 */
2889 {0xFF,0x0000,0x0000,0}
2890};
2891
2892XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[]=
2893{
2894 {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDSCRT11024x768_1_V */
2895 {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDSCRT11024x768_2_V */
2896 {Panel1280x1024,0x0018,0x0000,2}, /* XGI_LVDSCRT11280x1024_1_V */
2897 {Panel1280x1024,0x0018,0x0010,3}, /* XGI_LVDSCRT11280x1024_2_V */
2898 {Panel1400x1050,0x0018,0x0000,4}, /* XGI_LVDSCRT11400x1050_1_V */
2899 {Panel1400x1050,0x0018,0x0010,5}, /* XGI_LVDSCRT11400x1050_2_V */
2900 {Panel1600x1200,0x0018,0x0000,6}, /* XGI_LVDSCRT11600x1200_1_V */
2901 {Panel1024x768x75,0x0018,0x0000,7}, /* XGI_LVDSCRT11024x768_1_Vx75 */
2902 {Panel1024x768x75,0x0018,0x0010,8}, /* XGI_LVDSCRT11024x768_2_Vx75 */
2903 {Panel1280x1024x75,0x0018,0x0000,9}, /* XGI_LVDSCRT11280x1024_1_Vx75 */
2904 {Panel1280x1024x75,0x0018,0x0010,10}, /* XGI_LVDSCRT11280x1024_2_Vx75 */
2905 {0xFF,0x0000,0x0000,0}
2906};
2907
2908XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[]=
2909{
2910 {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDS1024x768Data_1 */
2911 {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDS1024x768Data_2 */
2912 {Panel1280x1024,0x0018,0x0000,2}, /* XGI_LVDS1280x1024Data_1 */
2913 {Panel1280x1024,0x0018,0x0010,3}, /* XGI_LVDS1280x1024Data_2 */
2914 {Panel1400x1050,0x0018,0x0000,4}, /* XGI_LVDS1400x1050Data_1 */
2915 {Panel1400x1050,0x0018,0x0010,5}, /* XGI_LVDS1400x1050Data_2 */
2916 {Panel1600x1200,0x0018,0x0000,6}, /* XGI_LVDS1600x1200Data_1 */
2917 {PanelRef60Hz,0x0008,0x0008,7}, /* XGI_LVDSNoScalingData */
2918 {Panel1024x768x75,0x0018,0x0000,8}, /* XGI_LVDS1024x768Data_1x75 */
2919 {Panel1024x768x75,0x0018,0x0010,9}, /* XGI_LVDS1024x768Data_2x75 */
2920 {Panel1280x1024x75,0x0018,0x0000,10}, /* XGI_LVDS1280x1024Data_1x75 */
2921 {Panel1280x1024x75,0x0018,0x0010,11}, /* XGI_LVDS1280x1024Data_2x75 */
2922 {PanelRef75Hz,0x0008,0x0008,12}, /* XGI_LVDSNoScalingDatax75 */
2923 {0xFF,0x0000,0x0000,0}
2924};
2925
2926XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[]=
2927{
2928 {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDS1024x768Des_1 */
2929 {Panel1024x768,0x0618,0x0410,1}, /* XGI_LVDS1024x768Des_3 */
2930 {Panel1024x768,0x0018,0x0010,2}, /* XGI_LVDS1024x768Des_2 */
2931 {Panel1280x1024,0x0018,0x0000,3}, /* XGI_LVDS1280x1024Des_1 */
2932 {Panel1280x1024,0x0018,0x0010,4}, /* XGI_LVDS1280x1024Des_2 */
2933 {Panel1400x1050,0x0018,0x0000,5}, /* XGI_LVDS1400x1050Des_1 */
2934 {Panel1400x1050,0x0018,0x0010,6}, /* XGI_LVDS1400x1050Des_2 */
2935 {Panel1600x1200,0x0018,0x0000,7}, /* XGI_LVDS1600x1200Des_1 */
2936 {PanelRef60Hz,0x0008,0x0008,8}, /* XGI_LVDSNoScalingDesData */
2937 {Panel1024x768x75,0x0018,0x0000,9}, /* XGI_LVDS1024x768Des_1x75 */
2938 {Panel1024x768x75,0x0618,0x0410,10}, /* XGI_LVDS1024x768Des_3x75 */
2939 {Panel1024x768x75,0x0018,0x0010,11}, /* XGI_LVDS1024x768Des_2x75 */
2940 {Panel1280x1024x75,0x0018,0x0000,12}, /* XGI_LVDS1280x1024Des_1x75 */
2941 {Panel1280x1024x75,0x0018,0x0010,13}, /* XGI_LVDS1280x1024Des_2x75 */
2942 {PanelRef75Hz,0x0008,0x0008,14}, /* XGI_LVDSNoScalingDesDatax75 */
2943 {0xFF,0x0000,0x0000,0}
2944};
2945
2946XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[]=
2947{
2948 {Panel1024x768,0x0000,0x0000,0}, /* XGI_CH7017LV1024x768 */
2949 {Panel1400x1050,0x0000,0x0000,1}, /* XGI_CH7017LV1400x1050 */
2950 {0xFF,0x0000,0x0000,0}
2951};
2952
2953XGI330_TVDataTablStruct XGI_TVDataTable[]=
2954{
2955 {0x09E1,0x0001,0}, /* XGI_ExtPALData */
2956 {0x09E1,0x0000,1}, /* XGI_ExtNTSCData */
2957 {0x09E1,0x0801,2}, /* XGI_StPALData */
2958 {0x09E1,0x0800,3}, /* XGI_StNTSCData */
2959 {0x49E0,0x0100,4}, /* XGI_ExtHiTVData */
2960 {0x49E0,0x4100,5}, /* XGI_St2HiTVData */
2961 {0x49E0,0x4900,13}, /* XGI_St1HiTVData */
2962 {0x09E0,0x0020,6}, /* XGI_ExtYPbPr525iData */
2963 {0x09E0,0x0040,7}, /* XGI_ExtYPbPr525pData */
2964 {0x09E0,0x0080,8}, /* XGI_ExtYPbPr750pData */
2965 {0x09E0,0x0820,9}, /* XGI_StYPbPr525iData */
2966 {0x09E0,0x0840,10}, /* XGI_StYPbPr525pData */
2967 {0x09E0,0x0880,11}, /* XGI_StYPbPr750pData */
2968 {0xffff,0x0000,12} /* END */
2969};
2970
2971USHORT TVLenList[]=
2972{
2973 LVDSCRT1Len_H,
2974 LVDSCRT1Len_V,
2975 LVDSDataLen,
2976 0,
2977 TVDataLen,
2978 0,
2979 0,
2980 CHTVRegLen
2981} ;
2982
2983/* Chrontel 7017 TV CRT1 Timing List */
2984XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[]=
2985{
2986 {0x0011,0x0000,0}, /* XGI_CHTVCRT1UNTSC */
2987 {0x0011,0x0010,1}, /* XGI_CHTVCRT1ONTSC */
2988 {0x0011,0x0001,2}, /* XGI_CHTVCRT1UPAL */
2989 {0x0011,0x0011,3}, /* XGI_CHTVCRT1OPAL */
2990 {0xFFFF,0x0000,4}
2991};
2992
2993/* ;;Chrontel 7017 TV Timing List */
2994XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[]=
2995{
2996 {0x0011,0x0000,0}, /* XGI_CHTVUNTSCData */
2997 {0x0011,0x0010,1}, /* XGI_CHTVONTSCData */
2998 {0x0011,0x0001,2}, /* XGI_CHTVUPALData */
2999 {0x0011,0x0011,3}, /* XGI_CHTVOPALData */
3000 {0xFFFF,0x0000,4}
3001};
3002
3003/* ;;Chrontel 7017 TV Reg. List */
3004XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[]=
3005{
3006 {0x0011,0x0000,0}, /* XGI_CHTVRegUNTSC */
3007 {0x0011,0x0010,1}, /* XGI_CHTVRegONTSC */
3008 {0x0011,0x0001,2}, /* XGI_CHTVRegUPAL */
3009 {0x0011,0x0011,3}, /* XGI_CHTVRegOPAL */
3010 {0xFFFF,0x0000,4}
3011};
3012
3013USHORT LCDLenList[]=
3014{
3015 LVDSCRT1Len_H,
3016 LVDSCRT1Len_V,
3017 LVDSDataLen,
3018 LCDDesDataLen,
3019 LCDDataLen,
3020 LCDDesDataLen,
3021 0,
3022 LCDDesDataLen,
3023 LCDDesDataLen,
3024 0
3025} ;
3026
3027XGI330_LCDCapStruct XGI660_LCDDLCapList[]= /* 660, Dual link */
3028{
3029/* LCDCap1024x768 */
3030 {Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
3031 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
3032 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
3033/* LCDCap1280x1024 */
3034 {Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
3035 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
3036 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3037/* LCDCap1400x1050 */
3038 {Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
3039 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
3040 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3041/* LCDCap1600x1200 */
3042 {Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull, 0x053, 0xC0, 0x03, VCLK162,
3043 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00,
3044 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3045/* LCDCap1024x768x75 */
3046 {Panel1024x768x75, DefaultLCDCap, 0, 0x014, 0x60, 0, VCLK78_75,
3047 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
3048 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
3049/* LCDCap1280x1024x75 */
3050 {Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x053, 0x90, 0x03, VCLK135_5,
3051 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
3052 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3053/* LCDCapDefault */
3054 {0xFF, DefaultLCDCap, 0, 0x053, 0x88, 0x06, VCLK65,
3055 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
3056 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
3057};
3058
3059XGI330_LCDCapStruct XGI_LCDDLCapList[]= /* Dual link only */
3060{
3061/* LCDCap1024x768 */
3062 {Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
3063 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
3064 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
3065/* LCDCap1280x1024 */
3066 {Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2,
3067 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
3068 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3069/* LCDCap1400x1050 */
3070 {Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2,
3071 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
3072 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3073/* LCDCap1600x1200 */
3074 {Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull, 0x012, 0xC0, 0x03, VCLK162,
3075 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00,
3076 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3077/* LCDCap1024x768x75 */
3078 {Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
3079 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
3080 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
3081/* LCDCap1280x1024x75 */
3082 {Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x90, 0x03, VCLK135_5,
3083 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
3084 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3085/* LCDCapDefault */
3086 {0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
3087 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
3088 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
3089};
3090
3091XGI330_LCDCapStruct XGI660_LCDCapList[]=
3092{
3093/* LCDCap1024x768 */
3094 {Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
3095 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
3096 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
3097/* LCDCap1280x1024 */
3098 {Panel1280x1024, DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
3099 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
3100 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3101/* LCDCap1400x1050 */
3102 {Panel1400x1050, DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
3103 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
3104 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3105/* LCDCap1600x1200 */
3106 {Panel1600x1200, DefaultLCDCap, LCDToFull, 0x053, 0xC0, 0x03, VCLK162,
3107 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00,
3108 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3109/* LCDCap1024x768x75 */
3110 {Panel1024x768x75, DefaultLCDCap, 0, 0x014, 0x60, 0, VCLK78_75,
3111 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
3112 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
3113/* LCDCap1280x1024x75 */
3114 {Panel1280x1024x75,+DefaultLCDCap, StLCDBToA, 0x053, 0x90, 0x03, VCLK135_5,
3115 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
3116 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3117/* LCDCapDefault */
3118 {0xFF, DefaultLCDCap, 0, 0x053, 0x88, 0x06, VCLK65,
3119 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
3120 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
3121};
3122
3123XGI330_LCDCapStruct XGI_LCDCapList[]=
3124{
3125/* LCDCap1024x768 */
3126 {Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
3127 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
3128 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
3129/* LCDCap1280x1024 */
3130 {Panel1280x1024, DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2,
3131 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
3132 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3133/* LCDCap1400x1050 */
3134 {Panel1400x1050, DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2,
3135 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
3136 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3137/* LCDCap1600x1200 */
3138 {Panel1600x1200, DefaultLCDCap, LCDToFull, 0x012, 0xC0, 0x03, VCLK162,
3139 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00,
3140 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3141/* LCDCap1024x768x75 */
3142 {Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
3143 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
3144 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
3145/* LCDCap1280x1024x75 */
3146 {Panel1280x1024x75, DefaultLCDCap, StLCDBToA, 0x012, 0x90, 0x03, VCLK135_5,
3147 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
3148 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
3149/* LCDCapDefault */
3150 {0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
3151 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
3152 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
3153};
3154
3155XGI21_LVDSCapStruct XGI21_LCDCapList[]=
3156{
3157 {DisableLCD24bpp + LCDPolarity,
3158 2160,1250,1600,1200, 64, 1, 192, 3,
3159 0x70,0x24,0x20,0x04,0x0A,0x02,0xC8
3160 },
3161 {DisableLCD24bpp + LCDPolarity,
3162 1688,1066,1280,1024, 48, 1, 112, 3,
3163 0x70,0x44,0x20,0x04,0x0A,0x02,0xC8
3164 },
3165 {DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
3166 1344, 806,1024, 768, 24, 3, 136, 6,
3167 0x6C,0x65,0x20,0x04,0x0A,0x02,0xC8
3168 },
3169 {DisableLCD24bpp + LCDPolarity,
3170 1056, 628, 800, 600, 40, 1, 128, 4,
3171 0x42,0xE2,0x20,0x14,0x0A,0x02,0x00
3172 },
3173 {DisableLCD24bpp + LCDPolarity,
3174 928, 525, 800, 480, 40, 13, 48, 3,
3175 0x52,0xC5,0x20,0x14,0x0A,0x02,0x00
3176 },
3177 {DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
3178 800, 525, 640, 480, 16, 10, 96, 2,
3179 0x1B,0xE1,0x20,0x04,0x0A,0x02,0xC8
3180 }
3181
3182};
3183
3184XGI_Ext2Struct XGI330_RefIndex[]=
3185{
3186{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00,0x10,0x59, 320, 200},/* 00 */
3187{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00,0x10,0x00, 320, 400},/* 01 */
3188{Support32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175, 0x04,0x20,0x50, 320, 240},/* 02 */
3189{Support32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40, 0x05,0x32,0x51, 400, 300},/* 03 */
3190{Support32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384, VCLK65, 0x06,0x43,0x52, 512, 384},/* 04 */
3191{Support32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175, 0x00,0x14,0x2f, 640, 400},/* 05 */
3192{Support32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175, 0x04,0x24,0x2e, 640, 480},/* 06 640x480x60Hz (LCD 640x480x60z) */
3193{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5, 0x04,0x24,0x2e, 640, 480},/* 07 640x480x72Hz (LCD 640x480x70Hz) */
3194{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5, 0x47,0x24,0x2e, 640, 480},/* 08 640x480x75Hz (LCD 640x480x75Hz) */
3195{Support32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36, 0x8A,0x24,0x2e, 640, 480},/* 09 640x480x85Hz */
3196{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163, 0x00,0x24,0x2e, 640, 480},/* 0a 640x480x100Hz */
3197{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406, 0x00,0x24,0x2e, 640, 480},/* 0b 640x480x120Hz */
3198{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852, 0x00,0x24,0x2e, 640, 480},/* 0c 640x480x160Hz */
3199{Support32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6, 0x00,0x24,0x2e, 640, 480},/* 0d 640x480x200Hz */
3200{Support32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36, 0x05,0x36,0x6a, 800, 600},/* 0e 800x600x56Hz */
3201{Support32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40, 0x05,0x36,0x6a, 800, 600},/* 0f 800x600x60Hz (LCD 800x600x60Hz) */
3202{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50, 0x48,0x36,0x6a, 800, 600},/* 10 800x600x72Hz (LCD 800x600x70Hz) */
3203{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5, 0x8B,0x36,0x6a, 800, 600},/* 11 800x600x75Hz (LCD 800x600x75Hz) */
3204{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25, 0x00,0x36,0x6a, 800, 600},/* 12 800x600x85Hz */
3205{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179, 0x00,0x36,0x6a, 800, 600},/* 13 800x600x100Hz */
3206{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95, 0x00,0x36,0x6a, 800, 600},/* 14 800x600x120Hz */
3207{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406,0x00,0x36,0x6a, 800, 600},/* 15 800x600x160Hz */
3208{Support32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9, 0x00,0x47,0x37,1024, 768},/* 16 1024x768x43Hz */
3209{Support32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60, VCLK65, 0x06,0x47,0x37,1024, 768},/* 17 1024x768x60Hz (LCD 1024x768x60Hz) */
3210{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75, 0x49,0x47,0x37,1024, 768},/* 18 1024x768x70Hz (LCD 1024x768x70Hz) */
3211{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75, 0x00,0x47,0x37,1024, 768},/* 19 1024x768x75Hz (LCD 1024x768x75Hz) */
3212{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5, 0x8C,0x47,0x37,1024, 768},/* 1a 1024x768x85Hz */
3213{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309,0x00,0x47,0x37,1024, 768},/* 1b 1024x768x100Hz */
3214{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054,0x00,0x47,0x37,1024, 768},/* 1c 1024x768x120Hz */
3215{Support32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2, 0x08,0x58,0x7b,1280, 960},/* 1d 1280x960x60Hz */
3216{Support32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75, 0x00,0x58,0x3a,1280,1024},/* 1e 1280x1024x43Hz */
3217{Support32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2, 0x07,0x58,0x3a,1280,1024},/* 1f 1280x1024x60Hz (LCD 1280x1024x60Hz) */
3218{Support32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5, 0x00,0x58,0x3a,1280,1024},/* 20 1280x1024x75Hz (LCD 1280x1024x75Hz) */
3219{Support32Bpp + SyncPP, RES1280x1024x85, VCLK157_5, 0x00,0x58,0x3a,1280,1024},/* 21 1280x1024x85Hz */
3220{Support32Bpp + SupportLCD + SyncPP + SupportCRT2in301C, RES1600x1200x60, VCLK162, 0x09,0x7A,0x3c,1600,1200},/* 22 1600x1200x60Hz */
3221{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175, 0x00,0x69,0x3c,1600,1200},/* 23 1600x1200x65Hz */
3222{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189, 0x00,0x69,0x3c,1600,1200},/* 24 1600x1200x70Hz */
3223{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5, 0x00,0x69,0x3c,1600,1200},/* 25 1600x1200x75Hz */
3224{Support32Bpp + SyncPP, RES1600x1200x85, VCLK229_5, 0x00,0x69,0x3c,1600,1200},/* 26 1600x1200x85Hz */
3225{Support32Bpp + SyncPP, RES1600x1200x100,VCLK269_655,0x00,0x69,0x3c,1600,1200},/* 27 1600x1200x100Hz */
3226{Support32Bpp + SyncPP, RES1600x1200x120,VCLK323_586,0x00,0x69,0x3c,1600,1200},/* 28 1600x1200x120Hz */
3227{Support32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234, 0x00,0x00,0x68,1920,1440},/* 29 1920x1440x60Hz */
3228{Support32Bpp + SyncPN, RES1920x1440x65, VCLK254_817,0x00,0x00,0x68,1920,1440},/* 2a 1920x1440x65Hz */
3229{Support32Bpp + SyncPN, RES1920x1440x70, VCLK277_015,0x00,0x00,0x68,1920,1440},/* 2b 1920x1440x70Hz */
3230{Support32Bpp + SyncPN, RES1920x1440x75, VCLK291_132,0x00,0x00,0x68,1920,1440},/* 2c 1920x1440x75Hz */
3231{Support32Bpp + SyncPN, RES1920x1440x85, VCLK330_615,0x00,0x00,0x68,1920,1440},/* 2d 1920x1440x85Hz */
3232{Support16Bpp + SyncPN, RES1920x1440x100,VCLK388_631,0x00,0x00,0x68,1920,1440},/* 2e 1920x1440x100Hz */
3233{Support32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952,0x00,0x00,0x6c,2048,1536},/* 2f 2048x1536x60Hz */
3234{Support32Bpp + SyncPN, RES2048x1536x65, VCLK291_766,0x00,0x00,0x6c,2048,1536},/* 30 2048x1536x65Hz */
3235{Support32Bpp + SyncPN, RES2048x1536x70, VCLK315_195,0x00,0x00,0x6c,2048,1536},/* 31 2048x1536x70Hz */
3236{Support32Bpp + SyncPN, RES2048x1536x75, VCLK340_477,0x00,0x00,0x6c,2048,1536},/* 32 2048x1536x75Hz */
3237{Support16Bpp + SyncPN, RES2048x1536x85, VCLK375_847,0x00,0x00,0x6c,2048,1536},/* 33 2048x1536x85Hz */
3238{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + SyncPP + SupportYPbPr, RES800x480x60, VCLK39_77, 0x08,0x00,0x70, 800, 480},/* 34 800x480x60Hz */
3239{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5, 0x08,0x00,0x70, 800, 480},/* 35 800x480x75Hz */
3240{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25, 0x08,0x00,0x70, 800, 480},/* 36 800x480x85Hz */
3241{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + SyncPP + SupportYPbPr, RES1024x576x60, VCLK65, 0x09,0x00,0x71,1024, 576},/* 37 1024x576x60Hz */
3242{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75, 0x09,0x00,0x71,1024, 576},/* 38 1024x576x75Hz */
3243{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5, 0x09,0x00,0x71,1024, 576},/* 39 1024x576x85Hz */
3244{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + SyncPP + SupportYPbPr, RES1280x720x60, VCLK108_2, 0x0A,0x00,0x75,1280, 720},/* 3a 1280x720x60Hz */
3245{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5, 0x0A,0x00,0x75,1280, 720},/* 3b 1280x720x75Hz */
3246{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5, 0x0A,0x00,0x75,1280, 720},/* 3c 1280x720x85Hz */
3247{Support32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322, 0x06,0x00,0x31, 720, 480},/* 3d 720x480x60Hz */
3248{Support32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36, 0x06,0x00,0x32, 720, 576},/* 3e 720x576x56Hz */
3249{Support32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I, VCLK35_2, 0x00,0x00,0x00, 856, 480},/* 3f 856x480x79I */
3250{Support32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2, 0x00,0x00,0x00, 856, 480},/* 40 856x480x60Hz */
3251{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60, VCLK79_411, 0x08,0x48,0x23,1280, 768},/* 41 1280x768x60Hz */
3252{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60, VCLK122_61, 0x08,0x69,0x26,1400,1050},/* 42 1400x1050x60Hz */
3253{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350, 0x37,0x00,0x20,1152, 864},/* 43 1152x864x60Hz */
3254{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385,0x37,0x00,0x20,1152, 864},/* 44 1152x864x75Hz */
3255{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75, VCLK125_999,0x3A,0x88,0x7b,1280, 960},/* 45 1280x960x75Hz */
3256{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85, VCLK148_5, 0x0A,0x88,0x7b,1280, 960},/* 46 1280x960x85Hz */
3257{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120, VCLK217_325,0x3A,0x88,0x7b,1280, 960},/* 47 1280x960x120Hz */
3258{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054,0x30,0x47,0x37,1024, 768},/* 48 1024x768x160Hz */
3259};
3260
3261
3262
3263XGI330_VCLKDataStruct XGI330_VCLKData[]=
3264{
3265 { 0x1b,0xe1, 25}, /* 0x0 */
3266 { 0x4e,0xe4, 28}, /* 0x1 */
3267 { 0x57,0xe4, 31}, /* 0x2 */
3268 { 0xc3,0xc8, 36}, /* 0x3 */
3269 { 0x42,0xe2, 40}, /* 0x4 */
3270 { 0xfe,0xcd, 43}, /* 0x5 */
3271 { 0x5d,0xc4, 44}, /* 0x6 */
3272 { 0x52,0xe2, 49}, /* 0x7 */
3273 { 0x53,0xe2, 50}, /* 0x8 */
3274 { 0x74,0x67, 52}, /* 0x9 */
3275 { 0x6d,0x66, 56}, /* 0xa */
3276 { 0x6c,0xc3, 65}, /* 0xb */
3277 { 0x46,0x44, 67}, /* 0xc */
3278 { 0xb1,0x46, 68}, /* 0xd */
3279 { 0xd3,0x4a, 72}, /* 0xe */
3280 { 0x29,0x61, 75}, /* 0xf */
3281 { 0x6e,0x46, 76}, /* 0x10 */
3282 { 0x2b,0x61, 78}, /* 0x11 */
3283 { 0x31,0x42, 79}, /* 0x12 */
3284 { 0xab,0x44, 83}, /* 0x13 */
3285 { 0x46,0x25, 84}, /* 0x14 */
3286 { 0x78,0x29, 86}, /* 0x15 */
3287 { 0x62,0x44, 94}, /* 0x16 */
3288 { 0x2b,0x41,104}, /* 0x17 */
3289 { 0x3a,0x23,105}, /* 0x18 */
3290 { 0x70,0x44,108}, /* 0x19 */
3291 { 0x3c,0x23,109}, /* 0x1a */
3292 { 0x5e,0x43,113}, /* 0x1b */
3293 { 0xbc,0x44,116}, /* 0x1c */
3294 { 0xe0,0x46,132}, /* 0x1d */
3295 { 0x54,0x42,135}, /* 0x1e */
3296 { 0xea,0x2a,139}, /* 0x1f */
3297 { 0x41,0x22,157}, /* 0x20 */
3298 { 0x70,0x24,162}, /* 0x21 */
3299 { 0x30,0x21,175}, /* 0x22 */
3300 { 0x4e,0x22,189}, /* 0x23 */
3301 { 0xde,0x26,194}, /* 0x24 */
3302 { 0x62,0x06,202}, /* 0x25 */
3303 { 0x3f,0x03,229}, /* 0x26 */
3304 { 0xb8,0x06,234}, /* 0x27 */
3305 { 0x34,0x02,253}, /* 0x28 */
3306 { 0x58,0x04,255}, /* 0x29 */
3307 { 0x24,0x01,265}, /* 0x2a */
3308 { 0x9b,0x02,267}, /* 0x2b */
3309 { 0x70,0x05,270}, /* 0x2c */
3310 { 0x25,0x01,272}, /* 0x2d */
3311 { 0x9c,0x02,277}, /* 0x2e */
3312 { 0x27,0x01,286}, /* 0x2f */
3313 { 0x3c,0x02,291}, /* 0x30 */
3314 { 0xef,0x0a,292}, /* 0x31 */
3315 { 0xf6,0x0a,310}, /* 0x32 */
3316 { 0x95,0x01,315}, /* 0x33 */
3317 { 0xf0,0x09,324}, /* 0x34 */
3318 { 0xfe,0x0a,331}, /* 0x35 */
3319 { 0xf3,0x09,332}, /* 0x36 */
3320 { 0xea,0x08,340}, /* 0x37 */
3321 { 0xe8,0x07,376}, /* 0x38 */
3322 { 0xde,0x06,389}, /* 0x39 */
3323 { 0x52,0x2a, 54}, /* 0x3a */
3324 { 0x52,0x6a, 27}, /* 0x3b */
3325 { 0x62,0x24, 70}, /* 0x3c */
3326 { 0x62,0x64, 70}, /* 0x3d */
3327 { 0xa8,0x4c, 30}, /* 0x3e */
3328 { 0x20,0x26, 33}, /* 0x3f */
3329 { 0x31,0xc2, 39}, /* 0x40 */
3330 { 0x60,0x36, 30}, /* 0x41 */
3331 { 0x40,0x4A, 28}, /* 0x42 */
3332 { 0x9F,0x46, 44}, /* 0x43 */
3333 { 0x97,0x2C, 26}, /* 0x44 */
3334 { 0x44,0xE4, 25}, /* 0x45 */
3335 { 0x7E,0x32, 47}, /* 0x46 */
3336 { 0x08,0x24, 31}, /* 0x47 */
3337 { 0x97,0x2c, 26}, /* 0x48 */
3338 { 0xCE,0x3c, 39}, /* 0x49 */
3339 { 0x52,0x4A, 36}, /* 0x4a */
3340 { 0x2C,0x61, 95}, /* 0x4b */
3341 { 0x78,0x27,108}, /* 0x4c */
3342 { 0x66,0x43,123}, /* 0x4d */
3343 { 0x2c,0x61, 80}, /* 0x4e */
3344 { 0x3b,0x61,108} /* 0x4f */
3345};
3346
3347XGI_VBVCLKDataStruct XGI330_VBVCLKData[]=
3348{
3349 { 0x1b,0xe1, 25}, /* 0x0 */
3350 { 0x4e,0xe4, 28}, /* 0x1 */
3351 { 0x57,0xe4, 31}, /* 0x2 */
3352 { 0xc3,0xc8, 36}, /* 0x3 */
3353 { 0x42,0x47, 40}, /* 0x4 */
3354 { 0xfe,0xcd, 43}, /* 0x5 */
3355 { 0x5d,0xc4, 44}, /* 0x6 */
3356 { 0x52,0x47, 49}, /* 0x7 */
3357 { 0x53,0x47, 50}, /* 0x8 */
3358 { 0x74,0x67, 52}, /* 0x9 */
3359 { 0x6d,0x66, 56}, /* 0xa */
3360 { 0x5a,0x64, 65}, /* 0xb */
3361 { 0x46,0x44, 67}, /* 0xc */
3362 { 0xb1,0x46, 68}, /* 0xd */
3363 { 0xd3,0x4a, 72}, /* 0xe */
3364 { 0x29,0x61, 75}, /* 0xf */
3365 { 0x6d,0x46, 75}, /* 0x10 */
3366 { 0x41,0x43, 78}, /* 0x11 */
3367 { 0x31,0x42, 79}, /* 0x12 */
3368 { 0xab,0x44, 83}, /* 0x13 */
3369 { 0x46,0x25, 84}, /* 0x14 */
3370 { 0x78,0x29, 86}, /* 0x15 */
3371 { 0x62,0x44, 94}, /* 0x16 */
3372 { 0x2b,0x22,104}, /* 0x17 */
3373 { 0x49,0x24,105}, /* 0x18 */
3374 { 0xf8,0x2f,108}, /* 0x19 */
3375 { 0x3c,0x23,109}, /* 0x1a */
3376 { 0x5e,0x43,113}, /* 0x1b */
3377 { 0xbc,0x44,116}, /* 0x1c */
3378 { 0xe0,0x46,132}, /* 0x1d */
3379 { 0xd4,0x28,135}, /* 0x1e */
3380 { 0xea,0x2a,139}, /* 0x1f */
3381 { 0x41,0x22,157}, /* 0x20 */
3382 { 0x70,0x24,162}, /* 0x21 */
3383 { 0x30,0x21,175}, /* 0x22 */
3384 { 0x4e,0x22,189}, /* 0x23 */
3385 { 0xde,0x26,194}, /* 0x24 */
3386 { 0x70,0x07,202}, /* 0x25 */
3387 { 0x3f,0x03,229}, /* 0x26 */
3388 { 0xb8,0x06,234}, /* 0x27 */
3389 { 0x34,0x02,253}, /* 0x28 */
3390 { 0x58,0x04,255}, /* 0x29 */
3391 { 0x24,0x01,265}, /* 0x2a */
3392 { 0x9b,0x02,267}, /* 0x2b */
3393 { 0x70,0x05,270}, /* 0x2c */
3394 { 0x25,0x01,272}, /* 0x2d */
3395 { 0x9c,0x02,277}, /* 0x2e */
3396 { 0x27,0x01,286}, /* 0x2f */
3397 { 0x3c,0x02,291}, /* 0x30 */
3398 { 0xef,0x0a,292}, /* 0x31 */
3399 { 0xf6,0x0a,310}, /* 0x32 */
3400 { 0x95,0x01,315}, /* 0x33 */
3401 { 0xf0,0x09,324}, /* 0x34 */
3402 { 0xfe,0x0a,331}, /* 0x35 */
3403 { 0xf3,0x09,332}, /* 0x36 */
3404 { 0xea,0x08,340}, /* 0x37 */
3405 { 0xe8,0x07,376}, /* 0x38 */
3406 { 0xde,0x06,389}, /* 0x39 */
3407 { 0x52,0x2a, 54}, /* 0x3a */
3408 { 0x52,0x6a, 27}, /* 0x3b */
3409 { 0x62,0x24, 70}, /* 0x3c */
3410 { 0x62,0x64, 70}, /* 0x3d */
3411 { 0xa8,0x4c, 30}, /* 0x3e */
3412 { 0x20,0x26, 33}, /* 0x3f */
3413 { 0x31,0xc2, 39}, /* 0x40 */
3414 { 0x2e,0x48, 25}, /* 0x41 */
3415 { 0x24,0x46, 25}, /* 0x42 */
3416 { 0x26,0x64, 28}, /* 0x43 */
3417 { 0x37,0x64, 40}, /* 0x44 */
3418 { 0xa1,0x42,108}, /* 0x45 */
3419 { 0x37,0x61,100}, /* 0x46 */
3420 { 0x78,0x27,108}, /* 0x47 */
3421 { 0x5e,0x64,68}, /* 0x48 chiawen for fuj1280x768*/
3422 { 0x70,0x44,108}, /* 0x49 chiawen for 1400x1050*/
3423};
3424
3425UCHAR XGI330_ScreenOffset[]={ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,0x78,0x80,0x2d,0x35,0x57,0x48 };
3426
3427XGI_StResInfoStruct XGI330_StResInfo[]=
3428{
3429 { 640,400},
3430 { 640,350},
3431 { 720,400},
3432 { 720,350},
3433 { 640,480}
3434};
3435
3436XGI_ModeResInfoStruct XGI330_ModeResInfo[]=
3437{
3438 { 320, 200, 8, 8},
3439 { 320, 240, 8, 8},
3440 { 320, 400, 8, 8},
3441 { 400, 300, 8, 8},
3442 { 512, 384, 8, 8},
3443 { 640, 400, 8,16},
3444 { 640, 480, 8,16},
3445 { 800, 600, 8,16},
3446 { 1024, 768, 8,16},
3447 { 1280,1024, 8,16},
3448 { 1600,1200, 8,16},
3449 { 1920,1440, 8,16},
3450 { 2048,1536, 8,16},
3451 { 720, 480, 8,16},
3452 { 720, 576, 8,16},
3453 { 1280, 960, 8,16},
3454 { 800, 480, 8,16},
3455 { 1024, 576, 8,16},
3456 { 1280, 720, 8,16},
3457 { 856, 480, 8,16},
3458 { 1280, 768, 8,16},
3459 { 1400,1050, 8,16},
3460 { 1152, 864, 8,16}
3461};
3462
3463UCHAR XGI330_OutputSelect =0x40;
3464UCHAR XGI330_SoftSetting = 0x30;
3465UCHAR XGI330_SR07=0x18;
3466UCHAR XGI330New_SR15[8][8]={
3467{0x0,0x4,0x60,0x60},
3468{0xf,0xf,0xf,0xf},
3469{0xba,0xba,0xba,0xba},
3470{0xa9,0xa9,0xac,0xac},
3471{0xa0,0xa0,0xa0,0xa8},
3472{0x0,0x0,0x2,0x2},
3473{0x30,0x30,0x40,0x40},
3474{0x0,0xa5,0xfb,0xf6}
3475};
3476
3477UCHAR XGI330New_CR40[5][8]={
3478{0x77,0x77,0x44,0x44},
3479{0x77,0x77,0x44,0x44},
3480{0x0,0x0,0x0,0x0},
3481{0x5b,0x5b,0xab,0xab},
3482{0x0,0x0,0xf0,0xf8}
3483};
3484
3485UCHAR XGI330_CR49[]={0xaa,0x88};
3486UCHAR XGI330_SR1F=0x0;
3487UCHAR XGI330_SR21=0xa3;
3488UCHAR XGI330_650_SR21=0xa7;
3489UCHAR XGI330_SR22=0xfb;
3490UCHAR XGI330_SR23=0xf6;
3491UCHAR XGI330_SR24=0xd;
3492
3493UCHAR XGI660_SR21=0xa3;/* 2003.0312 */
3494UCHAR XGI660_SR22=0xf3;/* 2003.0312 */
3495
3496UCHAR XGI330_LVDS_SR32=0x00; /* ynlai for 650 LVDS */
3497UCHAR XGI330_LVDS_SR33=0x00; /* chiawen for 650 LVDS */
3498UCHAR XGI330_650_SR31=0x40;
3499UCHAR XGI330_650_SR33=0x04;
3500UCHAR XGI330_CRT2Data_1_2 = 0x0;
3501UCHAR XGI330_CRT2Data_4_D = 0x0;
3502UCHAR XGI330_CRT2Data_4_E = 0x0;
3503UCHAR XGI330_CRT2Data_4_10 = 0x80;
3504USHORT XGI330_RGBSenseData = 0xd1;
3505USHORT XGI330_VideoSenseData = 0xb9;
3506USHORT XGI330_YCSenseData = 0xb3;
3507USHORT XGI330_RGBSenseData2 = 0x0190; /*301b*/
3508USHORT XGI330_VideoSenseData2 = 0x0110;
3509USHORT XGI330_YCSenseData2 = 0x016B;
3510UCHAR XGI330_NTSCPhase[] = {0x21,0xed,0x8a,0x8};
3511UCHAR XGI330_PALPhase[] = {0x2a,0x5,0xd3,0x0};
3512UCHAR XGI330_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};/*301b*/
3513UCHAR XGI330_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
3514UCHAR XGI330_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /*palmn*/
3515UCHAR XGI330_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
3516UCHAR XG40_I2CDefinition = 0x00 ;
3517UCHAR XG20_CR97 = 0x10 ;
3518
3519UCHAR XG21_DVOSetting = 0x00 ;
3520UCHAR XG21_CR2E = 0x00 ;
3521UCHAR XG21_CR2F = 0x00 ;
3522UCHAR XG21_CR46 = 0x00 ;
3523UCHAR XG21_CR47 = 0x00 ;
3524
3525UCHAR XG27_CR97 = 0xC1 ;
3526UCHAR XG27_SR36 = 0x30 ;
3527UCHAR XG27_CR8F = 0x0C ;
3528UCHAR XG27_CRD0[] = {0,0,0,0,0,0,0,0x82,0x00,0x66,0x01,0x00} ;
3529UCHAR XG27_CRDE[] = {0,0} ;
3530UCHAR XG27_SR40 = 0x04 ;
3531UCHAR XG27_SR41 = 0x00 ;
3532
3533UCHAR XGI330_CHTVVCLKUNTSC[]={0x00 };
3534
3535UCHAR XGI330_CHTVVCLKONTSC[]={0x00 };
3536
3537UCHAR XGI330_CHTVVCLKUPAL[]={0x00 };
3538
3539UCHAR XGI330_CHTVVCLKOPAL[]={0x00 };
3540
3541UCHAR XGI7007_CHTVVCLKUNTSC[]={CH7007TVVCLK30_2,
3542 CH7007TVVCLK30_2,
3543 CH7007TVVCLK30_2,
3544 CH7007TVVCLK30_2,
3545 CH7007TVVCLK28_1,
3546 CH7007TVVCLK47_8
3547 };
3548
3549UCHAR XGI7007_CHTVVCLKONTSC[]={CH7007TVVCLK26_4,
3550 CH7007TVVCLK26_4,
3551 CH7007TVVCLK26_4,
3552 CH7007TVVCLK26_4,
3553 CH7007TVVCLK24_6,
3554 CH7007TVVCLK43_6
3555 };
3556
3557UCHAR XGI7007_CHTVVCLKUPAL[]={CH7007TVVCLK31_5,
3558 CH7007TVVCLK31_5,
3559 CH7007TVVCLK31_5,
3560 CH7007TVVCLK31_5,
3561 CH7007TVVCLK26_2,
3562 CH7007TVVCLK39
3563 };
3564
3565UCHAR XGI7007_CHTVVCLKOPAL[]={CH7007TVVCLK31_5,
3566 CH7007TVVCLK31_5,
3567 CH7007TVVCLK31_5,
3568 CH7007TVVCLK31_5,
3569 CH7007TVVCLK26_2,
3570 CH7007TVVCLK36
3571 };
3572
3573XGI330_VCLKDataStruct XGI_CH7007VCLKData[]=
3574{
3575 { 0x60,0x36,30}, /* 0 30.2 MHZ */
3576 { 0x40,0x4A,28}, /* 1 28.19 MHZ */
3577 { 0x9F,0x46,44}, /* 2 43.6 MHZ */
3578 { 0x97,0x2C,26}, /* 3 26.4 MHZ */
3579 { 0x44,0xE4,25}, /* 4 24.6 MHZ */
3580 { 0x7E,0x32,47}, /* 5 47.832 MHZ */
3581 { 0x8A,0x24,31}, /* 6 31.5 MHZ */
3582 { 0x97,0x2C,26}, /* 7 26.2 MHZ */
3583 { 0xCE,0x3C,39}, /* 8 39 MHZ */
3584 { 0x52,0x4A,36}, /* 9 36 MHZ */
3585 { 0xFF,0x00,0 } /* End mark */
3586};
3587
3588XGI330_VCLKDataStruct XGI_VCLKData[]=
3589{
3590 /* SR2B,SR2C,SR2D */
3591 { 0x1B,0xE1,25 },/* 00 (25.175MHz) */
3592
3593 { 0x4E,0xE4,28 },/* 01 (28.322MHz) */
3594
3595 { 0x57,0xE4,31 },/* 02 (31.500MHz) */
3596
3597 { 0xC3,0xC8,36 },/* 03 (36.000MHz) */
3598
3599 { 0x42,0xE2,40 },/* 04 (40.000MHz) */
3600
3601 { 0xFE,0xCD,43 },/* 05 (43.163MHz) */
3602
3603 { 0x5D,0xC4,44 },/* 06 (44.900MHz) */
3604
3605 { 0x52,0xE2,49 },/* 07 (49.500MHz) */
3606
3607 { 0x53,0xE2,50 },/* 08 (50.000MHz) */
3608
3609 { 0x74,0x67,52 },/* 09 (52.406MHz) */
3610
3611 { 0x6D,0x66,56 },/* 0A (56.250MHz) */
3612
3613 { 0x6C,0xC3,65 },/* 0B (65.000MHz) */
3614
3615 { 0x46,0x44,67 },/* 0C (67.765MHz) */
3616
3617 { 0xB1,0x46,68 },/* 0D (68.179MHz) */
3618
3619 { 0xD3,0x4A,72 },/* 0E (72.852MHz) */
3620
3621 { 0x29,0x61,75 },/* 0F (75.000MHz) */
3622
3623 { 0x6E,0x46,76 },/* 10 (75.800MHz) */
3624
3625 { 0x2B,0x61,78 },/* 11 (78.750MHz) */
3626
3627 { 0x31,0x42,79 },/* 12 (79.411MHz) */
3628
3629 { 0xAB,0x44,83 },/* 13 (83.950MHz) */
3630
3631 { 0x46,0x25,84 },/* 14 (84.800MHz) */
3632
3633 { 0x78,0x29,86 },/* 15 (86.600MHz) */
3634
3635 { 0x62,0x44,94 },/* 16 (94.500MHz) */
3636
3637 { 0x2B,0x41,104 },/* 17 (104.998MHz) */
3638
3639 { 0x3A,0x23,105 },/* 18 (105.882MHz) */
3640
3641 { 0x70,0x44,108 },/* 19 (107.862MHz) */
3642
3643 { 0x3C,0x23,109 },/* 1A (109.175MHz) */
3644
3645 { 0x5E,0x43,113 },/* 1B (113.309MHz) */
3646
3647 { 0xBC,0x44,116 },/* 1C (116.406MHz) */
3648
3649 { 0xE0,0x46,132 },/* 1D (132.258MHz) */
3650
3651 { 0x54,0x42,135 },/* 1E (135.500MHz) */
3652
3653 { 0x9C,0x22,139 },/* 1F (139.275MHz) */
3654
3655 { 0x41,0x22,157 },/* 20 (157.500MHz) */
3656
3657 { 0x70,0x24,162 },/* 21 (161.793MHz) */
3658
3659 { 0x30,0x21,175 },/* 22 (175.000MHz) */
3660
3661 { 0x4E,0x22,189 },/* 23 (188.520MHz) */
3662
3663 { 0xDE,0x26,194 },/* 24 (194.400MHz) */
3664
3665 { 0x62,0x06,202 },/* 25 (202.500MHz) */
3666
3667 { 0x3F,0x03,229 },/* 26 (229.500MHz) */
3668
3669 { 0xB8,0x06,234 },/* 27 (233.178MHz) */
3670
3671 { 0x34,0x02,253 },/* 28 (252.699MHz) */
3672
3673 { 0x58,0x04,255 },/* 29 (254.817MHz) */
3674
3675 { 0x24,0x01,265 },/* 2A (265.728MHz) */
3676
3677 { 0x9B,0x02,267 },/* 2B (266.952MHz) */
3678
3679 { 0x70,0x05,270 },/* 2C (269.65567MHz) */
3680
3681 { 0x25,0x01,272 },/* 2D (272.04199MHz) */
3682
3683 { 0x9C,0x02,277 },/* 2E (277.015MHz) */
3684
3685 { 0x27,0x01,286 },/* 2F (286.359985MHz) */
3686
3687 { 0xB3,0x04,291 },/* 30 (291.13266MHz) */
3688
3689 { 0xBC,0x05,292 },/* 31 (291.766MHz) */
3690
3691 { 0xF6,0x0A,310 },/* 32 (309.789459MHz) */
3692
3693 { 0x95,0x01,315 },/* 33 (315.195MHz) */
3694
3695 { 0xF0,0x09,324 },/* 34 (323.586792MHz) */
3696
3697 { 0xFE,0x0A,331 },/* 35 (330.615631MHz) */
3698
3699 { 0xF3,0x09,332 },/* 36 (332.177612MHz) */
3700
3701 { 0x5E,0x03,340 },/* 37 (340.477MHz) */
3702
3703 { 0xE8,0x07,376 },/* 38 (375.847504MHz) */
3704
3705 { 0xDE, 0x06,389 },/* 39 (388.631439MHz) */
3706
3707 { 0x52,0x2A,54 },/* 3A (54.000MHz) */
3708
3709 { 0x52,0x6A,27 },/* 3B (27.000MHz) */
3710
3711 { 0x62,0x24,70 },/* 3C (70.874991MHz) */
3712
3713 { 0x62,0x64,70 },/* 3D (70.1048912MHz) */
3714
3715 { 0xA8,0x4C,30 },/* 3E (30.1048912MHz) */
3716
3717 { 0x20,0x26,33 },/* 3F (33.7499957MHz) */
3718
3719 { 0x31,0xc2,39 },/* 40 (39.77MHz) */
3720
3721 { 0x11,0x21,30 },/* 41 (30MHz) }// NTSC 1024X768 */
3722
3723 { 0x2E,0x48,25 },/* 42 (25.175MHz) }// ScaleLCD */
3724
3725 { 0x24,0x46,25 },/* 43 (25.175MHz) */
3726
3727 { 0x26,0x64,28 },/* 44 (28.322MHz) */
3728
3729 { 0x37,0x64,40 },/* 45 (40.000MHz) */
3730
3731 { 0xA1,0x42,108 },/* 46 (95.000MHz) }// QVGA */
3732
3733 { 0x37,0x61,100 },/* 47 (100.00MHz) */
3734
3735 { 0x78,0x27,108 },/* 48 (108.200MHz) */
3736
3737 { 0xBF,0xC8,35 },/* 49 (35.2MHz) */
3738
3739 { 0x66,0x43,123 },/* 4A (122.61Mhz) */
3740
3741 { 0x2C,0x61,80 },/* 4B (80.350Mhz) */
3742
3743 { 0x3B,0x61,108 },/* 4C (107.385Mhz) */
3744
3745
3746/* { 0x60,0x36,30 },// 4D (30.200MHz) }// No use
3747
3748 { 0x60,0x36,30 },// 4E (30.200MHz) }// No use
3749
3750 { 0x60,0x36,30 },// 4F (30.200MHz) }// No use
3751
3752 { 0x60,0x36,30 },// 50 (30.200MHz) }// CHTV
3753
3754 { 0x40,0x4A,28 },// 51 (28.190MHz)
3755
3756 { 0x9F,0x46,44 },// 52 (43.600MHz)
3757
3758 { 0x97,0x2C,26 },// 53 (26.400MHz)
3759
3760 { 0x44,0xE4,25 },// 54 (24.600MHz)
3761
3762 { 0x7E,0x32,47 },// 55 (47.832MHz)
3763
3764 { 0x8A,0x24,31 },// 56 (31.500MHz)
3765
3766 { 0x97,0x2C,26 },// 57 (26.200MHz)
3767
3768 { 0xCE,0x3C,39 },// 58 (39.000MHz)
3769
3770 { 0x52,0x4A,36 },// 59 (36.000MHz)
3771
3772*/
3773 { 0x69,0x61,191 }, /* 4D (190.96MHz ) */
3774 { 0x4F,0x22,192 }, /* 4E (192.069MHz) */
3775 { 0x28,0x26,322 }, /* 4F (322.273MHz) */
3776 { 0x5C,0x6B,27 }, /* 50 (27.74HMz) */
3777 { 0x57,0x24,126 }, /* 51 (125.999MHz) */
3778 { 0x5C,0x42,148 }, /* 52 (148.5MHz) */
3779 { 0x42,0x61,120 }, /* 53 (120.839MHz) */
3780 { 0x62,0x61,178 }, /* 54 (178.992MHz) */
3781 { 0x59,0x22,217 }, /* 55 (217.325MHz) */
3782 { 0x29,0x01,300 }, /* 56 (299.505Mhz) */
3783 { 0x52,0x63,74 }, /* 57 (74.25MHz) */
3784
3785
3786 { 0xFF,0x00,0 }/* End mark */
3787 } ;
3788
3789XGI330_VCLKDataStruct XGI_VBVCLKData[]=
3790{
3791 { 0x1B,0xE1,25 },/* 00 (25.175MHz) */
3792
3793 { 0x4E,0xE4,28 },/* 01 (28.322MHz) */
3794
3795 { 0x57,0xE4,31 },/* 02 (31.500MHz) */
3796
3797 { 0xC3,0xC8,36 },/* 03 (36.000MHz) */
3798
3799 { 0x42,0x47,40 },/* 04 (40.000MHz) */
3800
3801 { 0xFE,0xCD,43 },/* 05 (43.163MHz) */
3802
3803 { 0x5D,0xC4,44 },/* 06 (44.900MHz) */
3804
3805 { 0x52,0x47,49 },/* 07 (49.500MHz) */
3806
3807 { 0x53,0x47,50 },/* 08 (50.000MHz) */
3808
3809 { 0x74,0x67,52 },/* 09 (52.406MHz) */
3810
3811 { 0x6D,0x66,56 },/* 0A (56.250MHz) */
3812
3813 { 0x35,0x62,65 },/* 0B (65.000MHz) */
3814
3815 { 0x46,0x44,67 },/* 0C (67.765MHz) */
3816
3817 { 0xB1,0x46,68 },/* 0D (68.179MHz) */
3818
3819 { 0xD3,0x4A,72 },/* 0E (72.852MHz) */
3820
3821 { 0x29,0x61,75 },/* 0F (75.000MHz) */
3822
3823 { 0x6D,0x46,75 },/* 10 (75.800MHz) */
3824
3825 { 0x41,0x43,78 },/* 11 (78.750MHz) */
3826
3827 { 0x31,0x42,79 },/* 12 (79.411MHz) */
3828
3829 { 0xAB,0x44,83 },/* 13 (83.950MHz) */
3830
3831 { 0x46,0x25,84 },/* 14 (84.800MHz) */
3832
3833 { 0x78,0x29,86 },/* 15 (86.600MHz) */
3834
3835 { 0x62,0x44,94 },/* 16 (94.500MHz) */
3836
3837 { 0x2B,0x22,104 },/* 17 (104.998MHz) */
3838
3839 { 0x49,0x24,105 },/* 18 (105.882MHz) */
3840
3841 { 0xF8,0x2F,108 },/* 19 (108.279MHz) */
3842
3843 { 0x3C,0x23,109 },/* 1A (109.175MHz) */
3844
3845 { 0x5E,0x43,113 },/* 1B (113.309MHz) */
3846
3847 { 0xBC,0x44,116 },/* 1C (116.406MHz) */
3848
3849 { 0xE0,0x46,132 },/* 1D (132.258MHz) */
3850
3851 { 0xD4,0x28,135 },/* 1E (135.220MHz) */
3852
3853 { 0xEA,0x2A,139 },/* 1F (139.275MHz) */
3854
3855 { 0x41,0x22,157 },/* 20 (157.500MHz) */
3856
3857 { 0x70,0x24,162 },/* 21 (161.793MHz) */
3858
3859 { 0x30,0x21,175 },/* 22 (175.000MHz) */
3860
3861 { 0x4E,0x22,189 },/* 23 (188.520MHz) */
3862
3863 { 0xDE,0x26,194 },/* 24 (194.400MHz) */
3864
3865 { 0x70,0x07,202 },/* 25 (202.500MHz) */
3866
3867 { 0x3F,0x03,229 },/* 26 (229.500MHz) */
3868
3869 { 0xB8,0x06,234 },/* 27 (233.178MHz) */
3870
3871 { 0x34,0x02,253 },/* 28 (252.699997 MHz) */
3872
3873 { 0x58,0x04,255 },/* 29 (254.817MHz) */
3874
3875 { 0x24,0x01,265 },/* 2A (265.728MHz) */
3876
3877 { 0x9B,0x02,267 },/* 2B (266.952MHz) */
3878
3879 { 0x70,0x05,270 },/* 2C (269.65567 MHz) */
3880
3881 { 0x25,0x01,272 },/* 2D (272.041992 MHz) */
3882
3883 { 0x9C,0x02,277 },/* 2E (277.015MHz) */
3884
3885 { 0x27,0x01,286 },/* 2F (286.359985 MHz) */
3886
3887 { 0x3C,0x02,291 },/* 30 (291.132660 MHz) */
3888
3889 { 0xEF,0x0A,292 },/* 31 (291.766MHz) */
3890
3891 { 0xF6,0x0A,310 },/* 32 (309.789459 MHz) */
3892
3893 { 0x95,0x01,315 },/* 33 (315.195MHz) */
3894
3895 { 0xF0,0x09,324 },/* 34 (323.586792 MHz) */
3896
3897 { 0xFE,0x0A,331 },/* 35 (330.615631 MHz) */
3898
3899 { 0xF3,0x09,332 },/* 36 (332.177612 MHz) */
3900
3901 { 0xEA,0x08,340 },/* 37 (340.477MHz) */
3902
3903 { 0xE8,0x07,376 },/* 38 (375.847504 MHz) */
3904
3905 { 0xDE,0x06,389 },/* 39 (388.631439 MHz) */
3906
3907 { 0x52,0x2A,54 },/* 3A (54.000MHz) */
3908
3909 { 0x52,0x6A,27 },/* 3B (27.000MHz) */
3910
3911
3912 { 0x62,0x24,70 },/* 3C (70.874991MHz) */
3913
3914
3915 { 0x62,0x64,70 },/* 3D (70.1048912MHz) */
3916
3917 { 0xA8,0x4C,30 },/* 3E (30.1048912MHz) */
3918
3919 { 0x20,0x26,33 },/* 3F (33.7499957MHz) */
3920
3921 { 0x31,0xc2,39 },/* 40 (39.77MHz) */
3922
3923 { 0x11,0x21,30 },/* 41 (30MHz) }// NTSC 1024X768 */
3924
3925 { 0x2E,0x48,25 },/* 42 (25.175MHz) }// ScaleLCD */
3926
3927 { 0x24,0x46,25 },/* 43 (25.175MHz) */
3928
3929 { 0x26,0x64,28 },/* 44 (28.322MHz) */
3930
3931 { 0x37,0x64,40 },/* 45 (40.000MHz) */
3932
3933 { 0xA1,0x42,108 },/* 46 (95.000MHz) }// QVGA */
3934
3935 { 0x37,0x61,100 },/* 47 (100.00MHz) */
3936
3937 { 0x78,0x27,108 },/* 48 (108.200MHz) */
3938
3939 { 0xBF,0xC8,35 },/* 49 (35.2MHz) */
3940
3941 { 0x66,0x43,123 },/* 4A (122.61Mhz) */
3942
3943 { 0x2C,0x61,80 },/* 4B (80.350Mhz) */
3944
3945 { 0x3B,0x61,108 },/* 4C (107.385Mhz) */
3946
3947/*
3948 { 0x60,0x36,30 },// 4D (30.200MHz) }// No use
3949
3950 { 0x60,0x36,30 },// 4E (30.200MHz) }// No use
3951
3952 { 0x60,0x36,30 },// 4F (30.200MHz) }// No use
3953
3954 { 0x60,0x36,30 },// 50 (30.200MHz) }// CHTV
3955
3956 { 0x40,0x4A,28 },// 51 (28.190MHz)
3957
3958 { 0x9F,0x46,44 },// 52 (43.600MHz)
3959
3960 { 0x97,0x2C,26 },// 53 (26.400MHz)
3961
3962 { 0x44,0xE4,25 },// 54 (24.600MHz)
3963
3964 { 0x7E,0x32,47 },// 55 (47.832MHz)
3965
3966 { 0x8A,0x24,31 },// 56 (31.500MHz)
3967
3968 { 0x97,0x2C,26 },// 57 (26.200MHz)
3969
3970 { 0xCE,0x3C,39 },// 58 (39.000MHz)
3971
3972 { 0x52,0x4A,36 },// 59 (36.000MHz)
3973*/
3974 { 0x69,0x61,191 }, /* 4D (190.96MHz ) */
3975 { 0x4F,0x22,192 }, /* 4E (192.069MHz) */
3976 { 0x28,0x26,322 }, /* 4F (322.273MHz) */
3977 { 0x5C,0x6B,27 }, /* 50 (27.74HMz) */
3978 { 0x57,0x24,126 }, /* 51 (125.999MHz) */
3979 { 0x5C,0x42,148 }, /* 52 (148.5MHz) */
3980 { 0x42,0x61,120 }, /* 53 (120.839MHz) */
3981 { 0x62,0x61,178 }, /* 54 (178.992MHz) */
3982 { 0x59,0x22,217 }, /* 55 (217.325MHz) */
3983 { 0x29,0x01,300 }, /* 56 (299.505Mhz) */
3984 { 0x52,0x63,74 }, /* 57 (74.25MHz) */
3985
3986
3987 { 0xFF,0x00,0 } /* End mark */
3988};
3989
3990UCHAR XGI660_TVDelayList[]=
3991{
3992 0x44, /* ; 0 ExtNTSCDelay */
3993 0x44, /* ; 1 StNTSCDelay */
3994 0x44, /* ; 2 ExtPALDelay */
3995 0x44, /* ; 3 StPALDelay */
3996 0x44, /* ; 4 ExtHiTVDelay(1080i) */
3997 0x44, /* ; 5 StHiTVDelay(1080i) */
3998 0x44, /* ; 6 ExtYPbPrDelay(525i) */
3999 0x44, /* ; 7 StYPbPrDealy(525i) */
4000 0x44, /* ; 8 ExtYPbPrDelay(525p) */
4001 0x44, /* ; 9 StYPbPrDealy(525p) */
4002 0x44, /* ; A ExtYPbPrDelay(750p) */
4003 0x44 /* ; B StYPbPrDealy(750p) */
4004};
4005
4006UCHAR XGI660_TVDelayList2[]=
4007{
4008 0x44, /* ; 0 ExtNTSCDelay */
4009 0x44, /* ; 1 StNTSCDelay */
4010 0x44, /* ; 2 ExtPALDelay */
4011 0x44, /* ; 3 StPALDelay */
4012 0x44, /* ; 4 ExtHiTVDelay */
4013 0x44, /* ; 5 StHiTVDelay */
4014 0x44, /* ; 6 ExtYPbPrDelay(525i) */
4015 0x44, /* ; 7 StYPbPrDealy(525i) */
4016 0x44, /* ; 8 ExtYPbPrDelay(525p) */
4017 0x44, /* ; 9 StYPbPrDealy(525p) */
4018 0x44, /* ; A ExtYPbPrDelay(750p) */
4019 0x44 /* ; B StYPbPrDealy(750p) */
4020};
4021
4022UCHAR XGI301TVDelayList[]=
4023{
4024 0x22, /* ; 0 ExtNTSCDelay */
4025 0x22, /* ; 1 StNTSCDelay */
4026 0x22, /* ; 2 ExtPALDelay */
4027 0x22, /* ; 3 StPALDelay */
4028 0x88, /* ; 4 ExtHiTVDelay(1080i) */
4029 0xBB, /* ; 5 StHiTVDelay(1080i) */
4030 0x22, /* ; 6 ExtYPbPrDelay(525i) */
4031 0x22, /* ; 7 StYPbPrDealy(525i) */
4032 0x22, /* ; 8 ExtYPbPrDelay(525p) */
4033 0x22, /* ; 9 StYPbPrDealy(525p) */
4034 0x22, /* ; A ExtYPbPrDelay(750p) */
4035 0x22 /* B StYPbPrDealy(750p) */
4036};
4037
4038UCHAR XGI301TVDelayList2[]=
4039{
4040 0x22, /* ; 0 ExtNTSCDelay */
4041 0x22, /* ; 1 StNTSCDelay */
4042 0x22, /* ; 2 ExtPALDelay */
4043 0x22, /* ; 3 StPALDelay */
4044 0x22, /* ; 4 ExtHiTVDelay */
4045 0x22, /* ; 5 StHiTVDelay */
4046 0x22, /* ; 6 ExtYPbPrDelay(525i) */
4047 0x22, /* ; 7 StYPbPrDealy(525i) */
4048 0x22, /* ; 8 ExtYPbPrDelay(525p) */
4049 0x22, /* ; 9 StYPbPrDealy(525p) */
4050 0x22, /* ; A ExtYPbPrDelay(750p) */
4051 0x22 /* ; B StYPbPrDealy(750p) */
4052};
4053
4054
4055UCHAR TVAntiFlickList[]=
4056{/* NTSCAntiFlicker */
4057 0x04, /* ; 0 Adaptive */
4058 0x00, /* ; 1 new anti-flicker ? */
4059/* PALAntiFlicker */
4060 0x04, /* ; 0 Adaptive */
4061 0x08, /* ; 1 new anti-flicker ? */
4062/* HiTVAntiFlicker */
4063 0x04, /* ; 0 ? */
4064 0x00 /* ; 1 new anti-flicker ? */
4065};
4066
4067
4068UCHAR TVEdgeList[]=
4069{
4070 0x00, /* ; 0 NTSC No Edge enhance */
4071 0x04, /* ; 1 NTSC Adaptive Edge enhance */
4072 0x00, /* ; 0 PAL No Edge enhance */
4073 0x04, /* ; 1 PAL Adaptive Edge enhance */
4074 0x00, /* ; 0 HiTV */
4075 0x00 /* ; 1 HiTV */
4076};
4077
4078ULONG TVPhaseList[]=
4079{ 0x08BAED21, /* ; 0 NTSC phase */
4080 0x00E3052A, /* ; 1 PAL phase */
4081 0x9B2EE421, /* ; 2 PAL-M phase */
4082 0xBA3EF421, /* ; 3 PAL-N phase */
4083 0xA7A28B1E, /* ; 4 NTSC 1024x768 */
4084 0xE00A831E, /* ; 5 PAL-M 1024x768 */
4085 0x00000000, /* ; 6 reserved */
4086 0x00000000, /* ; 7 reserved */
4087 0xD67BF021, /* ; 8 NTSC phase */
4088 0xE986092A, /* ; 9 PAL phase */
4089 0xA4EFE621, /* ; A PAL-M phase */
4090 0x4694F621, /* ; B PAL-N phase */
4091 0x8BDE711C, /* ; C NTSC 1024x768 */
4092 0xE00A831E /* ; D PAL-M 1024x768 */
4093};
4094
4095UCHAR NTSCYFilter1[]=
4096{
4097 0x00,0xF4,0x10,0x38 ,/* 0 : 320x text mode */
4098 0x00,0xF4,0x10,0x38 ,/* 1 : 360x text mode */
4099 0xEB,0x04,0x25,0x18 ,/* 2 : 640x text mode */
4100 0xF1,0x04,0x1F,0x18 ,/* 3 : 720x text mode */
4101 0x00,0xF4,0x10,0x38 ,/* 4 : 320x gra. mode */
4102 0xEB,0x04,0x25,0x18 ,/* 5 : 640x gra. mode */
4103 0xEB,0x15,0x25,0xF6 /* 6 : 800x gra. mode */
4104};
4105
4106UCHAR PALYFilter1[]=
4107{
4108 0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
4109 0x00,0xF4,0x10,0x38 ,/* 1 : 360x text mode */
4110 0xF1,0xF7,0x1F,0x32 ,/* 2 : 640x text mode */
4111 0xF3,0x00,0x1D,0x20 ,/* 3 : 720x text mode */
4112 0x00,0xF4,0x10,0x38 ,/* 4 : 320x gra. mode */
4113 0xF1,0xF7,0x1F,0x32 ,/* 5 : 640x gra. mode */
4114 0xFC,0xFB,0x14,0x2A /* 6 : 800x gra. mode */
4115};
4116
4117UCHAR PALMYFilter1[]=
4118{
4119 0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
4120 0x00,0xF4,0x10,0x38, /* 1 : 360x text mode */
4121 0xEB,0x04,0x10,0x18, /* 2 : 640x text mode */
4122 0xF7,0x06,0x19,0x14, /* 3 : 720x text mode */
4123 0x00,0xF4,0x10,0x38, /* 4 : 320x gra. mode */
4124 0xEB,0x04,0x25,0x18, /* 5 : 640x gra. mode */
4125 0xEB,0x15,0x25,0xF6, /* 6 : 800x gra. mode */
4126 0xFF,0xFF,0xFF,0xFF /* End of Table */
4127};
4128
4129UCHAR PALNYFilter1[]=
4130{
4131 0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
4132 0x00,0xF4,0x10,0x38, /* 1 : 360x text mode */
4133 0xEB,0x04,0x10,0x18, /* 2 : 640x text mode */
4134 0xF7,0x06,0x19,0x14, /* 3 : 720x text mode */
4135 0x00,0xF4,0x10,0x38, /* 4 : 320x gra. mode */
4136 0xEB,0x04,0x25,0x18, /* 5 : 640x gra. mode */
4137 0xEB,0x15,0x25,0xF6, /* 6 : 800x gra. mode */
4138 0xFF,0xFF,0xFF,0xFF /* End of Table */
4139};
4140
4141UCHAR NTSCYFilter2[]=
4142{
4143 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
4144 0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
4145 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 2 : 640x text mode */
4146 0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 3 : 720x text mode */
4147 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 4 : 320x gra. mode */
4148 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 5 : 640x gra. mode */
4149 0x01,0x01,0xFC,0xF8,0x08,0x26,0x38, /* 6 : 800x gra. mode */
4150 0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28 /* 7 : 1024xgra. mode */
4151};
4152
4153UCHAR PALYFilter2[]=
4154{
4155 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
4156 0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
4157 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 2 : 640x text mode */
4158 0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 3 : 720x text mode */
4159 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 4 : 320x gra. mode */
4160 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 5 : 640x gra. mode */
4161 0x01,0x01,0xFC,0xF8,0x08,0x26,0x38, /* 6 : 800x gra. mode */
4162 0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28 /* 7 : 1024xgra. mode */
4163};
4164
4165UCHAR PALMYFilter2[]=
4166{
4167 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
4168 0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
4169 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 2 : 640x text mode */
4170 0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 3 : 720x text mode */
4171 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 4 : 320x gra. mode */
4172 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 5 : 640x gra. mode */
4173 0x01,0x01,0xFC,0xF8,0x08,0x26,0x38, /* 6 : 800x gra. mode */
4174 0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28 /* 7 : 1024xgra. mode */
4175};
4176
4177UCHAR PALNYFilter2[]=
4178{
4179 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
4180 0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
4181 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 2 : 640x text mode */
4182 0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 3 : 720x text mode */
4183 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 4 : 320x gra. mode */
4184 0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 5 : 640x gra. mode */
4185 0x01,0x01,0xFC,0xF8,0x08,0x26,0x38, /* 6 : 800x gra. mode */
4186 0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28 /* 7 : 1024xgra. mode */
4187};
4188
4189UCHAR XGI_NTSC1024AdjTime[]=
4190{
4191 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
4192 0x13,0x40,0x34,0xF4,0x63,0xBB,0xCC,0x7A,
4193 0x58,0xe4,0x73,0xd0,0x13
4194};
4195
4196XGI301C_Tap4TimingStruct HiTVTap4Timing[]=
4197{
4198 {0,{
4199 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
4200 0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, /* ; C8-CF */
4201 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E, /* ; D0-D7 */
4202 0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, /* ; D8-DF */
4203 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C, /* ; E0-E7 */
4204 0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C, /* ; EA-EF */
4205 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C, /* ; F0-F7 */
4206 0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E /* ; F8-FF */
4207 }
4208 }
4209};
4210
4211XGI301C_Tap4TimingStruct EnlargeTap4Timing[]=
4212{
4213 {0,{
4214 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
4215 0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, /* ; C8-CF */
4216 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E, /* ; D0-D7 */
4217 0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, /* ; D8-DF */
4218 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C, /* ; E0-E7 */
4219 0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C, /* ; EA-EF */
4220 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C, /* ; F0-F7 */
4221 0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E /* ; F8-FF */
4222 }
4223 }
4224};
4225
4226XGI301C_Tap4TimingStruct NoScaleTap4Timing[]=
4227{
4228 {0,{
4229 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
4230 0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, /* ; C8-CF */
4231 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E, /* ; D0-D7 */
4232 0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, /* ; D8-DF */
4233 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C, /* ; E0-E7 */
4234 0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C, /* ; EA-EF */
4235 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C, /* ; F0-F7 */
4236 0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E /* ; F8-FF */
4237 }
4238 }
4239};
4240
4241XGI301C_Tap4TimingStruct PALTap4Timing[]=
4242{
4243 {600, {
4244 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E, /* ; C0-C7 */
4245 0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D, /* ; C8-CF */
4246 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C, /* ; D0-D7 */
4247 0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D, /* ; D8-DF */
4248 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E, /* ; E0-E7 */
4249 0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E, /* ; EA-EF */
4250 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01, /* ; F0-F7 */
4251 0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04 /* ; F8-FF */
4252 }
4253 },
4254 {768, {
4255 0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E, /* ; C0-C7 */
4256 0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F, /* ; C8-CF */
4257 0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00, /* ; D0-D7 */
4258 0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01, /* ; D8-DF */
4259 0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02, /* ; E0-E7 */
4260 0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04, /* ; EA-EF */
4261 0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05, /* ; F0-F7 */
4262 0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07 /* ; F8-FF */
4263 }
4264 },
4265 {0xFFFF,
4266 {
4267 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E, /* ; C0-C7 */
4268 0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D, /* ; C8-CF */
4269 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D, /* ; D0-D7 */
4270 0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C, /* ; D8-DF */
4271 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D, /* ; E0-E7 */
4272 0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F, /* ; EA-EF */
4273 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00, /* ; F0-F7 */
4274 0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02 /* ; F8-FF */
4275 }
4276 }
4277};
4278
4279XGI301C_Tap4TimingStruct NTSCTap4Timing[]=
4280{
4281 {480, {
4282 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
4283 0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D, /* ; C8-CF */
4284 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C, /* ; D0-D7 */
4285 0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C, /* ; D8-DF */
4286 0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D, /* ; E0-E7 */
4287 0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E, /* ; EA-EF */
4288 0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00, /* ; F0-F7 */
4289 0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02 /* ; F8-FF */
4290 }
4291 },
4292 {600, {
4293 0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D, /* ; C0-C7 */
4294 0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E, /* ; C8-CF */
4295 0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F, /* ; D0-D7 */
4296 0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F, /* ; D8-DF */
4297 0x01,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01, /* ; E0-E7 */
4298 0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03, /* ; EA-EF */
4299 0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04, /* ; F0-F7 */
4300 0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06 /* ; F8-FF */
4301 }
4302 },
4303 {0xFFFF,
4304 {
4305 0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00, /* ; C0-C7 */
4306 0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01, /* ; C8-CF */
4307 0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02, /* ; D0-D7 */
4308 0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03, /* ; D8-DF */
4309 0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05, /* ; E0-E7 */
4310 0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06, /* ; EA-EF */
4311 0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07, /* ; F0-F7 */
4312 0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08 /* ; F8-FF */
4313 }
4314 }
4315};
4316
4317XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[]=
4318{
4319 {480, {
4320 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
4321 0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D, /* ; C8-CF */
4322 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C, /* ; D0-D7 */
4323 0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C, /* ; D8-DF */
4324 0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D, /* ; E0-E7 */
4325 0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E, /* ; EA-EF */
4326 0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00, /* ; F0-F7 */
4327 0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02 /* ; F8-FF */
4328 }
4329 },
4330 {600, {
4331 0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D, /* ; C0-C7 */
4332 0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E, /* ; C8-CF */
4333 0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F, /* ; D0-D7 */
4334 0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F, /* ; D8-DF */
4335 0x01,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01, /* ; E0-E7 */
4336 0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03, /* ; EA-EF */
4337 0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04, /* ; F0-F7 */
4338 0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06 /* ; F8-FF */
4339 }
4340 },
4341 {0xFFFF,
4342 {
4343 0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00, /* ; C0-C7 */
4344 0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01, /* ; C8-CF */
4345 0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02, /* ; D0-D7 */
4346 0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03, /* ; D8-DF */
4347 0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05, /* ; E0-E7 */
4348 0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06, /* ; EA-EF */
4349 0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07, /* ; F0-F7 */
4350 0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08 /* ; F8-FF */
4351 }
4352 }
4353};
4354
4355XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[]=
4356{
4357 {480, {
4358 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
4359 0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D, /* ; C8-CF */
4360 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C, /* ; D0-D7 */
4361 0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C, /* ; D8-DF */
4362 0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D, /* ; E0-E7 */
4363 0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E, /* ; EA-EF */
4364 0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00, /* ; F0-F7 */
4365 0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02 /* ; F8-FF */
4366 }
4367 },
4368 {600, {
4369 0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D, /* ; C0-C7 */
4370 0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E, /* ; C8-CF */
4371 0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F, /* ; D0-D7 */
4372 0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F, /* ; D8-DF */
4373 0x01,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01, /* ; E0-E7 */
4374 0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03, /* ; EA-EF */
4375 0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04, /* ; F0-F7 */
4376 0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06 /* ; F8-FF */
4377 }
4378 },
4379 {0xFFFF,
4380 {
4381 0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00, /* ; C0-C7 */
4382 0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01, /* ; C8-CF */
4383 0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02, /* ; D0-D7 */
4384 0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03, /* ; D8-DF */
4385 0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05, /* ; E0-E7 */
4386 0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06, /* ; EA-EF */
4387 0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07, /* ; F0-F7 */
4388 0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08 /* ; F8-FF */
4389 }
4390 }
4391};
4392
4393XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[]=
4394{ {0xFFFF,
4395 {
4396 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E, /* ; C0-C7 */
4397 0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D, /* ; C8-CF */
4398 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C, /* ; D0-D7 */
4399 0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D, /* ; D8-DF */
4400 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E, /* ; E0-E7 */
4401 0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E, /* ; EA-EF */
4402 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01, /* ; F0-F7 */
4403 0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04 /* F8-FF */
4404 }
4405 }
4406};
diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c
new file mode 100644
index 000000000000..87531b49b739
--- /dev/null
+++ b/drivers/staging/xgifb/vb_util.c
@@ -0,0 +1,263 @@
1#include "osdef.h"
2#include "vb_def.h"
3#include "vgatypes.h"
4#include "vb_struct.h"
5
6#ifdef LINUX_KERNEL
7#include "XGIfb.h"
8#include <asm/io.h>
9#include <linux/types.h>
10#endif
11
12#ifdef TC
13#include <stdio.h>
14#include <string.h>
15#include <conio.h>
16#include <dos.h>
17#endif
18
19#ifdef WIN2000
20#include <dderror.h>
21#include <devioctl.h>
22#include <miniport.h>
23#include <ntddvdeo.h>
24#include <video.h>
25
26#include "xgiv.h"
27#include "dd_i2c.h"
28#include "tools.h"
29#endif
30
31#ifdef LINUX_XF86
32#include "xf86.h"
33#include "xf86PciInfo.h"
34#include "xgi.h"
35#include "xgi_regs.h"
36#endif
37
38
39
40
41void XGINew_SetReg1( ULONG , USHORT , USHORT ) ;
42void XGINew_SetReg2( ULONG , USHORT , USHORT ) ;
43void XGINew_SetReg3( ULONG , USHORT ) ;
44void XGINew_SetReg4( ULONG , ULONG ) ;
45UCHAR XGINew_GetReg1( ULONG , USHORT) ;
46UCHAR XGINew_GetReg2( ULONG ) ;
47ULONG XGINew_GetReg3( ULONG ) ;
48void XGINew_ClearDAC( PUCHAR ) ;
49void XGINew_SetRegANDOR(ULONG Port,USHORT Index,USHORT DataAND,USHORT DataOR);
50void XGINew_SetRegOR(ULONG Port,USHORT Index,USHORT DataOR);
51void XGINew_SetRegAND(ULONG Port,USHORT Index,USHORT DataAND);
52
53
54/* --------------------------------------------------------------------- */
55/* Function : XGINew_SetReg1 */
56/* Input : */
57/* Output : */
58/* Description : SR CRTC GR */
59/* --------------------------------------------------------------------- */
60void XGINew_SetReg1( ULONG port , USHORT index , USHORT data )
61{
62#ifdef LINUX_XF86
63 OutPortByte( ( PUCHAR )(ULONG)port , index ) ;
64 OutPortByte( ( PUCHAR )(ULONG)port + 1 , data ) ;
65#else
66 OutPortByte( port , index ) ;
67 OutPortByte( port + 1 , data ) ;
68#endif
69}
70
71
72/* --------------------------------------------------------------------- */
73/* Function : XGINew_SetReg2 */
74/* Input : */
75/* Output : */
76/* Description : AR( 3C0 ) */
77/* --------------------------------------------------------------------- */
78/*void XGINew_SetReg2( ULONG port , USHORT index , USHORT data )
79{
80 InPortByte( ( PUCHAR )port + 0x3da - 0x3c0 ) ;
81 OutPortByte( XGINew_P3c0 , index ) ;
82 OutPortByte( XGINew_P3c0 , data ) ;
83 OutPortByte( XGINew_P3c0 , 0x20 ) ;
84}*/
85
86
87/* --------------------------------------------------------------------- */
88/* Function : */
89/* Input : */
90/* Output : */
91/* Description : */
92/* --------------------------------------------------------------------- */
93void XGINew_SetReg3( ULONG port , USHORT data )
94{
95 OutPortByte( port , data ) ;
96}
97
98
99/* --------------------------------------------------------------------- */
100/* Function : XGINew_SetReg4 */
101/* Input : */
102/* Output : */
103/* Description : */
104/* --------------------------------------------------------------------- */
105void XGINew_SetReg4( ULONG port , ULONG data )
106{
107 OutPortLong( port , data ) ;
108}
109
110
111/* --------------------------------------------------------------------- */
112/* Function : XGINew_GetReg1 */
113/* Input : */
114/* Output : */
115/* Description : */
116/* --------------------------------------------------------------------- */
117UCHAR XGINew_GetReg1( ULONG port , USHORT index )
118{
119 UCHAR data ;
120
121#ifdef LINUX_XF86
122 OutPortByte( ( PUCHAR )(ULONG)port , index ) ;
123 data = InPortByte( ( PUCHAR )(ULONG)port + 1 ) ;
124#else
125 OutPortByte( port , index ) ;
126 data = InPortByte( port + 1 ) ;
127#endif
128
129 return( data ) ;
130}
131
132
133/* --------------------------------------------------------------------- */
134/* Function : XGINew_GetReg2 */
135/* Input : */
136/* Output : */
137/* Description : */
138/* --------------------------------------------------------------------- */
139UCHAR XGINew_GetReg2( ULONG port )
140{
141 UCHAR data ;
142
143 data = InPortByte( port ) ;
144
145 return( data ) ;
146}
147
148
149/* --------------------------------------------------------------------- */
150/* Function : XGINew_GetReg3 */
151/* Input : */
152/* Output : */
153/* Description : */
154/* --------------------------------------------------------------------- */
155ULONG XGINew_GetReg3( ULONG port )
156{
157 ULONG data ;
158
159 data = InPortLong( port ) ;
160
161 return( data ) ;
162}
163
164
165
166/* --------------------------------------------------------------------- */
167/* Function : XGINew_SetRegANDOR */
168/* Input : */
169/* Output : */
170/* Description : */
171/* --------------------------------------------------------------------- */
172void XGINew_SetRegANDOR( ULONG Port , USHORT Index , USHORT DataAND , USHORT DataOR )
173{
174 USHORT temp ;
175
176 temp = XGINew_GetReg1( Port , Index ) ; /* XGINew_Part1Port index 02 */
177 temp = ( temp & ( DataAND ) ) | DataOR ;
178 XGINew_SetReg1( Port , Index , temp ) ;
179}
180
181
182/* --------------------------------------------------------------------- */
183/* Function : XGINew_SetRegAND */
184/* Input : */
185/* Output : */
186/* Description : */
187/* --------------------------------------------------------------------- */
188void XGINew_SetRegAND(ULONG Port,USHORT Index,USHORT DataAND)
189{
190 USHORT temp ;
191
192 temp = XGINew_GetReg1( Port , Index ) ; /* XGINew_Part1Port index 02 */
193 temp &= DataAND ;
194 XGINew_SetReg1( Port , Index , temp ) ;
195}
196
197
198/* --------------------------------------------------------------------- */
199/* Function : XGINew_SetRegOR */
200/* Input : */
201/* Output : */
202/* Description : */
203/* --------------------------------------------------------------------- */
204void XGINew_SetRegOR( ULONG Port , USHORT Index , USHORT DataOR )
205{
206 USHORT temp ;
207
208 temp = XGINew_GetReg1( Port , Index ) ; /* XGINew_Part1Port index 02 */
209 temp |= DataOR ;
210 XGINew_SetReg1( Port , Index , temp ) ;
211}
212
213
214/* --------------------------------------------------------------------- */
215/* Function : NewDelaySecond */
216/* Input : */
217/* Output : */
218/* Description : */
219/* --------------------------------------------------------------------- */
220void NewDelaySeconds( int seconds )
221{
222#ifdef WIN2000
223 int j ;
224#endif
225 int i ;
226
227
228 for( i = 0 ; i < seconds ; i++ )
229 {
230#ifdef TC
231 delay( 1000 ) ;
232#endif
233
234#ifdef WIN2000
235
236 for ( j = 0 ; j < 20000 ; j++ )
237 VideoPortStallExecution( 50 ) ;
238#endif
239
240#ifdef WINCE_HEADER
241#endif
242
243#ifdef LINUX_KERNEL
244#endif
245 }
246}
247
248
249/* --------------------------------------------------------------------- */
250/* Function : Newdebugcode */
251/* Input : */
252/* Output : */
253/* Description : */
254/* --------------------------------------------------------------------- */
255void Newdebugcode( UCHAR code )
256{
257// OutPortByte ( 0x80 , code ) ;
258 /* OutPortByte ( 0x300 , code ) ; */
259 /* NewDelaySeconds( 0x3 ) ; */
260}
261
262
263
diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h
new file mode 100644
index 000000000000..91779d8cfdc6
--- /dev/null
+++ b/drivers/staging/xgifb/vb_util.h
@@ -0,0 +1,15 @@
1#ifndef _VBUTIL_
2#define _VBUTIL_
3extern void NewDelaySeconds( int );
4extern void Newdebugcode( UCHAR );
5extern void XGINew_SetReg1(ULONG, USHORT, USHORT);
6extern void XGINew_SetReg3(ULONG, USHORT);
7extern UCHAR XGINew_GetReg1(ULONG, USHORT);
8extern UCHAR XGINew_GetReg2(ULONG);
9extern void XGINew_SetReg4(ULONG, ULONG);
10extern ULONG XGINew_GetReg3(ULONG);
11extern void XGINew_SetRegOR(ULONG Port,USHORT Index,USHORT DataOR);
12extern void XGINew_SetRegAND(ULONG Port,USHORT Index,USHORT DataAND);
13extern void XGINew_SetRegANDOR(ULONG Port,USHORT Index,USHORT DataAND,USHORT DataOR);
14#endif
15
diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h
new file mode 100644
index 000000000000..295ea860ae47
--- /dev/null
+++ b/drivers/staging/xgifb/vgatypes.h
@@ -0,0 +1,325 @@
1
2#ifndef _VGATYPES_
3#define _VGATYPES_
4
5#include "osdef.h"
6
7#ifdef LINUX_XF86
8#include "xf86Version.h"
9#include "xf86Pci.h"
10#endif
11
12#ifdef LINUX_KERNEL /* We don't want the X driver to depend on kernel source */
13#include <linux/ioctl.h>
14#endif
15
16#ifndef FALSE
17#define FALSE 0
18#endif
19
20#ifndef TRUE
21#define TRUE 1
22#endif
23
24#ifndef NULL
25#define NULL 0
26#endif
27
28#ifndef CHAR
29typedef char CHAR;
30#endif
31
32#ifndef SHORT
33typedef short SHORT;
34#endif
35
36#ifndef LONG
37typedef long LONG;
38#endif
39
40#ifndef UCHAR
41typedef unsigned char UCHAR;
42#endif
43
44#ifndef USHORT
45typedef unsigned short USHORT;
46#endif
47
48#ifndef ULONG
49typedef unsigned long ULONG;
50#endif
51
52#ifndef PUCHAR
53typedef UCHAR *PUCHAR;
54#endif
55
56#ifndef PUSHORT
57typedef USHORT *PUSHORT;
58#endif
59
60#ifndef PLONGU
61typedef ULONG *PULONG;
62#endif
63
64#ifndef VOID
65typedef void VOID;
66#endif
67
68#ifndef PVOID
69typedef void *PVOID;
70#endif
71
72#ifndef BOOLEAN
73typedef UCHAR BOOLEAN;
74#endif
75/*
76#ifndef bool
77typedef UCHAR bool;
78#endif
79*/
80#ifdef LINUX_KERNEL
81typedef unsigned long XGIIOADDRESS;
82#endif
83
84#ifdef LINUX_XF86
85#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
86typedef unsigned char IOADDRESS;
87typedef unsigned char XGIIOADDRESS;
88#else
89typedef IOADDRESS XGIIOADDRESS;
90#endif
91#endif
92
93#ifndef VBIOS_VER_MAX_LENGTH
94#define VBIOS_VER_MAX_LENGTH 4
95#endif
96
97#ifndef WIN2000
98
99#ifndef LINUX_KERNEL /* For the linux kernel, this is defined in xgifb.h */
100#ifndef XGI_CHIP_TYPE
101typedef enum _XGI_CHIP_TYPE {
102 XGI_VGALegacy = 0,
103#ifdef LINUX_XF86
104 XGI_530,
105 XGI_OLD,
106#endif
107 XGI_300,
108 XGI_630,
109 XGI_640,
110 XGI_315H,
111 XGI_315,
112 XGI_315PRO,
113 XGI_550,
114 XGI_650,
115 XGI_650M,
116 XGI_740,
117 XGI_330,
118 XGI_661,
119 XGI_660,
120 XGI_760,
121 XG40 = 32,
122 XG41,
123 XG42,
124 XG45,
125 XG20 = 48,
126 XG21,
127 XG27,
128 MAX_XGI_CHIP
129} XGI_CHIP_TYPE;
130#endif
131#endif
132
133#ifndef XGI_VB_CHIP_TYPE
134typedef enum _XGI_VB_CHIP_TYPE {
135 VB_CHIP_Legacy = 0,
136 VB_CHIP_301,
137 VB_CHIP_301B,
138 VB_CHIP_301LV,
139 VB_CHIP_302,
140 VB_CHIP_302B,
141 VB_CHIP_302LV,
142 VB_CHIP_301C,
143 VB_CHIP_302ELV,
144 VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
145 MAX_VB_CHIP
146} XGI_VB_CHIP_TYPE;
147#endif
148
149#ifndef XGI_LCD_TYPE
150typedef enum _XGI_LCD_TYPE {
151 LCD_INVALID = 0,
152 LCD_320x480, /* FSTN, DSTN */
153 LCD_640x480,
154 LCD_640x480_2, /* FSTN, DSTN */
155 LCD_640x480_3, /* FSTN, DSTN */
156 LCD_800x600,
157 LCD_848x480,
158 LCD_1024x600,
159 LCD_1024x768,
160 LCD_1152x768,
161 LCD_1152x864,
162 LCD_1280x720,
163 LCD_1280x768,
164 LCD_1280x800,
165 LCD_1280x960,
166 LCD_1280x1024,
167 LCD_1400x1050,
168 LCD_1600x1200,
169 LCD_1680x1050,
170 LCD_1920x1440,
171 LCD_2048x1536,
172 LCD_CUSTOM,
173 LCD_UNKNOWN
174} XGI_LCD_TYPE;
175#endif
176
177#endif /* not WIN2000 */
178
179#ifndef PXGI_DSReg
180typedef struct _XGI_DSReg
181{
182 UCHAR jIdx;
183 UCHAR jVal;
184} XGI_DSReg, *PXGI_DSReg;
185#endif
186
187#ifndef XGI_HW_DEVICE_INFO
188
189typedef struct _XGI_HW_DEVICE_INFO XGI_HW_DEVICE_INFO, *PXGI_HW_DEVICE_INFO;
190
191typedef BOOLEAN (*PXGI_QUERYSPACE) (PXGI_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
192
193struct _XGI_HW_DEVICE_INFO
194{
195 ULONG ulExternalChip; /* NO VB or other video bridge*/
196 /* if ujVBChipID = VB_CHIP_UNKNOWN, */
197#ifdef LINUX_XF86
198 PCITAG PciTag; /* PCI Tag */
199#endif
200
201 PUCHAR pjVirtualRomBase; /* ROM image */
202
203 BOOLEAN UseROM; /* Use the ROM image if provided */
204
205 PVOID pDevice;
206
207 PUCHAR pjVideoMemoryAddress;/* base virtual memory address */
208 /* of Linear VGA memory */
209
210 ULONG ulVideoMemorySize; /* size, in bytes, of the memory on the board */
211
212 PUCHAR pjIOAddress; /* base I/O address of VGA ports (0x3B0) */
213
214 PUCHAR pjCustomizedROMImage;
215
216 PUCHAR pj2ndVideoMemoryAddress;
217 ULONG ul2ndVideoMemorySize;
218
219 PUCHAR pj2ndIOAddress;
220/*#ifndef WIN2000
221 XGIIOADDRESS pjIOAddress; // base I/O address of VGA ports (0x3B0)
222#endif */
223 UCHAR jChipType; /* Used to Identify Graphics Chip */
224 /* defined in the data structure type */
225 /* "XGI_CHIP_TYPE" */
226
227 UCHAR jChipRevision; /* Used to Identify Graphics Chip Revision */
228
229 UCHAR ujVBChipID; /* the ID of video bridge */
230 /* defined in the data structure type */
231 /* "XGI_VB_CHIP_TYPE" */
232
233 BOOLEAN bNewScratch;
234
235 ULONG ulCRT2LCDType; /* defined in the data structure type */
236
237 ULONG usExternalChip; /* NO VB or other video bridge (other than */
238 /* video bridge) */
239
240 BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
241
242 BOOLEAN bSkipDramSizing; /* True: Skip video memory sizing. */
243
244 BOOLEAN bSkipSense;
245
246 BOOLEAN bIsPowerSaving; /* True: XGIInit() is invoked by power management,
247 otherwise by 2nd adapter's initialzation */
248
249 PXGI_DSReg pSR; /* restore SR registers in initial function. */
250 /* end data :(idx, val) = (FF, FF). */
251 /* Note : restore SR registers if */
252 /* bSkipDramSizing = TRUE */
253
254 PXGI_DSReg pCR; /* restore CR registers in initial function. */
255 /* end data :(idx, val) = (FF, FF) */
256 /* Note : restore cR registers if */
257 /* bSkipDramSizing = TRUE */
258/*
259#endif
260*/
261
262 PXGI_QUERYSPACE pQueryVGAConfigSpace;
263
264 PXGI_QUERYSPACE pQueryNorthBridgeSpace;
265
266 UCHAR szVBIOSVer[VBIOS_VER_MAX_LENGTH];
267
268};
269#endif
270
271/* Addtional IOCTL for communication xgifb <> X driver */
272/* If changing this, xgifb.h must also be changed (for xgifb) */
273
274#ifdef LINUX_XF86 /* We don't want the X driver to depend on the kernel source */
275
276/* ioctl for identifying and giving some info (esp. memory heap start) */
277#define XGIFB_GET_INFO 0x80046ef8 /* Wow, what a terrible hack... */
278
279/* Structure argument for XGIFB_GET_INFO ioctl */
280typedef struct _XGIFB_INFO xgifb_info, *pxgifb_info;
281
282struct _XGIFB_INFO {
283 CARD32 xgifb_id; /* for identifying xgifb */
284#ifndef XGIFB_ID
285#define XGIFB_ID 0x53495346 /* Identify myself with 'XGIF' */
286#endif
287 CARD32 chip_id; /* PCI ID of detected chip */
288 CARD32 memory; /* video memory in KB which xgifb manages */
289 CARD32 heapstart; /* heap start (= xgifb "mem" argument) in KB */
290 CARD8 fbvidmode; /* current xgifb mode */
291
292 CARD8 xgifb_version;
293 CARD8 xgifb_revision;
294 CARD8 xgifb_patchlevel;
295
296 CARD8 xgifb_caps; /* xgifb's capabilities */
297
298 CARD32 xgifb_tqlen; /* turbo queue length (in KB) */
299
300 CARD32 xgifb_pcibus; /* The card's PCI ID */
301 CARD32 xgifb_pcislot;
302 CARD32 xgifb_pcifunc;
303
304 CARD8 xgifb_lcdpdc;
305
306 CARD8 xgifb_lcda;
307
308 CARD32 xgifb_vbflags;
309 CARD32 xgifb_currentvbflags;
310
311 CARD32 xgifb_scalelcd;
312 CARD32 xgifb_specialtiming;
313
314 CARD8 xgifb_haveemi;
315 CARD8 xgifb_emi30,xgifb_emi31,xgifb_emi32,xgifb_emi33;
316 CARD8 xgifb_haveemilcd;
317
318 CARD8 xgifb_lcdpdca;
319
320 CARD8 reserved[212]; /* for future use */
321};
322#endif
323
324#endif
325
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 0c2f14ff9696..61d75507d5d0 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1201,7 +1201,7 @@ made_compressed_probe:
1201 if (rcv->urb == NULL) { 1201 if (rcv->urb == NULL) {
1202 dev_dbg(&intf->dev, 1202 dev_dbg(&intf->dev,
1203 "out of memory (read urbs usb_alloc_urb)\n"); 1203 "out of memory (read urbs usb_alloc_urb)\n");
1204 goto alloc_fail7; 1204 goto alloc_fail6;
1205 } 1205 }
1206 1206
1207 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1207 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -1225,7 +1225,7 @@ made_compressed_probe:
1225 if (snd->urb == NULL) { 1225 if (snd->urb == NULL) {
1226 dev_dbg(&intf->dev, 1226 dev_dbg(&intf->dev,
1227 "out of memory (write urbs usb_alloc_urb)"); 1227 "out of memory (write urbs usb_alloc_urb)");
1228 goto alloc_fail7; 1228 goto alloc_fail8;
1229 } 1229 }
1230 1230
1231 if (usb_endpoint_xfer_int(epwrite)) 1231 if (usb_endpoint_xfer_int(epwrite))
@@ -1264,6 +1264,7 @@ made_compressed_probe:
1264 i = device_create_file(&intf->dev, 1264 i = device_create_file(&intf->dev,
1265 &dev_attr_iCountryCodeRelDate); 1265 &dev_attr_iCountryCodeRelDate);
1266 if (i < 0) { 1266 if (i < 0) {
1267 device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
1267 kfree(acm->country_codes); 1268 kfree(acm->country_codes);
1268 goto skip_countries; 1269 goto skip_countries;
1269 } 1270 }
@@ -1300,6 +1301,7 @@ alloc_fail8:
1300 usb_free_urb(acm->wb[i].urb); 1301 usb_free_urb(acm->wb[i].urb);
1301alloc_fail7: 1302alloc_fail7:
1302 acm_read_buffers_free(acm); 1303 acm_read_buffers_free(acm);
1304alloc_fail6:
1303 for (i = 0; i < num_rx_buf; i++) 1305 for (i = 0; i < num_rx_buf; i++)
1304 usb_free_urb(acm->ru[i].urb); 1306 usb_free_urb(acm->ru[i].urb);
1305 usb_free_urb(acm->ctrlurb); 1307 usb_free_urb(acm->ctrlurb);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index ded550eda5d9..de98a94d1853 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1328,6 +1328,7 @@ int usb_resume(struct device *dev, pm_message_t msg)
1328 1328
1329 /* For all other calls, take the device back to full power and 1329 /* For all other calls, take the device back to full power and
1330 * tell the PM core in case it was autosuspended previously. 1330 * tell the PM core in case it was autosuspended previously.
1331 * Unbind the interfaces that will need rebinding later.
1331 */ 1332 */
1332 } else { 1333 } else {
1333 status = usb_resume_both(udev, msg); 1334 status = usb_resume_both(udev, msg);
@@ -1336,6 +1337,7 @@ int usb_resume(struct device *dev, pm_message_t msg)
1336 pm_runtime_set_active(dev); 1337 pm_runtime_set_active(dev);
1337 pm_runtime_enable(dev); 1338 pm_runtime_enable(dev);
1338 udev->last_busy = jiffies; 1339 udev->last_busy = jiffies;
1340 do_unbind_rebind(udev, DO_REBIND);
1339 } 1341 }
1340 } 1342 }
1341 1343
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 649c0c5f7158..591ae9fde199 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -295,6 +295,7 @@ config USB_GADGET_S3C_HSOTG
295 boolean "S3C HS/OtG USB Device controller" 295 boolean "S3C HS/OtG USB Device controller"
296 depends on S3C_DEV_USB_HSOTG 296 depends on S3C_DEV_USB_HSOTG
297 select USB_GADGET_S3C_HSOTG_PIO 297 select USB_GADGET_S3C_HSOTG_PIO
298 select USB_GADGET_DUALSPEED
298 help 299 help
299 The Samsung S3C64XX USB2.0 high-speed gadget controller 300 The Samsung S3C64XX USB2.0 high-speed gadget controller
300 integrated into the S3C64XX series SoC. 301 integrated into the S3C64XX series SoC.
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c
index 43bf44514c41..b91115f84b13 100644
--- a/drivers/usb/gadget/f_audio.c
+++ b/drivers/usb/gadget/f_audio.c
@@ -101,7 +101,7 @@ static struct uac_feature_unit_descriptor_0 feature_unit_desc = {
101static struct usb_audio_control mute_control = { 101static struct usb_audio_control mute_control = {
102 .list = LIST_HEAD_INIT(mute_control.list), 102 .list = LIST_HEAD_INIT(mute_control.list),
103 .name = "Mute Control", 103 .name = "Mute Control",
104 .type = UAC_MUTE_CONTROL, 104 .type = UAC_FU_MUTE,
105 /* Todo: add real Mute control code */ 105 /* Todo: add real Mute control code */
106 .set = generic_set_cmd, 106 .set = generic_set_cmd,
107 .get = generic_get_cmd, 107 .get = generic_get_cmd,
@@ -110,7 +110,7 @@ static struct usb_audio_control mute_control = {
110static struct usb_audio_control volume_control = { 110static struct usb_audio_control volume_control = {
111 .list = LIST_HEAD_INIT(volume_control.list), 111 .list = LIST_HEAD_INIT(volume_control.list),
112 .name = "Volume Control", 112 .name = "Volume Control",
113 .type = UAC_VOLUME_CONTROL, 113 .type = UAC_FU_VOLUME,
114 /* Todo: add real Volume control code */ 114 /* Todo: add real Volume control code */
115 .set = generic_set_cmd, 115 .set = generic_set_cmd,
116 .get = generic_get_cmd, 116 .get = generic_get_cmd,
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index 2928523268b5..82506ca297d5 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -2400,7 +2400,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver);
2400static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev) 2400static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev)
2401{ 2401{
2402 struct qe_udc *udc; 2402 struct qe_udc *udc;
2403 struct device_node *np = ofdev->node; 2403 struct device_node *np = ofdev->dev.of_node;
2404 unsigned int tmp_addr = 0; 2404 unsigned int tmp_addr = 0;
2405 struct usb_device_para __iomem *usbpram; 2405 struct usb_device_para __iomem *usbpram;
2406 unsigned int i; 2406 unsigned int i;
@@ -2525,7 +2525,7 @@ static void qe_udc_release(struct device *dev)
2525static int __devinit qe_udc_probe(struct of_device *ofdev, 2525static int __devinit qe_udc_probe(struct of_device *ofdev,
2526 const struct of_device_id *match) 2526 const struct of_device_id *match)
2527{ 2527{
2528 struct device_node *np = ofdev->node; 2528 struct device_node *np = ofdev->dev.of_node;
2529 struct qe_ep *ep; 2529 struct qe_ep *ep;
2530 unsigned int ret = 0; 2530 unsigned int ret = 0;
2531 unsigned int i; 2531 unsigned int i;
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h
index 8b960deed680..c3caf1ac73ce 100644
--- a/drivers/usb/gadget/m66592-udc.h
+++ b/drivers/usb/gadget/m66592-udc.h
@@ -537,35 +537,35 @@ struct m66592 {
537/*-------------------------------------------------------------------------*/ 537/*-------------------------------------------------------------------------*/
538static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset) 538static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset)
539{ 539{
540 return inw((unsigned long)m66592->reg + offset); 540 return ioread16(m66592->reg + offset);
541} 541}
542 542
543static inline void m66592_read_fifo(struct m66592 *m66592, 543static inline void m66592_read_fifo(struct m66592 *m66592,
544 unsigned long offset, 544 unsigned long offset,
545 void *buf, unsigned long len) 545 void *buf, unsigned long len)
546{ 546{
547 unsigned long fifoaddr = (unsigned long)m66592->reg + offset; 547 void __iomem *fifoaddr = m66592->reg + offset;
548 548
549 if (m66592->pdata->on_chip) { 549 if (m66592->pdata->on_chip) {
550 len = (len + 3) / 4; 550 len = (len + 3) / 4;
551 insl(fifoaddr, buf, len); 551 ioread32_rep(fifoaddr, buf, len);
552 } else { 552 } else {
553 len = (len + 1) / 2; 553 len = (len + 1) / 2;
554 insw(fifoaddr, buf, len); 554 ioread16_rep(fifoaddr, buf, len);
555 } 555 }
556} 556}
557 557
558static inline void m66592_write(struct m66592 *m66592, u16 val, 558static inline void m66592_write(struct m66592 *m66592, u16 val,
559 unsigned long offset) 559 unsigned long offset)
560{ 560{
561 outw(val, (unsigned long)m66592->reg + offset); 561 iowrite16(val, m66592->reg + offset);
562} 562}
563 563
564static inline void m66592_write_fifo(struct m66592 *m66592, 564static inline void m66592_write_fifo(struct m66592 *m66592,
565 unsigned long offset, 565 unsigned long offset,
566 void *buf, unsigned long len) 566 void *buf, unsigned long len)
567{ 567{
568 unsigned long fifoaddr = (unsigned long)m66592->reg + offset; 568 void __iomem *fifoaddr = m66592->reg + offset;
569 569
570 if (m66592->pdata->on_chip) { 570 if (m66592->pdata->on_chip) {
571 unsigned long count; 571 unsigned long count;
@@ -573,25 +573,25 @@ static inline void m66592_write_fifo(struct m66592 *m66592,
573 int i; 573 int i;
574 574
575 count = len / 4; 575 count = len / 4;
576 outsl(fifoaddr, buf, count); 576 iowrite32_rep(fifoaddr, buf, count);
577 577
578 if (len & 0x00000003) { 578 if (len & 0x00000003) {
579 pb = buf + count * 4; 579 pb = buf + count * 4;
580 for (i = 0; i < (len & 0x00000003); i++) { 580 for (i = 0; i < (len & 0x00000003); i++) {
581 if (m66592_read(m66592, M66592_CFBCFG)) /* le */ 581 if (m66592_read(m66592, M66592_CFBCFG)) /* le */
582 outb(pb[i], fifoaddr + (3 - i)); 582 iowrite8(pb[i], fifoaddr + (3 - i));
583 else 583 else
584 outb(pb[i], fifoaddr + i); 584 iowrite8(pb[i], fifoaddr + i);
585 } 585 }
586 } 586 }
587 } else { 587 } else {
588 unsigned long odd = len & 0x0001; 588 unsigned long odd = len & 0x0001;
589 589
590 len = len / 2; 590 len = len / 2;
591 outsw(fifoaddr, buf, len); 591 iowrite16_rep(fifoaddr, buf, len);
592 if (odd) { 592 if (odd) {
593 unsigned char *p = buf + len*2; 593 unsigned char *p = buf + len*2;
594 outb(*p, fifoaddr); 594 iowrite8(*p, fifoaddr);
595 } 595 }
596 } 596 }
597} 597}
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 888d8f166c0b..70a817842755 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -1500,7 +1500,7 @@ static int __exit r8a66597_remove(struct platform_device *pdev)
1500 struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); 1500 struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
1501 1501
1502 del_timer_sync(&r8a66597->timer); 1502 del_timer_sync(&r8a66597->timer);
1503 iounmap((void *)r8a66597->reg); 1503 iounmap(r8a66597->reg);
1504 free_irq(platform_get_irq(pdev, 0), r8a66597); 1504 free_irq(platform_get_irq(pdev, 0), r8a66597);
1505 r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); 1505 r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
1506#ifdef CONFIG_HAVE_CLK 1506#ifdef CONFIG_HAVE_CLK
@@ -1578,7 +1578,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
1578 init_timer(&r8a66597->timer); 1578 init_timer(&r8a66597->timer);
1579 r8a66597->timer.function = r8a66597_timer; 1579 r8a66597->timer.function = r8a66597_timer;
1580 r8a66597->timer.data = (unsigned long)r8a66597; 1580 r8a66597->timer.data = (unsigned long)r8a66597;
1581 r8a66597->reg = (unsigned long)reg; 1581 r8a66597->reg = reg;
1582 1582
1583#ifdef CONFIG_HAVE_CLK 1583#ifdef CONFIG_HAVE_CLK
1584 if (r8a66597->pdata->on_chip) { 1584 if (r8a66597->pdata->on_chip) {
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h
index 9a537aa07968..f763b5190afa 100644
--- a/drivers/usb/gadget/r8a66597-udc.h
+++ b/drivers/usb/gadget/r8a66597-udc.h
@@ -91,7 +91,7 @@ struct r8a66597_ep {
91 91
92struct r8a66597 { 92struct r8a66597 {
93 spinlock_t lock; 93 spinlock_t lock;
94 unsigned long reg; 94 void __iomem *reg;
95 95
96#ifdef CONFIG_HAVE_CLK 96#ifdef CONFIG_HAVE_CLK
97 struct clk *clk; 97 struct clk *clk;
@@ -127,7 +127,7 @@ struct r8a66597 {
127 127
128static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) 128static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
129{ 129{
130 return inw(r8a66597->reg + offset); 130 return ioread16(r8a66597->reg + offset);
131} 131}
132 132
133static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, 133static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
@@ -135,7 +135,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
135 unsigned char *buf, 135 unsigned char *buf,
136 int len) 136 int len)
137{ 137{
138 unsigned long fifoaddr = r8a66597->reg + offset; 138 void __iomem *fifoaddr = r8a66597->reg + offset;
139 unsigned int data; 139 unsigned int data;
140 int i; 140 int i;
141 141
@@ -144,7 +144,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
144 144
145 /* aligned buf case */ 145 /* aligned buf case */
146 if (len >= 4 && !((unsigned long)buf & 0x03)) { 146 if (len >= 4 && !((unsigned long)buf & 0x03)) {
147 insl(fifoaddr, buf, len / 4); 147 ioread32_rep(fifoaddr, buf, len / 4);
148 buf += len & ~0x03; 148 buf += len & ~0x03;
149 len &= 0x03; 149 len &= 0x03;
150 } 150 }
@@ -152,7 +152,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
152 /* unaligned buf case */ 152 /* unaligned buf case */
153 for (i = 0; i < len; i++) { 153 for (i = 0; i < len; i++) {
154 if (!(i & 0x03)) 154 if (!(i & 0x03))
155 data = inl(fifoaddr); 155 data = ioread32(fifoaddr);
156 156
157 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; 157 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
158 } 158 }
@@ -161,7 +161,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
161 161
162 /* aligned buf case */ 162 /* aligned buf case */
163 if (len >= 2 && !((unsigned long)buf & 0x01)) { 163 if (len >= 2 && !((unsigned long)buf & 0x01)) {
164 insw(fifoaddr, buf, len / 2); 164 ioread16_rep(fifoaddr, buf, len / 2);
165 buf += len & ~0x01; 165 buf += len & ~0x01;
166 len &= 0x01; 166 len &= 0x01;
167 } 167 }
@@ -169,7 +169,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
169 /* unaligned buf case */ 169 /* unaligned buf case */
170 for (i = 0; i < len; i++) { 170 for (i = 0; i < len; i++) {
171 if (!(i & 0x01)) 171 if (!(i & 0x01))
172 data = inw(fifoaddr); 172 data = ioread16(fifoaddr);
173 173
174 buf[i] = (data >> ((i & 0x01) * 8)) & 0xff; 174 buf[i] = (data >> ((i & 0x01) * 8)) & 0xff;
175 } 175 }
@@ -179,7 +179,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
179static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, 179static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
180 unsigned long offset) 180 unsigned long offset)
181{ 181{
182 outw(val, r8a66597->reg + offset); 182 iowrite16(val, r8a66597->reg + offset);
183} 183}
184 184
185static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, 185static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
@@ -187,21 +187,21 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
187 unsigned char *buf, 187 unsigned char *buf,
188 int len) 188 int len)
189{ 189{
190 unsigned long fifoaddr = r8a66597->reg + offset; 190 void __iomem *fifoaddr = r8a66597->reg + offset;
191 int adj = 0; 191 int adj = 0;
192 int i; 192 int i;
193 193
194 if (r8a66597->pdata->on_chip) { 194 if (r8a66597->pdata->on_chip) {
195 /* 32-bit access only if buf is 32-bit aligned */ 195 /* 32-bit access only if buf is 32-bit aligned */
196 if (len >= 4 && !((unsigned long)buf & 0x03)) { 196 if (len >= 4 && !((unsigned long)buf & 0x03)) {
197 outsl(fifoaddr, buf, len / 4); 197 iowrite32_rep(fifoaddr, buf, len / 4);
198 buf += len & ~0x03; 198 buf += len & ~0x03;
199 len &= 0x03; 199 len &= 0x03;
200 } 200 }
201 } else { 201 } else {
202 /* 16-bit access only if buf is 16-bit aligned */ 202 /* 16-bit access only if buf is 16-bit aligned */
203 if (len >= 2 && !((unsigned long)buf & 0x01)) { 203 if (len >= 2 && !((unsigned long)buf & 0x01)) {
204 outsw(fifoaddr, buf, len / 2); 204 iowrite16_rep(fifoaddr, buf, len / 2);
205 buf += len & ~0x01; 205 buf += len & ~0x01;
206 len &= 0x01; 206 len &= 0x01;
207 } 207 }
@@ -216,7 +216,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
216 } 216 }
217 217
218 for (i = 0; i < len; i++) 218 for (i = 0; i < len; i++)
219 outb(buf[i], fifoaddr + adj - (i & adj)); 219 iowrite8(buf[i], fifoaddr + adj - (i & adj));
220} 220}
221 221
222static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, 222static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 1f73b485732d..26193eceb323 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -297,6 +297,12 @@ static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg,
297 */ 297 */
298static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) 298static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
299{ 299{
300 unsigned int ep;
301 unsigned int addr;
302 unsigned int size;
303 int timeout;
304 u32 val;
305
300 /* the ryu 2.6.24 release ahs 306 /* the ryu 2.6.24 release ahs
301 writel(0x1C0, hsotg->regs + S3C_GRXFSIZ); 307 writel(0x1C0, hsotg->regs + S3C_GRXFSIZ);
302 writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) | 308 writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) |
@@ -310,6 +316,51 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
310 writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) | 316 writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) |
311 S3C_GNPTXFSIZ_NPTxFDep(0x1C0), 317 S3C_GNPTXFSIZ_NPTxFDep(0x1C0),
312 hsotg->regs + S3C_GNPTXFSIZ); 318 hsotg->regs + S3C_GNPTXFSIZ);
319
320 /* arange all the rest of the TX FIFOs, as some versions of this
321 * block have overlapping default addresses. This also ensures
322 * that if the settings have been changed, then they are set to
323 * known values. */
324
325 /* start at the end of the GNPTXFSIZ, rounded up */
326 addr = 2048 + 1024;
327 size = 768;
328
329 /* currently we allocate TX FIFOs for all possible endpoints,
330 * and assume that they are all the same size. */
331
332 for (ep = 0; ep <= 15; ep++) {
333 val = addr;
334 val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
335 addr += size;
336
337 writel(val, hsotg->regs + S3C_DPTXFSIZn(ep));
338 }
339
340 /* according to p428 of the design guide, we need to ensure that
341 * all fifos are flushed before continuing */
342
343 writel(S3C_GRSTCTL_TxFNum(0x10) | S3C_GRSTCTL_TxFFlsh |
344 S3C_GRSTCTL_RxFFlsh, hsotg->regs + S3C_GRSTCTL);
345
346 /* wait until the fifos are both flushed */
347 timeout = 100;
348 while (1) {
349 val = readl(hsotg->regs + S3C_GRSTCTL);
350
351 if ((val & (S3C_GRSTCTL_TxFFlsh | S3C_GRSTCTL_RxFFlsh)) == 0)
352 break;
353
354 if (--timeout == 0) {
355 dev_err(hsotg->dev,
356 "%s: timeout flushing fifos (GRSTCTL=%08x)\n",
357 __func__, val);
358 }
359
360 udelay(1);
361 }
362
363 dev_dbg(hsotg->dev, "FIFOs reset, timeout at %d\n", timeout);
313} 364}
314 365
315/** 366/**
@@ -2574,6 +2625,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
2574 writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK, 2625 writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK,
2575 hsotg->regs + S3C_DCTL); 2626 hsotg->regs + S3C_DCTL);
2576 2627
2628 /* must be at-least 3ms to allow bus to see disconnect */
2629 msleep(3);
2630
2577 /* remove the soft-disconnect and let's go */ 2631 /* remove the soft-disconnect and let's go */
2578 __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); 2632 __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
2579 2633
@@ -2730,6 +2784,9 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
2730 2784
2731 writel(0, hsotg->regs + S3C_DAINTMSK); 2785 writel(0, hsotg->regs + S3C_DAINTMSK);
2732 2786
2787 /* Be in disconnected state until gadget is registered */
2788 __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
2789
2733 if (0) { 2790 if (0) {
2734 /* post global nak until we're ready */ 2791 /* post global nak until we're ready */
2735 writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak, 2792 writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak,
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index ef3e88f0b3c3..a3ef2a9d9dc2 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1135,7 +1135,7 @@ MODULE_LICENSE ("GPL");
1135 1135
1136#ifdef CONFIG_XPS_USB_HCD_XILINX 1136#ifdef CONFIG_XPS_USB_HCD_XILINX
1137#include "ehci-xilinx-of.c" 1137#include "ehci-xilinx-of.c"
1138#define OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver 1138#define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver
1139#endif 1139#endif
1140 1140
1141#ifdef CONFIG_PLAT_ORION 1141#ifdef CONFIG_PLAT_ORION
@@ -1159,7 +1159,8 @@ MODULE_LICENSE ("GPL");
1159#endif 1159#endif
1160 1160
1161#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ 1161#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
1162 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) 1162 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
1163 !defined(XILINX_OF_PLATFORM_DRIVER)
1163#error "missing bus glue for ehci-hcd" 1164#error "missing bus glue for ehci-hcd"
1164#endif 1165#endif
1165 1166
@@ -1213,10 +1214,20 @@ static int __init ehci_hcd_init(void)
1213 if (retval < 0) 1214 if (retval < 0)
1214 goto clean3; 1215 goto clean3;
1215#endif 1216#endif
1217
1218#ifdef XILINX_OF_PLATFORM_DRIVER
1219 retval = of_register_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
1220 if (retval < 0)
1221 goto clean4;
1222#endif
1216 return retval; 1223 return retval;
1217 1224
1225#ifdef XILINX_OF_PLATFORM_DRIVER
1226 /* of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); */
1227clean4:
1228#endif
1218#ifdef OF_PLATFORM_DRIVER 1229#ifdef OF_PLATFORM_DRIVER
1219 /* of_unregister_platform_driver(&OF_PLATFORM_DRIVER); */ 1230 of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
1220clean3: 1231clean3:
1221#endif 1232#endif
1222#ifdef PS3_SYSTEM_BUS_DRIVER 1233#ifdef PS3_SYSTEM_BUS_DRIVER
@@ -1243,6 +1254,9 @@ module_init(ehci_hcd_init);
1243 1254
1244static void __exit ehci_hcd_cleanup(void) 1255static void __exit ehci_hcd_cleanup(void)
1245{ 1256{
1257#ifdef XILINX_OF_PLATFORM_DRIVER
1258 of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
1259#endif
1246#ifdef OF_PLATFORM_DRIVER 1260#ifdef OF_PLATFORM_DRIVER
1247 of_unregister_platform_driver(&OF_PLATFORM_DRIVER); 1261 of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
1248#endif 1262#endif
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c
index 013972bbde57..4899f451add9 100644
--- a/drivers/usb/host/ehci-xilinx-of.c
+++ b/drivers/usb/host/ehci-xilinx-of.c
@@ -151,7 +151,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
151static int __devinit 151static int __devinit
152ehci_hcd_xilinx_of_probe(struct of_device *op, const struct of_device_id *match) 152ehci_hcd_xilinx_of_probe(struct of_device *op, const struct of_device_id *match)
153{ 153{
154 struct device_node *dn = op->node; 154 struct device_node *dn = op->dev.of_node;
155 struct usb_hcd *hcd; 155 struct usb_hcd *hcd;
156 struct ehci_hcd *ehci; 156 struct ehci_hcd *ehci;
157 struct resource res; 157 struct resource res;
diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h
index 5151516ea1de..d995351f9bed 100644
--- a/drivers/usb/host/isp1362.h
+++ b/drivers/usb/host/isp1362.h
@@ -65,7 +65,7 @@ static inline void delayed_insw(unsigned int addr, void *buf, int len)
65 unsigned short *bp = (unsigned short *)buf; 65 unsigned short *bp = (unsigned short *)buf;
66 while (len--) { 66 while (len--) {
67 DUMMY_DELAY_ACCESS; 67 DUMMY_DELAY_ACCESS;
68 *bp++ = inw((void *)addr); 68 *bp++ = inw(addr);
69 } 69 }
70} 70}
71 71
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 6db57ab6079d..1a2bb4ce638f 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2404,7 +2404,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
2404 2404
2405 del_timer_sync(&r8a66597->rh_timer); 2405 del_timer_sync(&r8a66597->rh_timer);
2406 usb_remove_hcd(hcd); 2406 usb_remove_hcd(hcd);
2407 iounmap((void *)r8a66597->reg); 2407 iounmap(r8a66597->reg);
2408#ifdef CONFIG_HAVE_CLK 2408#ifdef CONFIG_HAVE_CLK
2409 if (r8a66597->pdata->on_chip) 2409 if (r8a66597->pdata->on_chip)
2410 clk_put(r8a66597->clk); 2410 clk_put(r8a66597->clk);
@@ -2496,7 +2496,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
2496 init_timer(&r8a66597->rh_timer); 2496 init_timer(&r8a66597->rh_timer);
2497 r8a66597->rh_timer.function = r8a66597_timer; 2497 r8a66597->rh_timer.function = r8a66597_timer;
2498 r8a66597->rh_timer.data = (unsigned long)r8a66597; 2498 r8a66597->rh_timer.data = (unsigned long)r8a66597;
2499 r8a66597->reg = (unsigned long)reg; 2499 r8a66597->reg = reg;
2500 2500
2501 /* make sure no interrupts are pending */ 2501 /* make sure no interrupts are pending */
2502 ret = r8a66597_clock_enable(r8a66597); 2502 ret = r8a66597_clock_enable(r8a66597);
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h
index 228e3fb23854..95d0f5adfdcf 100644
--- a/drivers/usb/host/r8a66597.h
+++ b/drivers/usb/host/r8a66597.h
@@ -112,7 +112,7 @@ struct r8a66597_root_hub {
112 112
113struct r8a66597 { 113struct r8a66597 {
114 spinlock_t lock; 114 spinlock_t lock;
115 unsigned long reg; 115 void __iomem *reg;
116#ifdef CONFIG_HAVE_CLK 116#ifdef CONFIG_HAVE_CLK
117 struct clk *clk; 117 struct clk *clk;
118#endif 118#endif
@@ -170,67 +170,67 @@ static inline struct urb *r8a66597_get_urb(struct r8a66597 *r8a66597,
170 170
171static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) 171static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
172{ 172{
173 return inw(r8a66597->reg + offset); 173 return ioread16(r8a66597->reg + offset);
174} 174}
175 175
176static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, 176static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
177 unsigned long offset, u16 *buf, 177 unsigned long offset, u16 *buf,
178 int len) 178 int len)
179{ 179{
180 unsigned long fifoaddr = r8a66597->reg + offset; 180 void __iomem *fifoaddr = r8a66597->reg + offset;
181 unsigned long count; 181 unsigned long count;
182 182
183 if (r8a66597->pdata->on_chip) { 183 if (r8a66597->pdata->on_chip) {
184 count = len / 4; 184 count = len / 4;
185 insl(fifoaddr, buf, count); 185 ioread32_rep(fifoaddr, buf, count);
186 186
187 if (len & 0x00000003) { 187 if (len & 0x00000003) {
188 unsigned long tmp = inl(fifoaddr); 188 unsigned long tmp = ioread32(fifoaddr);
189 memcpy((unsigned char *)buf + count * 4, &tmp, 189 memcpy((unsigned char *)buf + count * 4, &tmp,
190 len & 0x03); 190 len & 0x03);
191 } 191 }
192 } else { 192 } else {
193 len = (len + 1) / 2; 193 len = (len + 1) / 2;
194 insw(fifoaddr, buf, len); 194 ioread16_rep(fifoaddr, buf, len);
195 } 195 }
196} 196}
197 197
198static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, 198static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
199 unsigned long offset) 199 unsigned long offset)
200{ 200{
201 outw(val, r8a66597->reg + offset); 201 iowrite16(val, r8a66597->reg + offset);
202} 202}
203 203
204static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, 204static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
205 unsigned long offset, u16 *buf, 205 unsigned long offset, u16 *buf,
206 int len) 206 int len)
207{ 207{
208 unsigned long fifoaddr = r8a66597->reg + offset; 208 void __iomem *fifoaddr = r8a66597->reg + offset;
209 unsigned long count; 209 unsigned long count;
210 unsigned char *pb; 210 unsigned char *pb;
211 int i; 211 int i;
212 212
213 if (r8a66597->pdata->on_chip) { 213 if (r8a66597->pdata->on_chip) {
214 count = len / 4; 214 count = len / 4;
215 outsl(fifoaddr, buf, count); 215 iowrite32_rep(fifoaddr, buf, count);
216 216
217 if (len & 0x00000003) { 217 if (len & 0x00000003) {
218 pb = (unsigned char *)buf + count * 4; 218 pb = (unsigned char *)buf + count * 4;
219 for (i = 0; i < (len & 0x00000003); i++) { 219 for (i = 0; i < (len & 0x00000003); i++) {
220 if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND) 220 if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
221 outb(pb[i], fifoaddr + i); 221 iowrite8(pb[i], fifoaddr + i);
222 else 222 else
223 outb(pb[i], fifoaddr + 3 - i); 223 iowrite8(pb[i], fifoaddr + 3 - i);
224 } 224 }
225 } 225 }
226 } else { 226 } else {
227 int odd = len & 0x0001; 227 int odd = len & 0x0001;
228 228
229 len = len / 2; 229 len = len / 2;
230 outsw(fifoaddr, buf, len); 230 ioread16_rep(fifoaddr, buf, len);
231 if (unlikely(odd)) { 231 if (unlikely(odd)) {
232 buf = &buf[len]; 232 buf = &buf[len];
233 outb((unsigned char)*buf, fifoaddr); 233 iowrite8((unsigned char)*buf, fifoaddr);
234 } 234 }
235 } 235 }
236} 236}
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index edffd81fc253..11482b6b9381 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -78,6 +78,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
78 xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" 78 xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
79 " endpoint cmd after reset endpoint\n"); 79 " endpoint cmd after reset endpoint\n");
80 } 80 }
81 if (pdev->vendor == PCI_VENDOR_ID_NEC)
82 xhci->quirks |= XHCI_NEC_HOST;
81 83
82 /* Make sure the HC is halted. */ 84 /* Make sure the HC is halted. */
83 retval = xhci_halt(xhci); 85 retval = xhci_halt(xhci);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 36c858e5b529..9012098add6b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1071,6 +1071,15 @@ bandwidth_change:
1071 xhci_warn(xhci, "Reset device command completion " 1071 xhci_warn(xhci, "Reset device command completion "
1072 "for disabled slot %u\n", slot_id); 1072 "for disabled slot %u\n", slot_id);
1073 break; 1073 break;
1074 case TRB_TYPE(TRB_NEC_GET_FW):
1075 if (!(xhci->quirks & XHCI_NEC_HOST)) {
1076 xhci->error_bitmask |= 1 << 6;
1077 break;
1078 }
1079 xhci_dbg(xhci, "NEC firmware version %2x.%02x\n",
1080 NEC_FW_MAJOR(event->status),
1081 NEC_FW_MINOR(event->status));
1082 break;
1074 default: 1083 default:
1075 /* Skip over unknown commands on the event ring */ 1084 /* Skip over unknown commands on the event ring */
1076 xhci->error_bitmask |= 1 << 6; 1085 xhci->error_bitmask |= 1 << 6;
@@ -1079,6 +1088,17 @@ bandwidth_change:
1079 inc_deq(xhci, xhci->cmd_ring, false); 1088 inc_deq(xhci, xhci->cmd_ring, false);
1080} 1089}
1081 1090
1091static void handle_vendor_event(struct xhci_hcd *xhci,
1092 union xhci_trb *event)
1093{
1094 u32 trb_type;
1095
1096 trb_type = TRB_FIELD_TO_TYPE(event->generic.field[3]);
1097 xhci_dbg(xhci, "Vendor specific event TRB type = %u\n", trb_type);
1098 if (trb_type == TRB_NEC_CMD_COMP && (xhci->quirks & XHCI_NEC_HOST))
1099 handle_cmd_completion(xhci, &event->event_cmd);
1100}
1101
1082static void handle_port_status(struct xhci_hcd *xhci, 1102static void handle_port_status(struct xhci_hcd *xhci,
1083 union xhci_trb *event) 1103 union xhci_trb *event)
1084{ 1104{
@@ -1659,7 +1679,10 @@ void xhci_handle_event(struct xhci_hcd *xhci)
1659 update_ptrs = 0; 1679 update_ptrs = 0;
1660 break; 1680 break;
1661 default: 1681 default:
1662 xhci->error_bitmask |= 1 << 3; 1682 if ((event->event_cmd.flags & TRB_TYPE_BITMASK) >= TRB_TYPE(48))
1683 handle_vendor_event(xhci, event);
1684 else
1685 xhci->error_bitmask |= 1 << 3;
1663 } 1686 }
1664 /* Any of the above functions may drop and re-acquire the lock, so check 1687 /* Any of the above functions may drop and re-acquire the lock, so check
1665 * to make sure a watchdog timer didn't mark the host as non-responsive. 1688 * to make sure a watchdog timer didn't mark the host as non-responsive.
@@ -2378,6 +2401,12 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
2378 false); 2401 false);
2379} 2402}
2380 2403
2404int xhci_queue_vendor_command(struct xhci_hcd *xhci,
2405 u32 field1, u32 field2, u32 field3, u32 field4)
2406{
2407 return queue_command(xhci, field1, field2, field3, field4, false);
2408}
2409
2381/* Queue a reset device command TRB */ 2410/* Queue a reset device command TRB */
2382int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id) 2411int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id)
2383{ 2412{
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 40e0a0c221b8..27345cd04da0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -106,6 +106,33 @@ int xhci_halt(struct xhci_hcd *xhci)
106} 106}
107 107
108/* 108/*
109 * Set the run bit and wait for the host to be running.
110 */
111int xhci_start(struct xhci_hcd *xhci)
112{
113 u32 temp;
114 int ret;
115
116 temp = xhci_readl(xhci, &xhci->op_regs->command);
117 temp |= (CMD_RUN);
118 xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
119 temp);
120 xhci_writel(xhci, temp, &xhci->op_regs->command);
121
122 /*
123 * Wait for the HCHalted Status bit to be 0 to indicate the host is
124 * running.
125 */
126 ret = handshake(xhci, &xhci->op_regs->status,
127 STS_HALT, 0, XHCI_MAX_HALT_USEC);
128 if (ret == -ETIMEDOUT)
129 xhci_err(xhci, "Host took too long to start, "
130 "waited %u microseconds.\n",
131 XHCI_MAX_HALT_USEC);
132 return ret;
133}
134
135/*
109 * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. 136 * Reset a halted HC, and set the internal HC state to HC_STATE_HALT.
110 * 137 *
111 * This resets pipelines, timers, counters, state machines, etc. 138 * This resets pipelines, timers, counters, state machines, etc.
@@ -116,6 +143,7 @@ int xhci_reset(struct xhci_hcd *xhci)
116{ 143{
117 u32 command; 144 u32 command;
118 u32 state; 145 u32 state;
146 int ret;
119 147
120 state = xhci_readl(xhci, &xhci->op_regs->status); 148 state = xhci_readl(xhci, &xhci->op_regs->status);
121 if ((state & STS_HALT) == 0) { 149 if ((state & STS_HALT) == 0) {
@@ -130,7 +158,17 @@ int xhci_reset(struct xhci_hcd *xhci)
130 /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ 158 /* XXX: Why does EHCI set this here? Shouldn't other code do this? */
131 xhci_to_hcd(xhci)->state = HC_STATE_HALT; 159 xhci_to_hcd(xhci)->state = HC_STATE_HALT;
132 160
133 return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); 161 ret = handshake(xhci, &xhci->op_regs->command,
162 CMD_RESET, 0, 250 * 1000);
163 if (ret)
164 return ret;
165
166 xhci_dbg(xhci, "Wait for controller to be ready for doorbell rings\n");
167 /*
168 * xHCI cannot write to any doorbells or operational registers other
169 * than status until the "Controller Not Ready" flag is cleared.
170 */
171 return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000);
134} 172}
135 173
136 174
@@ -448,17 +486,20 @@ int xhci_run(struct usb_hcd *hcd)
448 486
449 if (NUM_TEST_NOOPS > 0) 487 if (NUM_TEST_NOOPS > 0)
450 doorbell = xhci_setup_one_noop(xhci); 488 doorbell = xhci_setup_one_noop(xhci);
489 if (xhci->quirks & XHCI_NEC_HOST)
490 xhci_queue_vendor_command(xhci, 0, 0, 0,
491 TRB_TYPE(TRB_NEC_GET_FW));
492
493 if (xhci_start(xhci)) {
494 xhci_halt(xhci);
495 return -ENODEV;
496 }
451 497
452 temp = xhci_readl(xhci, &xhci->op_regs->command);
453 temp |= (CMD_RUN);
454 xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
455 temp);
456 xhci_writel(xhci, temp, &xhci->op_regs->command);
457 /* Flush PCI posted writes */
458 temp = xhci_readl(xhci, &xhci->op_regs->command);
459 xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); 498 xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp);
460 if (doorbell) 499 if (doorbell)
461 (*doorbell)(xhci); 500 (*doorbell)(xhci);
501 if (xhci->quirks & XHCI_NEC_HOST)
502 xhci_ring_cmd_db(xhci);
462 503
463 xhci_dbg(xhci, "Finished xhci_run\n"); 504 xhci_dbg(xhci, "Finished xhci_run\n");
464 return 0; 505 return 0;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index dada2fb59261..8b4b7d39f79c 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -925,6 +925,7 @@ union xhci_trb {
925/* TRB bit mask */ 925/* TRB bit mask */
926#define TRB_TYPE_BITMASK (0xfc00) 926#define TRB_TYPE_BITMASK (0xfc00)
927#define TRB_TYPE(p) ((p) << 10) 927#define TRB_TYPE(p) ((p) << 10)
928#define TRB_FIELD_TO_TYPE(p) (((p) & TRB_TYPE_BITMASK) >> 10)
928/* TRB type IDs */ 929/* TRB type IDs */
929/* bulk, interrupt, isoc scatter/gather, and control data stage */ 930/* bulk, interrupt, isoc scatter/gather, and control data stage */
930#define TRB_NORMAL 1 931#define TRB_NORMAL 1
@@ -992,6 +993,14 @@ union xhci_trb {
992#define TRB_MFINDEX_WRAP 39 993#define TRB_MFINDEX_WRAP 39
993/* TRB IDs 40-47 reserved, 48-63 is vendor-defined */ 994/* TRB IDs 40-47 reserved, 48-63 is vendor-defined */
994 995
996/* Nec vendor-specific command completion event. */
997#define TRB_NEC_CMD_COMP 48
998/* Get NEC firmware revision. */
999#define TRB_NEC_GET_FW 49
1000
1001#define NEC_FW_MINOR(p) (((p) >> 0) & 0xff)
1002#define NEC_FW_MAJOR(p) (((p) >> 8) & 0xff)
1003
995/* 1004/*
996 * TRBS_PER_SEGMENT must be a multiple of 4, 1005 * TRBS_PER_SEGMENT must be a multiple of 4,
997 * since the command ring is 64-byte aligned. 1006 * since the command ring is 64-byte aligned.
@@ -1172,6 +1181,7 @@ struct xhci_hcd {
1172 unsigned int quirks; 1181 unsigned int quirks;
1173#define XHCI_LINK_TRB_QUIRK (1 << 0) 1182#define XHCI_LINK_TRB_QUIRK (1 << 0)
1174#define XHCI_RESET_EP_QUIRK (1 << 1) 1183#define XHCI_RESET_EP_QUIRK (1 << 1)
1184#define XHCI_NEC_HOST (1 << 2)
1175}; 1185};
1176 1186
1177/* For testing purposes */ 1187/* For testing purposes */
@@ -1379,6 +1389,8 @@ void xhci_set_hc_event_deq(struct xhci_hcd *xhci);
1379int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); 1389int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id);
1380int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, 1390int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
1381 u32 slot_id); 1391 u32 slot_id);
1392int xhci_queue_vendor_command(struct xhci_hcd *xhci,
1393 u32 field1, u32 field2, u32 field3, u32 field4);
1382int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, 1394int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id,
1383 unsigned int ep_index); 1395 unsigned int ep_index);
1384int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, 1396int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 3edda3ed822a..fd35f73b5721 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -1239,8 +1239,7 @@ static void digi_write_bulk_callback(struct urb *urb)
1239 1239
1240 /* port and serial sanity check */ 1240 /* port and serial sanity check */
1241 if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { 1241 if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
1242 dev_err(&port->dev, 1242 pr_err("%s: port or port->private is NULL, status=%d\n",
1243 "%s: port or port->private is NULL, status=%d\n",
1244 __func__, status); 1243 __func__, status);
1245 return; 1244 return;
1246 } 1245 }
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 050211afc07e..79dd1ae195e5 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -2005,6 +2005,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
2005 "urb failed to set to rts/cts flow control\n"); 2005 "urb failed to set to rts/cts flow control\n");
2006 } 2006 }
2007 2007
2008 /* raise DTR/RTS */
2009 set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
2008 } else { 2010 } else {
2009 /* 2011 /*
2010 * Xon/Xoff code 2012 * Xon/Xoff code
@@ -2052,6 +2054,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
2052 } 2054 }
2053 } 2055 }
2054 2056
2057 /* lower DTR/RTS */
2058 clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
2055 } 2059 }
2056 return; 2060 return;
2057} 2061}
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index f8424d1bfc1b..585b7e663740 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -730,7 +730,6 @@ static void mos7840_bulk_in_callback(struct urb *urb)
730 mos7840_port = urb->context; 730 mos7840_port = urb->context;
731 if (!mos7840_port) { 731 if (!mos7840_port) {
732 dbg("%s", "NULL mos7840_port pointer"); 732 dbg("%s", "NULL mos7840_port pointer");
733 mos7840_port->read_urb_busy = false;
734 return; 733 return;
735 } 734 }
736 735
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 1e6fec487973..3d94a1471724 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -8,6 +8,9 @@ menu "Graphics support"
8config HAVE_FB_ATMEL 8config HAVE_FB_ATMEL
9 bool 9 bool
10 10
11config HAVE_FB_IMX
12 bool
13
11source "drivers/char/agp/Kconfig" 14source "drivers/char/agp/Kconfig"
12 15
13source "drivers/gpu/vga/Kconfig" 16source "drivers/gpu/vga/Kconfig"
@@ -400,9 +403,6 @@ config FB_SA1100
400 If you plan to use the LCD display with your SA-1100 system, say 403 If you plan to use the LCD display with your SA-1100 system, say
401 Y here. 404 Y here.
402 405
403config HAVE_FB_IMX
404 bool
405
406config FB_IMX 406config FB_IMX
407 tristate "Motorola i.MX LCD support" 407 tristate "Motorola i.MX LCD support"
408 depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2) 408 depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2)
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
index 51fcc0a2c94a..e45833ce975b 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/aty/mach64_accel.c
@@ -242,7 +242,7 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
242void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 242void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
243{ 243{
244 struct atyfb_par *par = (struct atyfb_par *) info->par; 244 struct atyfb_par *par = (struct atyfb_par *) info->par;
245 u32 color = rect->color, dx = rect->dx, width = rect->width, rotation = 0; 245 u32 color, dx = rect->dx, width = rect->width, rotation = 0;
246 246
247 if (par->asleep) 247 if (par->asleep)
248 return; 248 return;
@@ -253,8 +253,11 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
253 return; 253 return;
254 } 254 }
255 255
256 color |= (rect->color << 8); 256 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
257 color |= (rect->color << 16); 257 info->fix.visual == FB_VISUAL_DIRECTCOLOR)
258 color = ((u32 *)(info->pseudo_palette))[rect->color];
259 else
260 color = rect->color;
258 261
259 if (info->var.bits_per_pixel == 24) { 262 if (info->var.bits_per_pixel == 24) {
260 /* In 24 bpp, the engine is in 8 bpp - this requires that all */ 263 /* In 24 bpp, the engine is in 8 bpp - this requires that all */
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 921ca37398f3..3ec24609151e 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -756,7 +756,6 @@ out:
756out1: 756out1:
757 backlight_device_unregister(bl); 757 backlight_device_unregister(bl);
758out2: 758out2:
759 i2c_set_clientdata(client, NULL);
760 kfree(data); 759 kfree(data);
761 760
762 return ret; 761 return ret;
@@ -776,7 +775,6 @@ static int __devexit adp8860_remove(struct i2c_client *client)
776 &adp8860_bl_attr_group); 775 &adp8860_bl_attr_group);
777 776
778 backlight_device_unregister(data->bl); 777 backlight_device_unregister(data->bl);
779 i2c_set_clientdata(client, NULL);
780 kfree(data); 778 kfree(data);
781 779
782 return 0; 780 return 0;
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index e03e60bbfd85..2a04b382ec48 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -119,7 +119,6 @@ static int __devinit tosa_bl_probe(struct i2c_client *client,
119 119
120err_reg: 120err_reg:
121 data->bl = NULL; 121 data->bl = NULL;
122 i2c_set_clientdata(client, NULL);
123err_gpio_dir: 122err_gpio_dir:
124 gpio_free(TOSA_GPIO_BL_C20MA); 123 gpio_free(TOSA_GPIO_BL_C20MA);
125err_gpio_bl: 124err_gpio_bl:
@@ -133,7 +132,6 @@ static int __devexit tosa_bl_remove(struct i2c_client *client)
133 132
134 backlight_device_unregister(data->bl); 133 backlight_device_unregister(data->bl);
135 data->bl = NULL; 134 data->bl = NULL;
136 i2c_set_clientdata(client, NULL);
137 135
138 gpio_free(TOSA_GPIO_BL_C20MA); 136 gpio_free(TOSA_GPIO_BL_C20MA);
139 137
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 2c371c07f0da..09f1b9b462f4 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -275,7 +275,7 @@ static int __devinit bw2_do_default_mode(struct bw2_par *par,
275 275
276static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match) 276static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match)
277{ 277{
278 struct device_node *dp = op->node; 278 struct device_node *dp = op->dev.of_node;
279 struct fb_info *info; 279 struct fb_info *info;
280 struct bw2_par *par; 280 struct bw2_par *par;
281 int linebytes, err; 281 int linebytes, err;
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index d12e05b6e63f..e5dc2241194f 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -465,7 +465,7 @@ static void cg14_unmap_regs(struct of_device *op, struct fb_info *info,
465 465
466static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match) 466static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match)
467{ 467{
468 struct device_node *dp = op->node; 468 struct device_node *dp = op->dev.of_node;
469 struct fb_info *info; 469 struct fb_info *info;
470 struct cg14_par *par; 470 struct cg14_par *par;
471 int is_8mb, linebytes, i, err; 471 int is_8mb, linebytes, i, err;
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index b98f93f7f663..558d73a948a0 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -349,7 +349,7 @@ static int __devinit cg3_do_default_mode(struct cg3_par *par)
349static int __devinit cg3_probe(struct of_device *op, 349static int __devinit cg3_probe(struct of_device *op,
350 const struct of_device_id *match) 350 const struct of_device_id *match)
351{ 351{
352 struct device_node *dp = op->node; 352 struct device_node *dp = op->dev.of_node;
353 struct fb_info *info; 353 struct fb_info *info;
354 struct cg3_par *par; 354 struct cg3_par *par;
355 int linebytes, err; 355 int linebytes, err;
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 073c9b408cf7..6b93ef93cb12 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -100,6 +100,16 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
100 /* protect against the workqueue changing the page list */ 100 /* protect against the workqueue changing the page list */
101 mutex_lock(&fbdefio->lock); 101 mutex_lock(&fbdefio->lock);
102 102
103 /*
104 * We want the page to remain locked from ->page_mkwrite until
105 * the PTE is marked dirty to avoid page_mkclean() being called
106 * before the PTE is updated, which would leave the page ignored
107 * by defio.
108 * Do this by locking the page here and informing the caller
109 * about it with VM_FAULT_LOCKED.
110 */
111 lock_page(page);
112
103 /* we loop through the pagelist before adding in order 113 /* we loop through the pagelist before adding in order
104 to keep the pagelist sorted */ 114 to keep the pagelist sorted */
105 list_for_each_entry(cur, &fbdefio->pagelist, lru) { 115 list_for_each_entry(cur, &fbdefio->pagelist, lru) {
@@ -121,7 +131,7 @@ page_already_added:
121 131
122 /* come back after delay to process the deferred IO */ 132 /* come back after delay to process the deferred IO */
123 schedule_delayed_work(&info->deferred_work, fbdefio->delay); 133 schedule_delayed_work(&info->deferred_work, fbdefio->delay);
124 return 0; 134 return VM_FAULT_LOCKED;
125} 135}
126 136
127static const struct vm_operations_struct fb_deferred_io_vm_ops = { 137static const struct vm_operations_struct fb_deferred_io_vm_ops = {
@@ -155,41 +165,25 @@ static void fb_deferred_io_work(struct work_struct *work)
155{ 165{
156 struct fb_info *info = container_of(work, struct fb_info, 166 struct fb_info *info = container_of(work, struct fb_info,
157 deferred_work.work); 167 deferred_work.work);
168 struct list_head *node, *next;
169 struct page *cur;
158 struct fb_deferred_io *fbdefio = info->fbdefio; 170 struct fb_deferred_io *fbdefio = info->fbdefio;
159 struct page *page, *tmp_page;
160 struct list_head *node, *tmp_node;
161 struct list_head non_dirty;
162
163 INIT_LIST_HEAD(&non_dirty);
164 171
165 /* here we mkclean the pages, then do all deferred IO */ 172 /* here we mkclean the pages, then do all deferred IO */
166 mutex_lock(&fbdefio->lock); 173 mutex_lock(&fbdefio->lock);
167 list_for_each_entry_safe(page, tmp_page, &fbdefio->pagelist, lru) { 174 list_for_each_entry(cur, &fbdefio->pagelist, lru) {
168 lock_page(page); 175 lock_page(cur);
169 /* 176 page_mkclean(cur);
170 * The workqueue callback can be triggered after a 177 unlock_page(cur);
171 * ->page_mkwrite() call but before the PTE has been marked
172 * dirty. In this case page_mkclean() won't "rearm" the page.
173 *
174 * To avoid this, remove those "non-dirty" pages from the
175 * pagelist before calling the driver's callback, then add
176 * them back to get processed on the next work iteration.
177 * At that time, their PTEs will hopefully be dirty for real.
178 */
179 if (!page_mkclean(page))
180 list_move_tail(&page->lru, &non_dirty);
181 unlock_page(page);
182 } 178 }
183 179
184 /* driver's callback with pagelist */ 180 /* driver's callback with pagelist */
185 fbdefio->deferred_io(info, &fbdefio->pagelist); 181 fbdefio->deferred_io(info, &fbdefio->pagelist);
186 182
187 /* clear the list... */ 183 /* clear the list */
188 list_for_each_safe(node, tmp_node, &fbdefio->pagelist) { 184 list_for_each_safe(node, next, &fbdefio->pagelist) {
189 list_del(node); 185 list_del(node);
190 } 186 }
191 /* ... and add back the "non-dirty" pages to the list */
192 list_splice_tail(&non_dirty, &fbdefio->pagelist);
193 mutex_unlock(&fbdefio->lock); 187 mutex_unlock(&fbdefio->lock);
194} 188}
195 189
@@ -218,7 +212,6 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open);
218void fb_deferred_io_cleanup(struct fb_info *info) 212void fb_deferred_io_cleanup(struct fb_info *info)
219{ 213{
220 struct fb_deferred_io *fbdefio = info->fbdefio; 214 struct fb_deferred_io *fbdefio = info->fbdefio;
221 struct list_head *node, *tmp_node;
222 struct page *page; 215 struct page *page;
223 int i; 216 int i;
224 217
@@ -226,13 +219,6 @@ void fb_deferred_io_cleanup(struct fb_info *info)
226 cancel_delayed_work(&info->deferred_work); 219 cancel_delayed_work(&info->deferred_work);
227 flush_scheduled_work(); 220 flush_scheduled_work();
228 221
229 /* the list may have still some non-dirty pages at this point */
230 mutex_lock(&fbdefio->lock);
231 list_for_each_safe(node, tmp_node, &fbdefio->pagelist) {
232 list_del(node);
233 }
234 mutex_unlock(&fbdefio->lock);
235
236 /* clear out the mapping that we setup */ 222 /* clear out the mapping that we setup */
237 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { 223 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
238 page = fb_deferred_io_page(info, i); 224 page = fb_deferred_io_page(info, i);
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 3d7895316eaf..9e8bf7d5e249 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -550,7 +550,7 @@ static void leo_unmap_regs(struct of_device *op, struct fb_info *info,
550static int __devinit leo_probe(struct of_device *op, 550static int __devinit leo_probe(struct of_device *op,
551 const struct of_device_id *match) 551 const struct of_device_id *match)
552{ 552{
553 struct device_node *dp = op->node; 553 struct device_node *dp = op->dev.of_node;
554 struct fb_info *info; 554 struct fb_info *info;
555 struct leo_par *par; 555 struct leo_par *par;
556 int linebytes, err; 556 int linebytes, err;
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c
index 0540de4f5cb4..4e2b8cc3d460 100644
--- a/drivers/video/mb862xx/mb862xxfb.c
+++ b/drivers/video/mb862xx/mb862xxfb.c
@@ -553,7 +553,7 @@ static int mb862xx_gdc_init(struct mb862xxfb_par *par)
553static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev, 553static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev,
554 const struct of_device_id *id) 554 const struct of_device_id *id)
555{ 555{
556 struct device_node *np = ofdev->node; 556 struct device_node *np = ofdev->dev.of_node;
557 struct device *dev = &ofdev->dev; 557 struct device *dev = &ofdev->dev;
558 struct mb862xxfb_par *par; 558 struct mb862xxfb_par *par;
559 struct fb_info *info; 559 struct fb_info *info;
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index c85dd408a9b8..6552751e81aa 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -251,7 +251,7 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no
251 251
252static int __devinit p9100_probe(struct of_device *op, const struct of_device_id *match) 252static int __devinit p9100_probe(struct of_device *op, const struct of_device_id *match)
253{ 253{
254 struct device_node *dp = op->node; 254 struct device_node *dp = op->dev.of_node;
255 struct fb_info *info; 255 struct fb_info *info;
256 struct p9100_par *par; 256 struct p9100_par *par;
257 int linebytes, err; 257 int linebytes, err;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index e8c769944812..12c451a711e9 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -991,13 +991,13 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
991 priv->ch[j].lcdc = priv; 991 priv->ch[j].lcdc = priv;
992 memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i])); 992 memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
993 993
994 error = sh_mobile_lcdc_check_interface(&priv->ch[i]); 994 error = sh_mobile_lcdc_check_interface(&priv->ch[j]);
995 if (error) { 995 if (error) {
996 dev_err(&pdev->dev, "unsupported interface type\n"); 996 dev_err(&pdev->dev, "unsupported interface type\n");
997 goto err1; 997 goto err1;
998 } 998 }
999 init_waitqueue_head(&priv->ch[i].frame_end_wait); 999 init_waitqueue_head(&priv->ch[j].frame_end_wait);
1000 init_completion(&priv->ch[i].vsync_completion); 1000 init_completion(&priv->ch[j].vsync_completion);
1001 priv->ch[j].pan_offset = 0; 1001 priv->ch[j].pan_offset = 0;
1002 1002
1003 switch (pdata->ch[i].chan) { 1003 switch (pdata->ch[i].chan) {
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index ef7a7bd8b503..cc039b33d2d8 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -365,7 +365,7 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info,
365static int __devinit tcx_probe(struct of_device *op, 365static int __devinit tcx_probe(struct of_device *op,
366 const struct of_device_id *match) 366 const struct of_device_id *match)
367{ 367{
368 struct device_node *dp = op->node; 368 struct device_node *dp = op->dev.of_node;
369 struct fb_info *info; 369 struct fb_info *info;
370 struct tcx_par *par; 370 struct tcx_par *par;
371 int linebytes, i, err; 371 int linebytes, i, err;
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index ca0f4c6cf5ab..1df284f9c2a1 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -273,7 +273,7 @@ static int __devinit gef_wdt_probe(struct of_device *dev,
273 bus_clk = freq; 273 bus_clk = freq;
274 274
275 /* Map devices registers into memory */ 275 /* Map devices registers into memory */
276 gef_wdt_regs = of_iomap(dev->node, 0); 276 gef_wdt_regs = of_iomap(dev->dev.of_node, 0);
277 if (gef_wdt_regs == NULL) 277 if (gef_wdt_regs == NULL)
278 return -ENOMEM; 278 return -ENOMEM;
279 279
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 6622335773bb..4cda64dd309c 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -189,7 +189,7 @@ static int __devinit mpc8xxx_wdt_probe(struct of_device *ofdev,
189 const struct of_device_id *match) 189 const struct of_device_id *match)
190{ 190{
191 int ret; 191 int ret;
192 struct device_node *np = ofdev->node; 192 struct device_node *np = ofdev->dev.of_node;
193 struct mpc8xxx_wdt_type *wdt_type = match->data; 193 struct mpc8xxx_wdt_type *wdt_type = match->data;
194 u32 freq = fsl_get_sys_freq(); 194 u32 freq = fsl_get_sys_freq();
195 bool enabled; 195 bool enabled;
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index eab33f1dbdf7..7b547f53f65e 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -499,7 +499,7 @@ int xenbus_printf(struct xenbus_transaction t,
499#define PRINTF_BUFFER_SIZE 4096 499#define PRINTF_BUFFER_SIZE 4096
500 char *printf_buffer; 500 char *printf_buffer;
501 501
502 printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL); 502 printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_NOIO | __GFP_HIGH);
503 if (printf_buffer == NULL) 503 if (printf_buffer == NULL)
504 return -ENOMEM; 504 return -ENOMEM;
505 505
diff --git a/fs/afs/server.c b/fs/afs/server.c
index f49099516675..9fdc7fe3a7bc 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -91,9 +91,10 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell,
91 91
92 memcpy(&server->addr, addr, sizeof(struct in_addr)); 92 memcpy(&server->addr, addr, sizeof(struct in_addr));
93 server->addr.s_addr = addr->s_addr; 93 server->addr.s_addr = addr->s_addr;
94 _leave(" = %p{%d}", server, atomic_read(&server->usage));
95 } else {
96 _leave(" = NULL [nomem]");
94 } 97 }
95
96 _leave(" = %p{%d}", server, atomic_read(&server->usage));
97 return server; 98 return server;
98} 99}
99 100
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 2c5f9a0e5d72..63039ed9576f 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -990,10 +990,9 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
990 990
991 /* clear any space allocated but not loaded */ 991 /* clear any space allocated but not loaded */
992 if (phdr->p_filesz < phdr->p_memsz) { 992 if (phdr->p_filesz < phdr->p_memsz) {
993 ret = clear_user((void *) (seg->addr + phdr->p_filesz), 993 if (clear_user((void *) (seg->addr + phdr->p_filesz),
994 phdr->p_memsz - phdr->p_filesz); 994 phdr->p_memsz - phdr->p_filesz))
995 if (ret) 995 return -EFAULT;
996 return ret;
997 } 996 }
998 997
999 if (mm) { 998 if (mm) {
@@ -1027,7 +1026,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1027 struct elf32_fdpic_loadseg *seg; 1026 struct elf32_fdpic_loadseg *seg;
1028 struct elf32_phdr *phdr; 1027 struct elf32_phdr *phdr;
1029 unsigned long load_addr, delta_vaddr; 1028 unsigned long load_addr, delta_vaddr;
1030 int loop, dvset, ret; 1029 int loop, dvset;
1031 1030
1032 load_addr = params->load_addr; 1031 load_addr = params->load_addr;
1033 delta_vaddr = 0; 1032 delta_vaddr = 0;
@@ -1127,9 +1126,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1127 * PT_LOAD */ 1126 * PT_LOAD */
1128 if (prot & PROT_WRITE && disp > 0) { 1127 if (prot & PROT_WRITE && disp > 0) {
1129 kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp); 1128 kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
1130 ret = clear_user((void __user *) maddr, disp); 1129 if (clear_user((void __user *) maddr, disp))
1131 if (ret) 1130 return -EFAULT;
1132 return ret;
1133 maddr += disp; 1131 maddr += disp;
1134 } 1132 }
1135 1133
@@ -1164,19 +1162,17 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1164 if (prot & PROT_WRITE && excess1 > 0) { 1162 if (prot & PROT_WRITE && excess1 > 0) {
1165 kdebug("clear[%d] ad=%lx sz=%lx", 1163 kdebug("clear[%d] ad=%lx sz=%lx",
1166 loop, maddr + phdr->p_filesz, excess1); 1164 loop, maddr + phdr->p_filesz, excess1);
1167 ret = clear_user((void __user *) maddr + phdr->p_filesz, 1165 if (clear_user((void __user *) maddr + phdr->p_filesz,
1168 excess1); 1166 excess1))
1169 if (ret) 1167 return -EFAULT;
1170 return ret;
1171 } 1168 }
1172 1169
1173#else 1170#else
1174 if (excess > 0) { 1171 if (excess > 0) {
1175 kdebug("clear[%d] ad=%lx sz=%lx", 1172 kdebug("clear[%d] ad=%lx sz=%lx",
1176 loop, maddr + phdr->p_filesz, excess); 1173 loop, maddr + phdr->p_filesz, excess);
1177 ret = clear_user((void *) maddr + phdr->p_filesz, excess); 1174 if (clear_user((void *) maddr + phdr->p_filesz, excess))
1178 if (ret) 1175 return -EFAULT;
1179 return ret;
1180 } 1176 }
1181#endif 1177#endif
1182 1178
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 49566c1687d8..b6ab27ccf214 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -56,15 +56,22 @@
56#endif 56#endif
57 57
58/* 58/*
59 * User data (stack, data section and bss) needs to be aligned 59 * User data (data section and bss) needs to be aligned.
60 * for the same reasons as SLAB memory is, and to the same amount. 60 * We pick 0x20 here because it is the max value elf2flt has always
61 * Avoid duplicating architecture specific code by using the same 61 * used in producing FLAT files, and because it seems to be large
62 * macro as with SLAB allocation: 62 * enough to make all the gcc alignment related tests happy.
63 */
64#define FLAT_DATA_ALIGN (0x20)
65
66/*
67 * User data (stack) also needs to be aligned.
68 * Here we can be a bit looser than the data sections since this
69 * needs to only meet arch ABI requirements.
63 */ 70 */
64#ifdef ARCH_SLAB_MINALIGN 71#ifdef ARCH_SLAB_MINALIGN
65#define FLAT_DATA_ALIGN (ARCH_SLAB_MINALIGN) 72#define FLAT_STACK_ALIGN (ARCH_SLAB_MINALIGN)
66#else 73#else
67#define FLAT_DATA_ALIGN (sizeof(void *)) 74#define FLAT_STACK_ALIGN (sizeof(void *))
68#endif 75#endif
69 76
70#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ 77#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
@@ -129,7 +136,7 @@ static unsigned long create_flat_tables(
129 136
130 sp = (unsigned long *)p; 137 sp = (unsigned long *)p;
131 sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); 138 sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
132 sp = (unsigned long *) ((unsigned long)sp & -FLAT_DATA_ALIGN); 139 sp = (unsigned long *) ((unsigned long)sp & -FLAT_STACK_ALIGN);
133 argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); 140 argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
134 envp = argv + (argc + 1); 141 envp = argv + (argc + 1);
135 142
@@ -589,7 +596,7 @@ static int load_flat_file(struct linux_binprm * bprm,
589 if (IS_ERR_VALUE(result)) { 596 if (IS_ERR_VALUE(result)) {
590 printk("Unable to read data+bss, errno %d\n", (int)-result); 597 printk("Unable to read data+bss, errno %d\n", (int)-result);
591 do_munmap(current->mm, textpos, text_len); 598 do_munmap(current->mm, textpos, text_len);
592 do_munmap(current->mm, realdatastart, data_len + extra); 599 do_munmap(current->mm, realdatastart, len);
593 ret = result; 600 ret = result;
594 goto err; 601 goto err;
595 } 602 }
@@ -876,7 +883,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
876 stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ 883 stack_len = TOP_OF_ARGS - bprm->p; /* the strings */
877 stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ 884 stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
878 stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ 885 stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */
879 stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */ 886 stack_len += FLAT_STACK_ALIGN - 1; /* reserve for upcoming alignment */
880 887
881 res = load_flat_file(bprm, &libinfo, 0, &stack_len); 888 res = load_flat_file(bprm, &libinfo, 0, &stack_len);
882 if (IS_ERR_VALUE(res)) 889 if (IS_ERR_VALUE(res))
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index f1ff785b2292..75541af4b3db 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1952,6 +1952,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
1952 bytes_read -= PAGE_CACHE_SIZE; 1952 bytes_read -= PAGE_CACHE_SIZE;
1953 continue; 1953 continue;
1954 } 1954 }
1955 page_cache_release(page);
1955 1956
1956 target = kmap_atomic(page, KM_USER0); 1957 target = kmap_atomic(page, KM_USER0);
1957 1958
diff --git a/fs/compat.c b/fs/compat.c
index f0b391c50552..6490d2134ff3 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -626,7 +626,7 @@ ssize_t compat_rw_copy_check_uvector(int type,
626 tot_len += len; 626 tot_len += len;
627 if (tot_len < tmp) /* maths overflow on the compat_ssize_t */ 627 if (tot_len < tmp) /* maths overflow on the compat_ssize_t */
628 goto out; 628 goto out;
629 if (!access_ok(vrfy_dir(type), buf, len)) { 629 if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) {
630 ret = -EFAULT; 630 ret = -EFAULT;
631 goto out; 631 goto out;
632 } 632 }
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index 41645142b88b..cf78d44a8d6a 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -72,10 +72,6 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
72 if (!sd) 72 if (!sd)
73 return -EINVAL; 73 return -EINVAL;
74 74
75 error = simple_setattr(dentry, iattr);
76 if (error)
77 return error;
78
79 sd_iattr = sd->s_iattr; 75 sd_iattr = sd->s_iattr;
80 if (!sd_iattr) { 76 if (!sd_iattr) {
81 /* setting attributes for the first time, allocate now */ 77 /* setting attributes for the first time, allocate now */
@@ -89,9 +85,12 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
89 sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; 85 sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
90 sd->s_iattr = sd_iattr; 86 sd->s_iattr = sd_iattr;
91 } 87 }
92
93 /* attributes were changed atleast once in past */ 88 /* attributes were changed atleast once in past */
94 89
90 error = simple_setattr(dentry, iattr);
91 if (error)
92 return error;
93
95 if (ia_valid & ATTR_UID) 94 if (ia_valid & ATTR_UID)
96 sd_iattr->ia_uid = iattr->ia_uid; 95 sd_iattr->ia_uid = iattr->ia_uid;
97 if (ia_valid & ATTR_GID) 96 if (ia_valid & ATTR_GID)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 19214435b752..3675088cb88c 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1552,7 +1552,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
1552 if (error) 1552 if (error)
1553 return error; 1553 return error;
1554 } 1554 }
1555 if (iattr->ia_valid & ATTR_SIZE) { 1555 if (iattr->ia_valid & ATTR_SIZE && iattr->ia_size != inode->i_size) {
1556 error = ext2_setsize(inode, iattr->ia_size); 1556 error = ext2_setsize(inode, iattr->ia_size);
1557 if (error) 1557 if (error)
1558 return error; 1558 return error;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 19df61c321fd..42272d67955a 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4942,20 +4942,26 @@ void ext4_set_inode_flags(struct inode *inode)
4942/* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ 4942/* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
4943void ext4_get_inode_flags(struct ext4_inode_info *ei) 4943void ext4_get_inode_flags(struct ext4_inode_info *ei)
4944{ 4944{
4945 unsigned int flags = ei->vfs_inode.i_flags; 4945 unsigned int vfs_fl;
4946 4946 unsigned long old_fl, new_fl;
4947 ei->i_flags &= ~(EXT4_SYNC_FL|EXT4_APPEND_FL| 4947
4948 EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|EXT4_DIRSYNC_FL); 4948 do {
4949 if (flags & S_SYNC) 4949 vfs_fl = ei->vfs_inode.i_flags;
4950 ei->i_flags |= EXT4_SYNC_FL; 4950 old_fl = ei->i_flags;
4951 if (flags & S_APPEND) 4951 new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL|
4952 ei->i_flags |= EXT4_APPEND_FL; 4952 EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|
4953 if (flags & S_IMMUTABLE) 4953 EXT4_DIRSYNC_FL);
4954 ei->i_flags |= EXT4_IMMUTABLE_FL; 4954 if (vfs_fl & S_SYNC)
4955 if (flags & S_NOATIME) 4955 new_fl |= EXT4_SYNC_FL;
4956 ei->i_flags |= EXT4_NOATIME_FL; 4956 if (vfs_fl & S_APPEND)
4957 if (flags & S_DIRSYNC) 4957 new_fl |= EXT4_APPEND_FL;
4958 ei->i_flags |= EXT4_DIRSYNC_FL; 4958 if (vfs_fl & S_IMMUTABLE)
4959 new_fl |= EXT4_IMMUTABLE_FL;
4960 if (vfs_fl & S_NOATIME)
4961 new_fl |= EXT4_NOATIME_FL;
4962 if (vfs_fl & S_DIRSYNC)
4963 new_fl |= EXT4_DIRSYNC_FL;
4964 } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl);
4959} 4965}
4960 4966
4961static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode, 4967static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
@@ -5191,7 +5197,7 @@ static int ext4_inode_blocks_set(handle_t *handle,
5191 */ 5197 */
5192 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); 5198 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
5193 raw_inode->i_blocks_high = 0; 5199 raw_inode->i_blocks_high = 0;
5194 ei->i_flags &= ~EXT4_HUGE_FILE_FL; 5200 ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE);
5195 return 0; 5201 return 0;
5196 } 5202 }
5197 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) 5203 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
@@ -5204,9 +5210,9 @@ static int ext4_inode_blocks_set(handle_t *handle,
5204 */ 5210 */
5205 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); 5211 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
5206 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); 5212 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
5207 ei->i_flags &= ~EXT4_HUGE_FILE_FL; 5213 ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE);
5208 } else { 5214 } else {
5209 ei->i_flags |= EXT4_HUGE_FILE_FL; 5215 ext4_set_inode_flag(inode, EXT4_INODE_HUGE_FILE);
5210 /* i_block is stored in file system block size */ 5216 /* i_block is stored in file system block size */
5211 i_blocks = i_blocks >> (inode->i_blkbits - 9); 5217 i_blocks = i_blocks >> (inode->i_blkbits - 9);
5212 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); 5218 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 3a6c92ac131c..52abfa12762a 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -960,6 +960,9 @@ mext_check_arguments(struct inode *orig_inode,
960 return -EINVAL; 960 return -EINVAL;
961 } 961 }
962 962
963 if (IS_IMMUTABLE(donor_inode) || IS_APPEND(donor_inode))
964 return -EPERM;
965
963 /* Ext4 move extent does not support swapfile */ 966 /* Ext4 move extent does not support swapfile */
964 if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) { 967 if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) {
965 ext4_debug("ext4 move extent: The argument files should " 968 ext4_debug("ext4 move extent: The argument files should "
diff --git a/fs/fcntl.c b/fs/fcntl.c
index f74d270ba155..51e11bf5708f 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -274,7 +274,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
274 274
275 ret = copy_from_user(&owner, owner_p, sizeof(owner)); 275 ret = copy_from_user(&owner, owner_p, sizeof(owner));
276 if (ret) 276 if (ret)
277 return ret; 277 return -EFAULT;
278 278
279 switch (owner.type) { 279 switch (owner.type) {
280 case F_OWNER_TID: 280 case F_OWNER_TID:
@@ -332,8 +332,11 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
332 } 332 }
333 read_unlock(&filp->f_owner.lock); 333 read_unlock(&filp->f_owner.lock);
334 334
335 if (!ret) 335 if (!ret) {
336 ret = copy_to_user(owner_p, &owner, sizeof(owner)); 336 ret = copy_to_user(owner_p, &owner, sizeof(owner));
337 if (ret)
338 ret = -EFAULT;
339 }
337 return ret; 340 return ret;
338} 341}
339 342
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index ea8592b90696..1d1088f48bc2 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -45,7 +45,6 @@ struct wb_writeback_args {
45 unsigned int for_kupdate:1; 45 unsigned int for_kupdate:1;
46 unsigned int range_cyclic:1; 46 unsigned int range_cyclic:1;
47 unsigned int for_background:1; 47 unsigned int for_background:1;
48 unsigned int sb_pinned:1;
49}; 48};
50 49
51/* 50/*
@@ -193,8 +192,7 @@ static void bdi_wait_on_work_clear(struct bdi_work *work)
193} 192}
194 193
195static void bdi_alloc_queue_work(struct backing_dev_info *bdi, 194static void bdi_alloc_queue_work(struct backing_dev_info *bdi,
196 struct wb_writeback_args *args, 195 struct wb_writeback_args *args)
197 int wait)
198{ 196{
199 struct bdi_work *work; 197 struct bdi_work *work;
200 198
@@ -206,8 +204,6 @@ static void bdi_alloc_queue_work(struct backing_dev_info *bdi,
206 if (work) { 204 if (work) {
207 bdi_work_init(work, args); 205 bdi_work_init(work, args);
208 bdi_queue_work(bdi, work); 206 bdi_queue_work(bdi, work);
209 if (wait)
210 bdi_wait_on_work_clear(work);
211 } else { 207 } else {
212 struct bdi_writeback *wb = &bdi->wb; 208 struct bdi_writeback *wb = &bdi->wb;
213 209
@@ -234,11 +230,6 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi,
234 .sync_mode = WB_SYNC_ALL, 230 .sync_mode = WB_SYNC_ALL,
235 .nr_pages = LONG_MAX, 231 .nr_pages = LONG_MAX,
236 .range_cyclic = 0, 232 .range_cyclic = 0,
237 /*
238 * Setting sb_pinned is not necessary for WB_SYNC_ALL, but
239 * lets make it explicitly clear.
240 */
241 .sb_pinned = 1,
242 }; 233 };
243 struct bdi_work work; 234 struct bdi_work work;
244 235
@@ -254,23 +245,21 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi,
254 * @bdi: the backing device to write from 245 * @bdi: the backing device to write from
255 * @sb: write inodes from this super_block 246 * @sb: write inodes from this super_block
256 * @nr_pages: the number of pages to write 247 * @nr_pages: the number of pages to write
257 * @sb_locked: caller already holds sb umount sem.
258 * 248 *
259 * Description: 249 * Description:
260 * This does WB_SYNC_NONE opportunistic writeback. The IO is only 250 * This does WB_SYNC_NONE opportunistic writeback. The IO is only
261 * started when this function returns, we make no guarentees on 251 * started when this function returns, we make no guarentees on
262 * completion. Caller specifies whether sb umount sem is held already or not. 252 * completion. Caller need not hold sb s_umount semaphore.
263 * 253 *
264 */ 254 */
265void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, 255void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
266 long nr_pages, int sb_locked) 256 long nr_pages)
267{ 257{
268 struct wb_writeback_args args = { 258 struct wb_writeback_args args = {
269 .sb = sb, 259 .sb = sb,
270 .sync_mode = WB_SYNC_NONE, 260 .sync_mode = WB_SYNC_NONE,
271 .nr_pages = nr_pages, 261 .nr_pages = nr_pages,
272 .range_cyclic = 1, 262 .range_cyclic = 1,
273 .sb_pinned = sb_locked,
274 }; 263 };
275 264
276 /* 265 /*
@@ -282,7 +271,7 @@ void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
282 args.for_background = 1; 271 args.for_background = 1;
283 } 272 }
284 273
285 bdi_alloc_queue_work(bdi, &args, sb_locked); 274 bdi_alloc_queue_work(bdi, &args);
286} 275}
287 276
288/* 277/*
@@ -595,7 +584,7 @@ static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc,
595 /* 584 /*
596 * Caller must already hold the ref for this 585 * Caller must already hold the ref for this
597 */ 586 */
598 if (wbc->sync_mode == WB_SYNC_ALL || wbc->sb_pinned) { 587 if (wbc->sync_mode == WB_SYNC_ALL) {
599 WARN_ON(!rwsem_is_locked(&sb->s_umount)); 588 WARN_ON(!rwsem_is_locked(&sb->s_umount));
600 return SB_NOT_PINNED; 589 return SB_NOT_PINNED;
601 } 590 }
@@ -769,7 +758,6 @@ static long wb_writeback(struct bdi_writeback *wb,
769 .for_kupdate = args->for_kupdate, 758 .for_kupdate = args->for_kupdate,
770 .for_background = args->for_background, 759 .for_background = args->for_background,
771 .range_cyclic = args->range_cyclic, 760 .range_cyclic = args->range_cyclic,
772 .sb_pinned = args->sb_pinned,
773 }; 761 };
774 unsigned long oldest_jif; 762 unsigned long oldest_jif;
775 long wrote = 0; 763 long wrote = 0;
@@ -912,7 +900,6 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait)
912 900
913 while ((work = get_next_work_item(bdi, wb)) != NULL) { 901 while ((work = get_next_work_item(bdi, wb)) != NULL) {
914 struct wb_writeback_args args = work->args; 902 struct wb_writeback_args args = work->args;
915 int post_clear;
916 903
917 /* 904 /*
918 * Override sync mode, in case we must wait for completion 905 * Override sync mode, in case we must wait for completion
@@ -920,13 +907,11 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait)
920 if (force_wait) 907 if (force_wait)
921 work->args.sync_mode = args.sync_mode = WB_SYNC_ALL; 908 work->args.sync_mode = args.sync_mode = WB_SYNC_ALL;
922 909
923 post_clear = WB_SYNC_ALL || args.sb_pinned;
924
925 /* 910 /*
926 * If this isn't a data integrity operation, just notify 911 * If this isn't a data integrity operation, just notify
927 * that we have seen this work and we are now starting it. 912 * that we have seen this work and we are now starting it.
928 */ 913 */
929 if (!post_clear) 914 if (args.sync_mode == WB_SYNC_NONE)
930 wb_clear_pending(wb, work); 915 wb_clear_pending(wb, work);
931 916
932 wrote += wb_writeback(wb, &args); 917 wrote += wb_writeback(wb, &args);
@@ -935,7 +920,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait)
935 * This is a data integrity writeback, so only do the 920 * This is a data integrity writeback, so only do the
936 * notification when we have completed the work. 921 * notification when we have completed the work.
937 */ 922 */
938 if (post_clear) 923 if (args.sync_mode == WB_SYNC_ALL)
939 wb_clear_pending(wb, work); 924 wb_clear_pending(wb, work);
940 } 925 }
941 926
@@ -1011,7 +996,7 @@ static void bdi_writeback_all(struct super_block *sb, long nr_pages)
1011 if (!bdi_has_dirty_io(bdi)) 996 if (!bdi_has_dirty_io(bdi))
1012 continue; 997 continue;
1013 998
1014 bdi_alloc_queue_work(bdi, &args, 0); 999 bdi_alloc_queue_work(bdi, &args);
1015 } 1000 }
1016 1001
1017 rcu_read_unlock(); 1002 rcu_read_unlock();
@@ -1220,18 +1205,6 @@ static void wait_sb_inodes(struct super_block *sb)
1220 iput(old_inode); 1205 iput(old_inode);
1221} 1206}
1222 1207
1223static void __writeback_inodes_sb(struct super_block *sb, int sb_locked)
1224{
1225 unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
1226 unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
1227 long nr_to_write;
1228
1229 nr_to_write = nr_dirty + nr_unstable +
1230 (inodes_stat.nr_inodes - inodes_stat.nr_unused);
1231
1232 bdi_start_writeback(sb->s_bdi, sb, nr_to_write, sb_locked);
1233}
1234
1235/** 1208/**
1236 * writeback_inodes_sb - writeback dirty inodes from given super_block 1209 * writeback_inodes_sb - writeback dirty inodes from given super_block
1237 * @sb: the superblock 1210 * @sb: the superblock
@@ -1243,21 +1216,16 @@ static void __writeback_inodes_sb(struct super_block *sb, int sb_locked)
1243 */ 1216 */
1244void writeback_inodes_sb(struct super_block *sb) 1217void writeback_inodes_sb(struct super_block *sb)
1245{ 1218{
1246 __writeback_inodes_sb(sb, 0); 1219 unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
1247} 1220 unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
1248EXPORT_SYMBOL(writeback_inodes_sb); 1221 long nr_to_write;
1249 1222
1250/** 1223 nr_to_write = nr_dirty + nr_unstable +
1251 * writeback_inodes_sb_locked - writeback dirty inodes from given super_block 1224 (inodes_stat.nr_inodes - inodes_stat.nr_unused);
1252 * @sb: the superblock 1225
1253 * 1226 bdi_start_writeback(sb->s_bdi, sb, nr_to_write);
1254 * Like writeback_inodes_sb(), except the caller already holds the
1255 * sb umount sem.
1256 */
1257void writeback_inodes_sb_locked(struct super_block *sb)
1258{
1259 __writeback_inodes_sb(sb, 1);
1260} 1227}
1228EXPORT_SYMBOL(writeback_inodes_sb);
1261 1229
1262/** 1230/**
1263 * writeback_inodes_sb_if_idle - start writeback if none underway 1231 * writeback_inodes_sb_if_idle - start writeback if none underway
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 47aefd376e54..723b889fd219 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -710,30 +710,26 @@ static void fscache_write_op(struct fscache_operation *_op)
710 goto superseded; 710 goto superseded;
711 } 711 }
712 712
713 if (page) { 713 radix_tree_tag_set(&cookie->stores, page->index,
714 radix_tree_tag_set(&cookie->stores, page->index, 714 FSCACHE_COOKIE_STORING_TAG);
715 FSCACHE_COOKIE_STORING_TAG); 715 radix_tree_tag_clear(&cookie->stores, page->index,
716 radix_tree_tag_clear(&cookie->stores, page->index, 716 FSCACHE_COOKIE_PENDING_TAG);
717 FSCACHE_COOKIE_PENDING_TAG);
718 }
719 717
720 spin_unlock(&cookie->stores_lock); 718 spin_unlock(&cookie->stores_lock);
721 spin_unlock(&object->lock); 719 spin_unlock(&object->lock);
722 720
723 if (page) { 721 fscache_set_op_state(&op->op, "Store");
724 fscache_set_op_state(&op->op, "Store"); 722 fscache_stat(&fscache_n_store_pages);
725 fscache_stat(&fscache_n_store_pages); 723 fscache_stat(&fscache_n_cop_write_page);
726 fscache_stat(&fscache_n_cop_write_page); 724 ret = object->cache->ops->write_page(op, page);
727 ret = object->cache->ops->write_page(op, page); 725 fscache_stat_d(&fscache_n_cop_write_page);
728 fscache_stat_d(&fscache_n_cop_write_page); 726 fscache_set_op_state(&op->op, "EndWrite");
729 fscache_set_op_state(&op->op, "EndWrite"); 727 fscache_end_page_write(object, page);
730 fscache_end_page_write(object, page); 728 if (ret < 0) {
731 if (ret < 0) { 729 fscache_set_op_state(&op->op, "Abort");
732 fscache_set_op_state(&op->op, "Abort"); 730 fscache_abort_object(object);
733 fscache_abort_object(object); 731 } else {
734 } else { 732 fscache_enqueue_operation(&op->op);
735 fscache_enqueue_operation(&op->op);
736 }
737 } 733 }
738 734
739 _leave(""); 735 _leave("");
diff --git a/fs/libfs.c b/fs/libfs.c
index 09e1016eb774..dcaf972cbf1b 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -489,7 +489,8 @@ int simple_write_end(struct file *file, struct address_space *mapping,
489 * unique inode values later for this filesystem, then you must take care 489 * unique inode values later for this filesystem, then you must take care
490 * to pass it an appropriate max_reserved value to avoid collisions. 490 * to pass it an appropriate max_reserved value to avoid collisions.
491 */ 491 */
492int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files) 492int simple_fill_super(struct super_block *s, unsigned long magic,
493 struct tree_descr *files)
493{ 494{
494 struct inode *inode; 495 struct inode *inode;
495 struct dentry *root; 496 struct dentry *root;
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 91969589131c..1dbf921ca44b 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -75,10 +75,6 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n)
75 if (!IS_ERR(page)) 75 if (!IS_ERR(page))
76 kmap(page); 76 kmap(page);
77 return page; 77 return page;
78
79fail:
80 dir_put_page(page);
81 return ERR_PTR(-EIO);
82} 78}
83 79
84static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi) 80static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h
index af638d59e3bf..43c8c5b541fd 100644
--- a/fs/nilfs2/btree.h
+++ b/fs/nilfs2/btree.h
@@ -75,8 +75,6 @@ struct nilfs_btree_path {
75 75
76extern struct kmem_cache *nilfs_btree_path_cache; 76extern struct kmem_cache *nilfs_btree_path_cache;
77 77
78int nilfs_btree_path_cache_init(void);
79void nilfs_btree_path_cache_destroy(void);
80int nilfs_btree_init(struct nilfs_bmap *); 78int nilfs_btree_init(struct nilfs_bmap *);
81int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64, 79int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64,
82 const __u64 *, const __u64 *, int); 80 const __u64 *, const __u64 *, int);
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index fdf1c3b6d673..85fbb66455e2 100644
--- a/fs/nilfs2/segbuf.h
+++ b/fs/nilfs2/segbuf.h
@@ -127,8 +127,6 @@ struct nilfs_segment_buffer {
127 127
128extern struct kmem_cache *nilfs_segbuf_cachep; 128extern struct kmem_cache *nilfs_segbuf_cachep;
129 129
130int __init nilfs_init_segbuf_cache(void);
131void nilfs_destroy_segbuf_cache(void);
132struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *); 130struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *);
133void nilfs_segbuf_free(struct nilfs_segment_buffer *); 131void nilfs_segbuf_free(struct nilfs_segment_buffer *);
134void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long, 132void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long,
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index dca142361ccf..01e20dbb217d 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -221,8 +221,6 @@ enum {
221extern struct kmem_cache *nilfs_transaction_cachep; 221extern struct kmem_cache *nilfs_transaction_cachep;
222 222
223/* segment.c */ 223/* segment.c */
224extern int nilfs_init_transaction_cache(void);
225extern void nilfs_destroy_transaction_cache(void);
226extern void nilfs_relax_pressure_in_lock(struct super_block *); 224extern void nilfs_relax_pressure_in_lock(struct super_block *);
227 225
228extern int nilfs_construct_segment(struct super_block *); 226extern int nilfs_construct_segment(struct super_block *);
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 03b34b738993..414ef68931cf 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -1130,13 +1130,13 @@ static void nilfs_segbuf_init_once(void *obj)
1130 1130
1131static void nilfs_destroy_cachep(void) 1131static void nilfs_destroy_cachep(void)
1132{ 1132{
1133 if (nilfs_inode_cachep) 1133 if (nilfs_inode_cachep)
1134 kmem_cache_destroy(nilfs_inode_cachep); 1134 kmem_cache_destroy(nilfs_inode_cachep);
1135 if (nilfs_transaction_cachep) 1135 if (nilfs_transaction_cachep)
1136 kmem_cache_destroy(nilfs_transaction_cachep); 1136 kmem_cache_destroy(nilfs_transaction_cachep);
1137 if (nilfs_segbuf_cachep) 1137 if (nilfs_segbuf_cachep)
1138 kmem_cache_destroy(nilfs_segbuf_cachep); 1138 kmem_cache_destroy(nilfs_segbuf_cachep);
1139 if (nilfs_btree_path_cache) 1139 if (nilfs_btree_path_cache)
1140 kmem_cache_destroy(nilfs_btree_path_cache); 1140 kmem_cache_destroy(nilfs_btree_path_cache);
1141} 1141}
1142 1142
diff --git a/fs/pipe.c b/fs/pipe.c
index db6eaaba0dd8..69c4c7c13ea9 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -26,9 +26,14 @@
26 26
27/* 27/*
28 * The max size that a non-root user is allowed to grow the pipe. Can 28 * The max size that a non-root user is allowed to grow the pipe. Can
29 * be set by root in /proc/sys/fs/pipe-max-pages 29 * be set by root in /proc/sys/fs/pipe-max-size
30 */ 30 */
31unsigned int pipe_max_pages = PIPE_DEF_BUFFERS * 16; 31unsigned int pipe_max_size = 1048576;
32
33/*
34 * Minimum pipe size, as required by POSIX
35 */
36unsigned int pipe_min_size = PAGE_SIZE;
32 37
33/* 38/*
34 * We use a start+len construction, which provides full use of the 39 * We use a start+len construction, which provides full use of the
@@ -1118,26 +1123,20 @@ SYSCALL_DEFINE1(pipe, int __user *, fildes)
1118 * Allocate a new array of pipe buffers and copy the info over. Returns the 1123 * Allocate a new array of pipe buffers and copy the info over. Returns the
1119 * pipe size if successful, or return -ERROR on error. 1124 * pipe size if successful, or return -ERROR on error.
1120 */ 1125 */
1121static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg) 1126static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
1122{ 1127{
1123 struct pipe_buffer *bufs; 1128 struct pipe_buffer *bufs;
1124 1129
1125 /* 1130 /*
1126 * Must be a power-of-2 currently
1127 */
1128 if (!is_power_of_2(arg))
1129 return -EINVAL;
1130
1131 /*
1132 * We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't 1131 * We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't
1133 * expect a lot of shrink+grow operations, just free and allocate 1132 * expect a lot of shrink+grow operations, just free and allocate
1134 * again like we would do for growing. If the pipe currently 1133 * again like we would do for growing. If the pipe currently
1135 * contains more buffers than arg, then return busy. 1134 * contains more buffers than arg, then return busy.
1136 */ 1135 */
1137 if (arg < pipe->nrbufs) 1136 if (nr_pages < pipe->nrbufs)
1138 return -EBUSY; 1137 return -EBUSY;
1139 1138
1140 bufs = kcalloc(arg, sizeof(struct pipe_buffer), GFP_KERNEL); 1139 bufs = kcalloc(nr_pages, sizeof(struct pipe_buffer), GFP_KERNEL);
1141 if (unlikely(!bufs)) 1140 if (unlikely(!bufs))
1142 return -ENOMEM; 1141 return -ENOMEM;
1143 1142
@@ -1158,8 +1157,37 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
1158 pipe->curbuf = 0; 1157 pipe->curbuf = 0;
1159 kfree(pipe->bufs); 1158 kfree(pipe->bufs);
1160 pipe->bufs = bufs; 1159 pipe->bufs = bufs;
1161 pipe->buffers = arg; 1160 pipe->buffers = nr_pages;
1162 return arg; 1161 return nr_pages * PAGE_SIZE;
1162}
1163
1164/*
1165 * Currently we rely on the pipe array holding a power-of-2 number
1166 * of pages.
1167 */
1168static inline unsigned int round_pipe_size(unsigned int size)
1169{
1170 unsigned long nr_pages;
1171
1172 nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
1173 return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
1174}
1175
1176/*
1177 * This should work even if CONFIG_PROC_FS isn't set, as proc_dointvec_minmax
1178 * will return an error.
1179 */
1180int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
1181 size_t *lenp, loff_t *ppos)
1182{
1183 int ret;
1184
1185 ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
1186 if (ret < 0 || !write)
1187 return ret;
1188
1189 pipe_max_size = round_pipe_size(pipe_max_size);
1190 return ret;
1163} 1191}
1164 1192
1165long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) 1193long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -1174,23 +1202,24 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
1174 mutex_lock(&pipe->inode->i_mutex); 1202 mutex_lock(&pipe->inode->i_mutex);
1175 1203
1176 switch (cmd) { 1204 switch (cmd) {
1177 case F_SETPIPE_SZ: 1205 case F_SETPIPE_SZ: {
1178 if (!capable(CAP_SYS_ADMIN) && arg > pipe_max_pages) { 1206 unsigned int size, nr_pages;
1179 ret = -EINVAL; 1207
1208 size = round_pipe_size(arg);
1209 nr_pages = size >> PAGE_SHIFT;
1210
1211 if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) {
1212 ret = -EPERM;
1180 goto out; 1213 goto out;
1181 } 1214 } else if (nr_pages < PAGE_SIZE) {
1182 /*
1183 * The pipe needs to be at least 2 pages large to
1184 * guarantee POSIX behaviour.
1185 */
1186 if (arg < 2) {
1187 ret = -EINVAL; 1215 ret = -EINVAL;
1188 goto out; 1216 goto out;
1189 } 1217 }
1190 ret = pipe_set_size(pipe, arg); 1218 ret = pipe_set_size(pipe, nr_pages);
1191 break; 1219 break;
1220 }
1192 case F_GETPIPE_SZ: 1221 case F_GETPIPE_SZ:
1193 ret = pipe->buffers; 1222 ret = pipe->buffers * PAGE_SIZE;
1194 break; 1223 break;
1195 default: 1224 default:
1196 ret = -EINVAL; 1225 ret = -EINVAL;
diff --git a/fs/splice.c b/fs/splice.c
index ac22b00d86c3..740e6b9faf7a 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -354,7 +354,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
354 break; 354 break;
355 355
356 error = add_to_page_cache_lru(page, mapping, index, 356 error = add_to_page_cache_lru(page, mapping, index,
357 mapping_gfp_mask(mapping)); 357 GFP_KERNEL);
358 if (unlikely(error)) { 358 if (unlikely(error)) {
359 page_cache_release(page); 359 page_cache_release(page);
360 if (error == -EEXIST) 360 if (error == -EEXIST)
diff --git a/fs/sync.c b/fs/sync.c
index c9f83f480ec5..15aa6f03b2da 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -42,7 +42,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
42 if (wait) 42 if (wait)
43 sync_inodes_sb(sb); 43 sync_inodes_sb(sb);
44 else 44 else
45 writeback_inodes_sb_locked(sb); 45 writeback_inodes_sb(sb);
46 46
47 if (sb->s_op->sync_fs) 47 if (sb->s_op->sync_fs)
48 sb->s_op->sync_fs(sb, wait); 48 sb->s_op->sync_fs(sb, wait);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index bde1a4c3679a..0835a3b70e03 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -117,11 +117,13 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
117 if (error) 117 if (error)
118 goto out; 118 goto out;
119 119
120 error = sysfs_sd_setattr(sd, iattr);
121 if (error)
122 goto out;
123
120 /* this ignores size changes */ 124 /* this ignores size changes */
121 generic_setattr(inode, iattr); 125 generic_setattr(inode, iattr);
122 126
123 error = sysfs_sd_setattr(sd, iattr);
124
125out: 127out:
126 mutex_unlock(&sysfs_mutex); 128 mutex_unlock(&sysfs_mutex);
127 return error; 129 return error;
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 089eaca860b4..a0fa3bf0d1bb 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1333,6 +1333,21 @@ xfs_vm_writepage(
1333 trace_xfs_writepage(inode, page, 0); 1333 trace_xfs_writepage(inode, page, 0);
1334 1334
1335 /* 1335 /*
1336 * Refuse to write the page out if we are called from reclaim context.
1337 *
1338 * This is primarily to avoid stack overflows when called from deep
1339 * used stacks in random callers for direct reclaim, but disabling
1340 * reclaim for kswap is a nice side-effect as kswapd causes rather
1341 * suboptimal I/O patters, too.
1342 *
1343 * This should really be done by the core VM, but until that happens
1344 * filesystems like XFS, btrfs and ext4 have to take care of this
1345 * by themselves.
1346 */
1347 if (current->flags & PF_MEMALLOC)
1348 goto out_fail;
1349
1350 /*
1336 * We need a transaction if: 1351 * We need a transaction if:
1337 * 1. There are delalloc buffers on the page 1352 * 1. There are delalloc buffers on the page
1338 * 2. The page is uptodate and we have unmapped buffers 1353 * 2. The page is uptodate and we have unmapped buffers
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 9c8019c78c92..44f0b2de153e 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -585,11 +585,20 @@ xfs_vn_fallocate(
585 bf.l_len = len; 585 bf.l_len = len;
586 586
587 xfs_ilock(ip, XFS_IOLOCK_EXCL); 587 xfs_ilock(ip, XFS_IOLOCK_EXCL);
588
589 /* check the new inode size is valid before allocating */
590 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
591 offset + len > i_size_read(inode)) {
592 new_size = offset + len;
593 error = inode_newsize_ok(inode, new_size);
594 if (error)
595 goto out_unlock;
596 }
597
588 error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, 598 error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf,
589 0, XFS_ATTR_NOLOCK); 599 0, XFS_ATTR_NOLOCK);
590 if (!error && !(mode & FALLOC_FL_KEEP_SIZE) && 600 if (error)
591 offset + len > i_size_read(inode)) 601 goto out_unlock;
592 new_size = offset + len;
593 602
594 /* Change file size if needed */ 603 /* Change file size if needed */
595 if (new_size) { 604 if (new_size) {
@@ -600,6 +609,7 @@ xfs_vn_fallocate(
600 error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); 609 error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK);
601 } 610 }
602 611
612out_unlock:
603 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 613 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
604out_error: 614out_error:
605 return error; 615 return error;
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c
index 9ac8aea91529..067cafbfc635 100644
--- a/fs/xfs/linux-2.6/xfs_quotaops.c
+++ b/fs/xfs/linux-2.6/xfs_quotaops.c
@@ -23,7 +23,6 @@
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_mount.h" 24#include "xfs_mount.h"
25#include "xfs_quota.h" 25#include "xfs_quota.h"
26#include "xfs_log.h"
27#include "xfs_trans.h" 26#include "xfs_trans.h"
28#include "xfs_bmap_btree.h" 27#include "xfs_bmap_btree.h"
29#include "xfs_inode.h" 28#include "xfs_inode.h"
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 3884e20bc14e..ef7f0218bccb 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -164,10 +164,6 @@ xfs_inode_ag_iterator(
164 struct xfs_perag *pag; 164 struct xfs_perag *pag;
165 165
166 pag = xfs_perag_get(mp, ag); 166 pag = xfs_perag_get(mp, ag);
167 if (!pag->pag_ici_init) {
168 xfs_perag_put(pag);
169 continue;
170 }
171 error = xfs_inode_ag_walk(mp, pag, execute, flags, tag, 167 error = xfs_inode_ag_walk(mp, pag, execute, flags, tag,
172 exclusive, &nr); 168 exclusive, &nr);
173 xfs_perag_put(pag); 169 xfs_perag_put(pag);
@@ -867,12 +863,7 @@ xfs_reclaim_inode_shrink(
867 down_read(&xfs_mount_list_lock); 863 down_read(&xfs_mount_list_lock);
868 list_for_each_entry(mp, &xfs_mount_list, m_mplist) { 864 list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
869 for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { 865 for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
870
871 pag = xfs_perag_get(mp, ag); 866 pag = xfs_perag_get(mp, ag);
872 if (!pag->pag_ici_init) {
873 xfs_perag_put(pag);
874 continue;
875 }
876 reclaimable += pag->pag_ici_reclaimable; 867 reclaimable += pag->pag_ici_reclaimable;
877 xfs_perag_put(pag); 868 xfs_perag_put(pag);
878 } 869 }
diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/linux-2.6/xfs_trace.c
index 207fa77f63ae..d12be8470cba 100644
--- a/fs/xfs/linux-2.6/xfs_trace.c
+++ b/fs/xfs/linux-2.6/xfs_trace.c
@@ -50,7 +50,6 @@
50#include "quota/xfs_dquot_item.h" 50#include "quota/xfs_dquot_item.h"
51#include "quota/xfs_dquot.h" 51#include "quota/xfs_dquot.h"
52#include "xfs_log_recover.h" 52#include "xfs_log_recover.h"
53#include "xfs_buf_item.h"
54#include "xfs_inode_item.h" 53#include "xfs_inode_item.h"
55 54
56/* 55/*
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index ff6bc797baf2..73d5aa117384 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -82,33 +82,6 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
82 ) 82 )
83) 83)
84 84
85#define DEFINE_PERAG_REF_EVENT(name) \
86TRACE_EVENT(name, \
87 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \
88 unsigned long caller_ip), \
89 TP_ARGS(mp, agno, refcount, caller_ip), \
90 TP_STRUCT__entry( \
91 __field(dev_t, dev) \
92 __field(xfs_agnumber_t, agno) \
93 __field(int, refcount) \
94 __field(unsigned long, caller_ip) \
95 ), \
96 TP_fast_assign( \
97 __entry->dev = mp->m_super->s_dev; \
98 __entry->agno = agno; \
99 __entry->refcount = refcount; \
100 __entry->caller_ip = caller_ip; \
101 ), \
102 TP_printk("dev %d:%d agno %u refcount %d caller %pf", \
103 MAJOR(__entry->dev), MINOR(__entry->dev), \
104 __entry->agno, \
105 __entry->refcount, \
106 (char *)__entry->caller_ip) \
107);
108
109DEFINE_PERAG_REF_EVENT(xfs_perag_get)
110DEFINE_PERAG_REF_EVENT(xfs_perag_put)
111
112#define DEFINE_ATTR_LIST_EVENT(name) \ 85#define DEFINE_ATTR_LIST_EVENT(name) \
113DEFINE_EVENT(xfs_attr_list_class, name, \ 86DEFINE_EVENT(xfs_attr_list_class, name, \
114 TP_PROTO(struct xfs_attr_list_context *ctx), \ 87 TP_PROTO(struct xfs_attr_list_context *ctx), \
@@ -122,6 +95,37 @@ DEFINE_ATTR_LIST_EVENT(xfs_attr_list_add);
122DEFINE_ATTR_LIST_EVENT(xfs_attr_list_wrong_blk); 95DEFINE_ATTR_LIST_EVENT(xfs_attr_list_wrong_blk);
123DEFINE_ATTR_LIST_EVENT(xfs_attr_list_notfound); 96DEFINE_ATTR_LIST_EVENT(xfs_attr_list_notfound);
124 97
98DECLARE_EVENT_CLASS(xfs_perag_class,
99 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount,
100 unsigned long caller_ip),
101 TP_ARGS(mp, agno, refcount, caller_ip),
102 TP_STRUCT__entry(
103 __field(dev_t, dev)
104 __field(xfs_agnumber_t, agno)
105 __field(int, refcount)
106 __field(unsigned long, caller_ip)
107 ),
108 TP_fast_assign(
109 __entry->dev = mp->m_super->s_dev;
110 __entry->agno = agno;
111 __entry->refcount = refcount;
112 __entry->caller_ip = caller_ip;
113 ),
114 TP_printk("dev %d:%d agno %u refcount %d caller %pf",
115 MAJOR(__entry->dev), MINOR(__entry->dev),
116 __entry->agno,
117 __entry->refcount,
118 (char *)__entry->caller_ip)
119);
120
121#define DEFINE_PERAG_REF_EVENT(name) \
122DEFINE_EVENT(xfs_perag_class, name, \
123 TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \
124 unsigned long caller_ip), \
125 TP_ARGS(mp, agno, refcount, caller_ip))
126DEFINE_PERAG_REF_EVENT(xfs_perag_get);
127DEFINE_PERAG_REF_EVENT(xfs_perag_put);
128
125TRACE_EVENT(xfs_attr_list_node_descend, 129TRACE_EVENT(xfs_attr_list_node_descend,
126 TP_PROTO(struct xfs_attr_list_context *ctx, 130 TP_PROTO(struct xfs_attr_list_context *ctx,
127 struct xfs_da_node_entry *btree), 131 struct xfs_da_node_entry *btree),
@@ -775,165 +779,181 @@ DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_enter);
775DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_exit); 779DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_exit);
776DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_sub); 780DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_sub);
777 781
778#define DEFINE_RW_EVENT(name) \ 782DECLARE_EVENT_CLASS(xfs_file_class,
779TRACE_EVENT(name, \ 783 TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags),
780 TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), \ 784 TP_ARGS(ip, count, offset, flags),
781 TP_ARGS(ip, count, offset, flags), \ 785 TP_STRUCT__entry(
782 TP_STRUCT__entry( \ 786 __field(dev_t, dev)
783 __field(dev_t, dev) \ 787 __field(xfs_ino_t, ino)
784 __field(xfs_ino_t, ino) \ 788 __field(xfs_fsize_t, size)
785 __field(xfs_fsize_t, size) \ 789 __field(xfs_fsize_t, new_size)
786 __field(xfs_fsize_t, new_size) \ 790 __field(loff_t, offset)
787 __field(loff_t, offset) \ 791 __field(size_t, count)
788 __field(size_t, count) \ 792 __field(int, flags)
789 __field(int, flags) \ 793 ),
790 ), \ 794 TP_fast_assign(
791 TP_fast_assign( \ 795 __entry->dev = VFS_I(ip)->i_sb->s_dev;
792 __entry->dev = VFS_I(ip)->i_sb->s_dev; \ 796 __entry->ino = ip->i_ino;
793 __entry->ino = ip->i_ino; \ 797 __entry->size = ip->i_d.di_size;
794 __entry->size = ip->i_d.di_size; \ 798 __entry->new_size = ip->i_new_size;
795 __entry->new_size = ip->i_new_size; \ 799 __entry->offset = offset;
796 __entry->offset = offset; \ 800 __entry->count = count;
797 __entry->count = count; \ 801 __entry->flags = flags;
798 __entry->flags = flags; \ 802 ),
799 ), \ 803 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx "
800 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ 804 "offset 0x%llx count 0x%zx ioflags %s",
801 "offset 0x%llx count 0x%zx ioflags %s", \ 805 MAJOR(__entry->dev), MINOR(__entry->dev),
802 MAJOR(__entry->dev), MINOR(__entry->dev), \ 806 __entry->ino,
803 __entry->ino, \ 807 __entry->size,
804 __entry->size, \ 808 __entry->new_size,
805 __entry->new_size, \ 809 __entry->offset,
806 __entry->offset, \ 810 __entry->count,
807 __entry->count, \ 811 __print_flags(__entry->flags, "|", XFS_IO_FLAGS))
808 __print_flags(__entry->flags, "|", XFS_IO_FLAGS)) \
809) 812)
813
814#define DEFINE_RW_EVENT(name) \
815DEFINE_EVENT(xfs_file_class, name, \
816 TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), \
817 TP_ARGS(ip, count, offset, flags))
810DEFINE_RW_EVENT(xfs_file_read); 818DEFINE_RW_EVENT(xfs_file_read);
811DEFINE_RW_EVENT(xfs_file_buffered_write); 819DEFINE_RW_EVENT(xfs_file_buffered_write);
812DEFINE_RW_EVENT(xfs_file_direct_write); 820DEFINE_RW_EVENT(xfs_file_direct_write);
813DEFINE_RW_EVENT(xfs_file_splice_read); 821DEFINE_RW_EVENT(xfs_file_splice_read);
814DEFINE_RW_EVENT(xfs_file_splice_write); 822DEFINE_RW_EVENT(xfs_file_splice_write);
815 823
816 824DECLARE_EVENT_CLASS(xfs_page_class,
817#define DEFINE_PAGE_EVENT(name) \ 825 TP_PROTO(struct inode *inode, struct page *page, unsigned long off),
818TRACE_EVENT(name, \ 826 TP_ARGS(inode, page, off),
819 TP_PROTO(struct inode *inode, struct page *page, unsigned long off), \ 827 TP_STRUCT__entry(
820 TP_ARGS(inode, page, off), \ 828 __field(dev_t, dev)
821 TP_STRUCT__entry( \ 829 __field(xfs_ino_t, ino)
822 __field(dev_t, dev) \ 830 __field(pgoff_t, pgoff)
823 __field(xfs_ino_t, ino) \ 831 __field(loff_t, size)
824 __field(pgoff_t, pgoff) \ 832 __field(unsigned long, offset)
825 __field(loff_t, size) \ 833 __field(int, delalloc)
826 __field(unsigned long, offset) \ 834 __field(int, unmapped)
827 __field(int, delalloc) \ 835 __field(int, unwritten)
828 __field(int, unmapped) \ 836 ),
829 __field(int, unwritten) \ 837 TP_fast_assign(
830 ), \ 838 int delalloc = -1, unmapped = -1, unwritten = -1;
831 TP_fast_assign( \ 839
832 int delalloc = -1, unmapped = -1, unwritten = -1; \ 840 if (page_has_buffers(page))
833 \ 841 xfs_count_page_state(page, &delalloc,
834 if (page_has_buffers(page)) \ 842 &unmapped, &unwritten);
835 xfs_count_page_state(page, &delalloc, \ 843 __entry->dev = inode->i_sb->s_dev;
836 &unmapped, &unwritten); \ 844 __entry->ino = XFS_I(inode)->i_ino;
837 __entry->dev = inode->i_sb->s_dev; \ 845 __entry->pgoff = page_offset(page);
838 __entry->ino = XFS_I(inode)->i_ino; \ 846 __entry->size = i_size_read(inode);
839 __entry->pgoff = page_offset(page); \ 847 __entry->offset = off;
840 __entry->size = i_size_read(inode); \ 848 __entry->delalloc = delalloc;
841 __entry->offset = off; \ 849 __entry->unmapped = unmapped;
842 __entry->delalloc = delalloc; \ 850 __entry->unwritten = unwritten;
843 __entry->unmapped = unmapped; \ 851 ),
844 __entry->unwritten = unwritten; \ 852 TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx "
845 ), \ 853 "delalloc %d unmapped %d unwritten %d",
846 TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " \ 854 MAJOR(__entry->dev), MINOR(__entry->dev),
847 "delalloc %d unmapped %d unwritten %d", \ 855 __entry->ino,
848 MAJOR(__entry->dev), MINOR(__entry->dev), \ 856 __entry->pgoff,
849 __entry->ino, \ 857 __entry->size,
850 __entry->pgoff, \ 858 __entry->offset,
851 __entry->size, \ 859 __entry->delalloc,
852 __entry->offset, \ 860 __entry->unmapped,
853 __entry->delalloc, \ 861 __entry->unwritten)
854 __entry->unmapped, \
855 __entry->unwritten) \
856) 862)
863
864#define DEFINE_PAGE_EVENT(name) \
865DEFINE_EVENT(xfs_page_class, name, \
866 TP_PROTO(struct inode *inode, struct page *page, unsigned long off), \
867 TP_ARGS(inode, page, off))
857DEFINE_PAGE_EVENT(xfs_writepage); 868DEFINE_PAGE_EVENT(xfs_writepage);
858DEFINE_PAGE_EVENT(xfs_releasepage); 869DEFINE_PAGE_EVENT(xfs_releasepage);
859DEFINE_PAGE_EVENT(xfs_invalidatepage); 870DEFINE_PAGE_EVENT(xfs_invalidatepage);
860 871
861#define DEFINE_IOMAP_EVENT(name) \ 872DECLARE_EVENT_CLASS(xfs_iomap_class,
862TRACE_EVENT(name, \ 873 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count,
863 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \ 874 int flags, struct xfs_bmbt_irec *irec),
864 int flags, struct xfs_bmbt_irec *irec), \ 875 TP_ARGS(ip, offset, count, flags, irec),
865 TP_ARGS(ip, offset, count, flags, irec), \ 876 TP_STRUCT__entry(
866 TP_STRUCT__entry( \ 877 __field(dev_t, dev)
867 __field(dev_t, dev) \ 878 __field(xfs_ino_t, ino)
868 __field(xfs_ino_t, ino) \ 879 __field(loff_t, size)
869 __field(loff_t, size) \ 880 __field(loff_t, new_size)
870 __field(loff_t, new_size) \ 881 __field(loff_t, offset)
871 __field(loff_t, offset) \ 882 __field(size_t, count)
872 __field(size_t, count) \ 883 __field(int, flags)
873 __field(int, flags) \ 884 __field(xfs_fileoff_t, startoff)
874 __field(xfs_fileoff_t, startoff) \ 885 __field(xfs_fsblock_t, startblock)
875 __field(xfs_fsblock_t, startblock) \ 886 __field(xfs_filblks_t, blockcount)
876 __field(xfs_filblks_t, blockcount) \ 887 ),
877 ), \ 888 TP_fast_assign(
878 TP_fast_assign( \ 889 __entry->dev = VFS_I(ip)->i_sb->s_dev;
879 __entry->dev = VFS_I(ip)->i_sb->s_dev; \ 890 __entry->ino = ip->i_ino;
880 __entry->ino = ip->i_ino; \ 891 __entry->size = ip->i_d.di_size;
881 __entry->size = ip->i_d.di_size; \ 892 __entry->new_size = ip->i_new_size;
882 __entry->new_size = ip->i_new_size; \ 893 __entry->offset = offset;
883 __entry->offset = offset; \ 894 __entry->count = count;
884 __entry->count = count; \ 895 __entry->flags = flags;
885 __entry->flags = flags; \ 896 __entry->startoff = irec ? irec->br_startoff : 0;
886 __entry->startoff = irec ? irec->br_startoff : 0; \ 897 __entry->startblock = irec ? irec->br_startblock : 0;
887 __entry->startblock = irec ? irec->br_startblock : 0; \ 898 __entry->blockcount = irec ? irec->br_blockcount : 0;
888 __entry->blockcount = irec ? irec->br_blockcount : 0; \ 899 ),
889 ), \ 900 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx "
890 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ 901 "offset 0x%llx count %zd flags %s "
891 "offset 0x%llx count %zd flags %s " \ 902 "startoff 0x%llx startblock %lld blockcount 0x%llx",
892 "startoff 0x%llx startblock %lld blockcount 0x%llx", \ 903 MAJOR(__entry->dev), MINOR(__entry->dev),
893 MAJOR(__entry->dev), MINOR(__entry->dev), \ 904 __entry->ino,
894 __entry->ino, \ 905 __entry->size,
895 __entry->size, \ 906 __entry->new_size,
896 __entry->new_size, \ 907 __entry->offset,
897 __entry->offset, \ 908 __entry->count,
898 __entry->count, \ 909 __print_flags(__entry->flags, "|", BMAPI_FLAGS),
899 __print_flags(__entry->flags, "|", BMAPI_FLAGS), \ 910 __entry->startoff,
900 __entry->startoff, \ 911 (__int64_t)__entry->startblock,
901 (__int64_t)__entry->startblock, \ 912 __entry->blockcount)
902 __entry->blockcount) \
903) 913)
914
915#define DEFINE_IOMAP_EVENT(name) \
916DEFINE_EVENT(xfs_iomap_class, name, \
917 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \
918 int flags, struct xfs_bmbt_irec *irec), \
919 TP_ARGS(ip, offset, count, flags, irec))
904DEFINE_IOMAP_EVENT(xfs_iomap_enter); 920DEFINE_IOMAP_EVENT(xfs_iomap_enter);
905DEFINE_IOMAP_EVENT(xfs_iomap_found); 921DEFINE_IOMAP_EVENT(xfs_iomap_found);
906DEFINE_IOMAP_EVENT(xfs_iomap_alloc); 922DEFINE_IOMAP_EVENT(xfs_iomap_alloc);
907 923
908#define DEFINE_SIMPLE_IO_EVENT(name) \ 924DECLARE_EVENT_CLASS(xfs_simple_io_class,
909TRACE_EVENT(name, \ 925 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count),
910 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), \ 926 TP_ARGS(ip, offset, count),
911 TP_ARGS(ip, offset, count), \ 927 TP_STRUCT__entry(
912 TP_STRUCT__entry( \ 928 __field(dev_t, dev)
913 __field(dev_t, dev) \ 929 __field(xfs_ino_t, ino)
914 __field(xfs_ino_t, ino) \ 930 __field(loff_t, size)
915 __field(loff_t, size) \ 931 __field(loff_t, new_size)
916 __field(loff_t, new_size) \ 932 __field(loff_t, offset)
917 __field(loff_t, offset) \ 933 __field(size_t, count)
918 __field(size_t, count) \ 934 ),
919 ), \ 935 TP_fast_assign(
920 TP_fast_assign( \ 936 __entry->dev = VFS_I(ip)->i_sb->s_dev;
921 __entry->dev = VFS_I(ip)->i_sb->s_dev; \ 937 __entry->ino = ip->i_ino;
922 __entry->ino = ip->i_ino; \ 938 __entry->size = ip->i_d.di_size;
923 __entry->size = ip->i_d.di_size; \ 939 __entry->new_size = ip->i_new_size;
924 __entry->new_size = ip->i_new_size; \ 940 __entry->offset = offset;
925 __entry->offset = offset; \ 941 __entry->count = count;
926 __entry->count = count; \ 942 ),
927 ), \ 943 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx "
928 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ 944 "offset 0x%llx count %zd",
929 "offset 0x%llx count %zd", \ 945 MAJOR(__entry->dev), MINOR(__entry->dev),
930 MAJOR(__entry->dev), MINOR(__entry->dev), \ 946 __entry->ino,
931 __entry->ino, \ 947 __entry->size,
932 __entry->size, \ 948 __entry->new_size,
933 __entry->new_size, \ 949 __entry->offset,
934 __entry->offset, \ 950 __entry->count)
935 __entry->count) \
936); 951);
952
953#define DEFINE_SIMPLE_IO_EVENT(name) \
954DEFINE_EVENT(xfs_simple_io_class, name, \
955 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), \
956 TP_ARGS(ip, offset, count))
937DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); 957DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc);
938DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); 958DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert);
939 959
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 38e764146644..2d8b7bc792c9 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -249,8 +249,10 @@ xfs_qm_hold_quotafs_ref(
249 249
250 if (!xfs_Gqm) { 250 if (!xfs_Gqm) {
251 xfs_Gqm = xfs_Gqm_init(); 251 xfs_Gqm = xfs_Gqm_init();
252 if (!xfs_Gqm) 252 if (!xfs_Gqm) {
253 mutex_unlock(&xfs_Gqm_lock);
253 return ENOMEM; 254 return ENOMEM;
255 }
254 } 256 }
255 257
256 /* 258 /*
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 401f364ad36c..4917d4eed4ed 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -227,7 +227,6 @@ typedef struct xfs_perag {
227 227
228 atomic_t pagf_fstrms; /* # of filestreams active in this AG */ 228 atomic_t pagf_fstrms; /* # of filestreams active in this AG */
229 229
230 int pag_ici_init; /* incore inode cache initialised */
231 rwlock_t pag_ici_lock; /* incore inode lock */ 230 rwlock_t pag_ici_lock; /* incore inode lock */
232 struct radix_tree_root pag_ici_root; /* incore inode cache root */ 231 struct radix_tree_root pag_ici_root; /* incore inode cache root */
233 int pag_ici_reclaimable; /* reclaimable inodes */ 232 int pag_ici_reclaimable; /* reclaimable inodes */
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 6845db90818f..75df75f43d48 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -382,9 +382,6 @@ xfs_iget(
382 382
383 /* get the perag structure and ensure that it's inode capable */ 383 /* get the perag structure and ensure that it's inode capable */
384 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); 384 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino));
385 if (!pag->pagi_inodeok)
386 return EINVAL;
387 ASSERT(pag->pag_ici_init);
388 agino = XFS_INO_TO_AGINO(mp, ino); 385 agino = XFS_INO_TO_AGINO(mp, ino);
389 386
390again: 387again:
@@ -744,30 +741,24 @@ xfs_ilock_demote(
744} 741}
745 742
746#ifdef DEBUG 743#ifdef DEBUG
747/*
748 * Debug-only routine, without additional rw_semaphore APIs, we can
749 * now only answer requests regarding whether we hold the lock for write
750 * (reader state is outside our visibility, we only track writer state).
751 *
752 * Note: this means !xfs_isilocked would give false positives, so don't do that.
753 */
754int 744int
755xfs_isilocked( 745xfs_isilocked(
756 xfs_inode_t *ip, 746 xfs_inode_t *ip,
757 uint lock_flags) 747 uint lock_flags)
758{ 748{
759 if ((lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) == 749 if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) {
760 XFS_ILOCK_EXCL) { 750 if (!(lock_flags & XFS_ILOCK_SHARED))
761 if (!ip->i_lock.mr_writer) 751 return !!ip->i_lock.mr_writer;
762 return 0; 752 return rwsem_is_locked(&ip->i_lock.mr_lock);
763 } 753 }
764 754
765 if ((lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) == 755 if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) {
766 XFS_IOLOCK_EXCL) { 756 if (!(lock_flags & XFS_IOLOCK_SHARED))
767 if (!ip->i_iolock.mr_writer) 757 return !!ip->i_iolock.mr_writer;
768 return 0; 758 return rwsem_is_locked(&ip->i_iolock.mr_lock);
769 } 759 }
770 760
771 return 1; 761 ASSERT(0);
762 return 0;
772} 763}
773#endif 764#endif
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 8cd6e8d8fe9c..d53c39de7d05 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1940,10 +1940,10 @@ xfs_ifree_cluster(
1940 int blks_per_cluster; 1940 int blks_per_cluster;
1941 int nbufs; 1941 int nbufs;
1942 int ninodes; 1942 int ninodes;
1943 int i, j, found, pre_flushed; 1943 int i, j;
1944 xfs_daddr_t blkno; 1944 xfs_daddr_t blkno;
1945 xfs_buf_t *bp; 1945 xfs_buf_t *bp;
1946 xfs_inode_t *ip, **ip_found; 1946 xfs_inode_t *ip;
1947 xfs_inode_log_item_t *iip; 1947 xfs_inode_log_item_t *iip;
1948 xfs_log_item_t *lip; 1948 xfs_log_item_t *lip;
1949 struct xfs_perag *pag; 1949 struct xfs_perag *pag;
@@ -1960,114 +1960,97 @@ xfs_ifree_cluster(
1960 nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; 1960 nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster;
1961 } 1961 }
1962 1962
1963 ip_found = kmem_alloc(ninodes * sizeof(xfs_inode_t *), KM_NOFS);
1964
1965 for (j = 0; j < nbufs; j++, inum += ninodes) { 1963 for (j = 0; j < nbufs; j++, inum += ninodes) {
1964 int found = 0;
1965
1966 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), 1966 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),
1967 XFS_INO_TO_AGBNO(mp, inum)); 1967 XFS_INO_TO_AGBNO(mp, inum));
1968 1968
1969 /*
1970 * We obtain and lock the backing buffer first in the process
1971 * here, as we have to ensure that any dirty inode that we
1972 * can't get the flush lock on is attached to the buffer.
1973 * If we scan the in-memory inodes first, then buffer IO can
1974 * complete before we get a lock on it, and hence we may fail
1975 * to mark all the active inodes on the buffer stale.
1976 */
1977 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
1978 mp->m_bsize * blks_per_cluster,
1979 XBF_LOCK);
1980
1981 /*
1982 * Walk the inodes already attached to the buffer and mark them
1983 * stale. These will all have the flush locks held, so an
1984 * in-memory inode walk can't lock them.
1985 */
1986 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
1987 while (lip) {
1988 if (lip->li_type == XFS_LI_INODE) {
1989 iip = (xfs_inode_log_item_t *)lip;
1990 ASSERT(iip->ili_logged == 1);
1991 lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done;
1992 xfs_trans_ail_copy_lsn(mp->m_ail,
1993 &iip->ili_flush_lsn,
1994 &iip->ili_item.li_lsn);
1995 xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
1996 found++;
1997 }
1998 lip = lip->li_bio_list;
1999 }
1969 2000
1970 /* 2001 /*
1971 * Look for each inode in memory and attempt to lock it, 2002 * For each inode in memory attempt to add it to the inode
1972 * we can be racing with flush and tail pushing here. 2003 * buffer and set it up for being staled on buffer IO
1973 * any inode we get the locks on, add to an array of 2004 * completion. This is safe as we've locked out tail pushing
1974 * inode items to process later. 2005 * and flushing by locking the buffer.
1975 * 2006 *
1976 * The get the buffer lock, we could beat a flush 2007 * We have already marked every inode that was part of a
1977 * or tail pushing thread to the lock here, in which 2008 * transaction stale above, which means there is no point in
1978 * case they will go looking for the inode buffer 2009 * even trying to lock them.
1979 * and fail, we need some other form of interlock
1980 * here.
1981 */ 2010 */
1982 found = 0;
1983 for (i = 0; i < ninodes; i++) { 2011 for (i = 0; i < ninodes; i++) {
1984 read_lock(&pag->pag_ici_lock); 2012 read_lock(&pag->pag_ici_lock);
1985 ip = radix_tree_lookup(&pag->pag_ici_root, 2013 ip = radix_tree_lookup(&pag->pag_ici_root,
1986 XFS_INO_TO_AGINO(mp, (inum + i))); 2014 XFS_INO_TO_AGINO(mp, (inum + i)));
1987 2015
1988 /* Inode not in memory or we found it already, 2016 /* Inode not in memory or stale, nothing to do */
1989 * nothing to do
1990 */
1991 if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { 2017 if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) {
1992 read_unlock(&pag->pag_ici_lock); 2018 read_unlock(&pag->pag_ici_lock);
1993 continue; 2019 continue;
1994 } 2020 }
1995 2021
1996 if (xfs_inode_clean(ip)) { 2022 /* don't try to lock/unlock the current inode */
1997 read_unlock(&pag->pag_ici_lock); 2023 if (ip != free_ip &&
1998 continue; 2024 !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
1999 }
2000
2001 /* If we can get the locks then add it to the
2002 * list, otherwise by the time we get the bp lock
2003 * below it will already be attached to the
2004 * inode buffer.
2005 */
2006
2007 /* This inode will already be locked - by us, lets
2008 * keep it that way.
2009 */
2010
2011 if (ip == free_ip) {
2012 if (xfs_iflock_nowait(ip)) {
2013 xfs_iflags_set(ip, XFS_ISTALE);
2014 if (xfs_inode_clean(ip)) {
2015 xfs_ifunlock(ip);
2016 } else {
2017 ip_found[found++] = ip;
2018 }
2019 }
2020 read_unlock(&pag->pag_ici_lock); 2025 read_unlock(&pag->pag_ici_lock);
2021 continue; 2026 continue;
2022 } 2027 }
2028 read_unlock(&pag->pag_ici_lock);
2023 2029
2024 if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { 2030 if (!xfs_iflock_nowait(ip)) {
2025 if (xfs_iflock_nowait(ip)) { 2031 if (ip != free_ip)
2026 xfs_iflags_set(ip, XFS_ISTALE);
2027
2028 if (xfs_inode_clean(ip)) {
2029 xfs_ifunlock(ip);
2030 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2031 } else {
2032 ip_found[found++] = ip;
2033 }
2034 } else {
2035 xfs_iunlock(ip, XFS_ILOCK_EXCL); 2032 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2036 } 2033 continue;
2037 } 2034 }
2038 read_unlock(&pag->pag_ici_lock);
2039 }
2040 2035
2041 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, 2036 xfs_iflags_set(ip, XFS_ISTALE);
2042 mp->m_bsize * blks_per_cluster, 2037 if (xfs_inode_clean(ip)) {
2043 XBF_LOCK); 2038 ASSERT(ip != free_ip);
2044 2039 xfs_ifunlock(ip);
2045 pre_flushed = 0; 2040 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2046 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 2041 continue;
2047 while (lip) {
2048 if (lip->li_type == XFS_LI_INODE) {
2049 iip = (xfs_inode_log_item_t *)lip;
2050 ASSERT(iip->ili_logged == 1);
2051 lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done;
2052 xfs_trans_ail_copy_lsn(mp->m_ail,
2053 &iip->ili_flush_lsn,
2054 &iip->ili_item.li_lsn);
2055 xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
2056 pre_flushed++;
2057 } 2042 }
2058 lip = lip->li_bio_list;
2059 }
2060 2043
2061 for (i = 0; i < found; i++) {
2062 ip = ip_found[i];
2063 iip = ip->i_itemp; 2044 iip = ip->i_itemp;
2064
2065 if (!iip) { 2045 if (!iip) {
2046 /* inode with unlogged changes only */
2047 ASSERT(ip != free_ip);
2066 ip->i_update_core = 0; 2048 ip->i_update_core = 0;
2067 xfs_ifunlock(ip); 2049 xfs_ifunlock(ip);
2068 xfs_iunlock(ip, XFS_ILOCK_EXCL); 2050 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2069 continue; 2051 continue;
2070 } 2052 }
2053 found++;
2071 2054
2072 iip->ili_last_fields = iip->ili_format.ilf_fields; 2055 iip->ili_last_fields = iip->ili_format.ilf_fields;
2073 iip->ili_format.ilf_fields = 0; 2056 iip->ili_format.ilf_fields = 0;
@@ -2078,17 +2061,16 @@ xfs_ifree_cluster(
2078 xfs_buf_attach_iodone(bp, 2061 xfs_buf_attach_iodone(bp,
2079 (void(*)(xfs_buf_t*,xfs_log_item_t*)) 2062 (void(*)(xfs_buf_t*,xfs_log_item_t*))
2080 xfs_istale_done, (xfs_log_item_t *)iip); 2063 xfs_istale_done, (xfs_log_item_t *)iip);
2081 if (ip != free_ip) { 2064
2065 if (ip != free_ip)
2082 xfs_iunlock(ip, XFS_ILOCK_EXCL); 2066 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2083 }
2084 } 2067 }
2085 2068
2086 if (found || pre_flushed) 2069 if (found)
2087 xfs_trans_stale_inode_buf(tp, bp); 2070 xfs_trans_stale_inode_buf(tp, bp);
2088 xfs_trans_binval(tp, bp); 2071 xfs_trans_binval(tp, bp);
2089 } 2072 }
2090 2073
2091 kmem_free(ip_found);
2092 xfs_perag_put(pag); 2074 xfs_perag_put(pag);
2093} 2075}
2094 2076
@@ -2649,8 +2631,6 @@ xfs_iflush_cluster(
2649 int i; 2631 int i;
2650 2632
2651 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); 2633 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
2652 ASSERT(pag->pagi_inodeok);
2653 ASSERT(pag->pag_ici_init);
2654 2634
2655 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; 2635 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog;
2656 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); 2636 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 14a69aec2c0b..ed0684cc50ee 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -132,15 +132,10 @@ xlog_align(
132 int nbblks, 132 int nbblks,
133 xfs_buf_t *bp) 133 xfs_buf_t *bp)
134{ 134{
135 xfs_daddr_t offset; 135 xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1);
136 xfs_caddr_t ptr;
137 136
138 offset = blk_no & ((xfs_daddr_t) log->l_sectBBsize - 1); 137 ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp));
139 ptr = XFS_BUF_PTR(bp) + BBTOB(offset); 138 return XFS_BUF_PTR(bp) + BBTOB(offset);
140
141 ASSERT(ptr + BBTOB(nbblks) <= XFS_BUF_PTR(bp) + XFS_BUF_SIZE(bp));
142
143 return ptr;
144} 139}
145 140
146 141
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index d7bf38c8cd1c..d59f4e8bedcf 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -268,10 +268,10 @@ xfs_sb_validate_fsb_count(
268 268
269#if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ 269#if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */
270 if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX) 270 if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX)
271 return E2BIG; 271 return EFBIG;
272#else /* Limited by UINT_MAX of sectors */ 272#else /* Limited by UINT_MAX of sectors */
273 if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX) 273 if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX)
274 return E2BIG; 274 return EFBIG;
275#endif 275#endif
276 return 0; 276 return 0;
277} 277}
@@ -393,7 +393,7 @@ xfs_mount_validate_sb(
393 xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { 393 xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {
394 xfs_fs_mount_cmn_err(flags, 394 xfs_fs_mount_cmn_err(flags,
395 "file system too large to be mounted on this system."); 395 "file system too large to be mounted on this system.");
396 return XFS_ERROR(E2BIG); 396 return XFS_ERROR(EFBIG);
397 } 397 }
398 398
399 if (unlikely(sbp->sb_inprogress)) { 399 if (unlikely(sbp->sb_inprogress)) {
@@ -413,17 +413,6 @@ xfs_mount_validate_sb(
413 return 0; 413 return 0;
414} 414}
415 415
416STATIC void
417xfs_initialize_perag_icache(
418 xfs_perag_t *pag)
419{
420 if (!pag->pag_ici_init) {
421 rwlock_init(&pag->pag_ici_lock);
422 INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
423 pag->pag_ici_init = 1;
424 }
425}
426
427int 416int
428xfs_initialize_perag( 417xfs_initialize_perag(
429 xfs_mount_t *mp, 418 xfs_mount_t *mp,
@@ -436,13 +425,8 @@ xfs_initialize_perag(
436 xfs_agino_t agino; 425 xfs_agino_t agino;
437 xfs_ino_t ino; 426 xfs_ino_t ino;
438 xfs_sb_t *sbp = &mp->m_sb; 427 xfs_sb_t *sbp = &mp->m_sb;
439 xfs_ino_t max_inum = XFS_MAXINUMBER_32;
440 int error = -ENOMEM; 428 int error = -ENOMEM;
441 429
442 /* Check to see if the filesystem can overflow 32 bit inodes */
443 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
444 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
445
446 /* 430 /*
447 * Walk the current per-ag tree so we don't try to initialise AGs 431 * Walk the current per-ag tree so we don't try to initialise AGs
448 * that already exist (growfs case). Allocate and insert all the 432 * that already exist (growfs case). Allocate and insert all the
@@ -456,11 +440,18 @@ xfs_initialize_perag(
456 } 440 }
457 if (!first_initialised) 441 if (!first_initialised)
458 first_initialised = index; 442 first_initialised = index;
443
459 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); 444 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL);
460 if (!pag) 445 if (!pag)
461 goto out_unwind; 446 goto out_unwind;
447 pag->pag_agno = index;
448 pag->pag_mount = mp;
449 rwlock_init(&pag->pag_ici_lock);
450 INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
451
462 if (radix_tree_preload(GFP_NOFS)) 452 if (radix_tree_preload(GFP_NOFS))
463 goto out_unwind; 453 goto out_unwind;
454
464 spin_lock(&mp->m_perag_lock); 455 spin_lock(&mp->m_perag_lock);
465 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { 456 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {
466 BUG(); 457 BUG();
@@ -469,25 +460,26 @@ xfs_initialize_perag(
469 error = -EEXIST; 460 error = -EEXIST;
470 goto out_unwind; 461 goto out_unwind;
471 } 462 }
472 pag->pag_agno = index;
473 pag->pag_mount = mp;
474 spin_unlock(&mp->m_perag_lock); 463 spin_unlock(&mp->m_perag_lock);
475 radix_tree_preload_end(); 464 radix_tree_preload_end();
476 } 465 }
477 466
478 /* Clear the mount flag if no inode can overflow 32 bits 467 /*
479 * on this filesystem, or if specifically requested.. 468 * If we mount with the inode64 option, or no inode overflows
469 * the legacy 32-bit address space clear the inode32 option.
480 */ 470 */
481 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) { 471 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
472 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
473
474 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
482 mp->m_flags |= XFS_MOUNT_32BITINODES; 475 mp->m_flags |= XFS_MOUNT_32BITINODES;
483 } else { 476 else
484 mp->m_flags &= ~XFS_MOUNT_32BITINODES; 477 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
485 }
486 478
487 /* If we can overflow then setup the ag headers accordingly */
488 if (mp->m_flags & XFS_MOUNT_32BITINODES) { 479 if (mp->m_flags & XFS_MOUNT_32BITINODES) {
489 /* Calculate how much should be reserved for inodes to 480 /*
490 * meet the max inode percentage. 481 * Calculate how much should be reserved for inodes to meet
482 * the max inode percentage.
491 */ 483 */
492 if (mp->m_maxicount) { 484 if (mp->m_maxicount) {
493 __uint64_t icount; 485 __uint64_t icount;
@@ -500,30 +492,28 @@ xfs_initialize_perag(
500 } else { 492 } else {
501 max_metadata = agcount; 493 max_metadata = agcount;
502 } 494 }
495
503 for (index = 0; index < agcount; index++) { 496 for (index = 0; index < agcount; index++) {
504 ino = XFS_AGINO_TO_INO(mp, index, agino); 497 ino = XFS_AGINO_TO_INO(mp, index, agino);
505 if (ino > max_inum) { 498 if (ino > XFS_MAXINUMBER_32) {
506 index++; 499 index++;
507 break; 500 break;
508 } 501 }
509 502
510 /* This ag is preferred for inodes */
511 pag = xfs_perag_get(mp, index); 503 pag = xfs_perag_get(mp, index);
512 pag->pagi_inodeok = 1; 504 pag->pagi_inodeok = 1;
513 if (index < max_metadata) 505 if (index < max_metadata)
514 pag->pagf_metadata = 1; 506 pag->pagf_metadata = 1;
515 xfs_initialize_perag_icache(pag);
516 xfs_perag_put(pag); 507 xfs_perag_put(pag);
517 } 508 }
518 } else { 509 } else {
519 /* Setup default behavior for smaller filesystems */
520 for (index = 0; index < agcount; index++) { 510 for (index = 0; index < agcount; index++) {
521 pag = xfs_perag_get(mp, index); 511 pag = xfs_perag_get(mp, index);
522 pag->pagi_inodeok = 1; 512 pag->pagi_inodeok = 1;
523 xfs_initialize_perag_icache(pag);
524 xfs_perag_put(pag); 513 xfs_perag_put(pag);
525 } 514 }
526 } 515 }
516
527 if (maxagi) 517 if (maxagi)
528 *maxagi = index; 518 *maxagi = index;
529 return 0; 519 return 0;
@@ -1009,7 +999,7 @@ xfs_check_sizes(xfs_mount_t *mp)
1009 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); 999 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
1010 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { 1000 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
1011 cmn_err(CE_WARN, "XFS: size check 1 failed"); 1001 cmn_err(CE_WARN, "XFS: size check 1 failed");
1012 return XFS_ERROR(E2BIG); 1002 return XFS_ERROR(EFBIG);
1013 } 1003 }
1014 error = xfs_read_buf(mp, mp->m_ddev_targp, 1004 error = xfs_read_buf(mp, mp->m_ddev_targp,
1015 d - XFS_FSS_TO_BB(mp, 1), 1005 d - XFS_FSS_TO_BB(mp, 1),
@@ -1019,7 +1009,7 @@ xfs_check_sizes(xfs_mount_t *mp)
1019 } else { 1009 } else {
1020 cmn_err(CE_WARN, "XFS: size check 2 failed"); 1010 cmn_err(CE_WARN, "XFS: size check 2 failed");
1021 if (error == ENOSPC) 1011 if (error == ENOSPC)
1022 error = XFS_ERROR(E2BIG); 1012 error = XFS_ERROR(EFBIG);
1023 return error; 1013 return error;
1024 } 1014 }
1025 1015
@@ -1027,7 +1017,7 @@ xfs_check_sizes(xfs_mount_t *mp)
1027 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); 1017 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
1028 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { 1018 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {
1029 cmn_err(CE_WARN, "XFS: size check 3 failed"); 1019 cmn_err(CE_WARN, "XFS: size check 3 failed");
1030 return XFS_ERROR(E2BIG); 1020 return XFS_ERROR(EFBIG);
1031 } 1021 }
1032 error = xfs_read_buf(mp, mp->m_logdev_targp, 1022 error = xfs_read_buf(mp, mp->m_logdev_targp,
1033 d - XFS_FSB_TO_BB(mp, 1), 1023 d - XFS_FSB_TO_BB(mp, 1),
@@ -1037,7 +1027,7 @@ xfs_check_sizes(xfs_mount_t *mp)
1037 } else { 1027 } else {
1038 cmn_err(CE_WARN, "XFS: size check 3 failed"); 1028 cmn_err(CE_WARN, "XFS: size check 3 failed");
1039 if (error == ENOSPC) 1029 if (error == ENOSPC)
1040 error = XFS_ERROR(E2BIG); 1030 error = XFS_ERROR(EFBIG);
1041 return error; 1031 return error;
1042 } 1032 }
1043 } 1033 }
@@ -1254,7 +1244,7 @@ xfs_mountfs(
1254 * Allocate and initialize the per-ag data. 1244 * Allocate and initialize the per-ag data.
1255 */ 1245 */
1256 spin_lock_init(&mp->m_perag_lock); 1246 spin_lock_init(&mp->m_perag_lock);
1257 INIT_RADIX_TREE(&mp->m_perag_tree, GFP_NOFS); 1247 INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
1258 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); 1248 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
1259 if (error) { 1249 if (error) {
1260 cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error); 1250 cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error);
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 6be05f756d59..16445518506d 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -2247,7 +2247,7 @@ xfs_rtmount_init(
2247 cmn_err(CE_WARN, "XFS: realtime mount -- %llu != %llu", 2247 cmn_err(CE_WARN, "XFS: realtime mount -- %llu != %llu",
2248 (unsigned long long) XFS_BB_TO_FSB(mp, d), 2248 (unsigned long long) XFS_BB_TO_FSB(mp, d),
2249 (unsigned long long) mp->m_sb.sb_rblocks); 2249 (unsigned long long) mp->m_sb.sb_rblocks);
2250 return XFS_ERROR(E2BIG); 2250 return XFS_ERROR(EFBIG);
2251 } 2251 }
2252 error = xfs_read_buf(mp, mp->m_rtdev_targp, 2252 error = xfs_read_buf(mp, mp->m_rtdev_targp,
2253 d - XFS_FSB_TO_BB(mp, 1), 2253 d - XFS_FSB_TO_BB(mp, 1),
@@ -2256,7 +2256,7 @@ xfs_rtmount_init(
2256 cmn_err(CE_WARN, 2256 cmn_err(CE_WARN,
2257 "XFS: realtime mount -- xfs_read_buf failed, returned %d", error); 2257 "XFS: realtime mount -- xfs_read_buf failed, returned %d", error);
2258 if (error == ENOSPC) 2258 if (error == ENOSPC)
2259 return XFS_ERROR(E2BIG); 2259 return XFS_ERROR(EFBIG);
2260 return error; 2260 return error;
2261 } 2261 }
2262 xfs_buf_relse(bp); 2262 xfs_buf_relse(bp);
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index b2d67adb6a08..ff614c29b441 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -147,7 +147,16 @@ xfs_growfs_rt(
147# define xfs_rtfree_extent(t,b,l) (ENOSYS) 147# define xfs_rtfree_extent(t,b,l) (ENOSYS)
148# define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) 148# define xfs_rtpick_extent(m,t,l,rb) (ENOSYS)
149# define xfs_growfs_rt(mp,in) (ENOSYS) 149# define xfs_growfs_rt(mp,in) (ENOSYS)
150# define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) 150static inline int /* error */
151xfs_rtmount_init(
152 xfs_mount_t *mp) /* file system mount structure */
153{
154 if (mp->m_sb.sb_rblocks == 0)
155 return 0;
156
157 cmn_err(CE_WARN, "XFS: Not built with CONFIG_XFS_RT");
158 return ENOSYS;
159}
151# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) 160# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
152# define xfs_rtunmount_inodes(m) 161# define xfs_rtunmount_inodes(m)
153#endif /* CONFIG_XFS_RT */ 162#endif /* CONFIG_XFS_RT */
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index ce558efa2ea0..28547dfce037 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -48,134 +48,489 @@
48 48
49kmem_zone_t *xfs_trans_zone; 49kmem_zone_t *xfs_trans_zone;
50 50
51
51/* 52/*
52 * Reservation functions here avoid a huge stack in xfs_trans_init 53 * Various log reservation values.
53 * due to register overflow from temporaries in the calculations. 54 *
55 * These are based on the size of the file system block because that is what
56 * most transactions manipulate. Each adds in an additional 128 bytes per
57 * item logged to try to account for the overhead of the transaction mechanism.
58 *
59 * Note: Most of the reservations underestimate the number of allocation
60 * groups into which they could free extents in the xfs_bmap_finish() call.
61 * This is because the number in the worst case is quite high and quite
62 * unusual. In order to fix this we need to change xfs_bmap_finish() to free
63 * extents in only a single AG at a time. This will require changes to the
64 * EFI code as well, however, so that the EFI for the extents not freed is
65 * logged again in each transaction. See SGI PV #261917.
66 *
67 * Reservation functions here avoid a huge stack in xfs_trans_init due to
68 * register overflow from temporaries in the calculations.
69 */
70
71
72/*
73 * In a write transaction we can allocate a maximum of 2
74 * extents. This gives:
75 * the inode getting the new extents: inode size
76 * the inode's bmap btree: max depth * block size
77 * the agfs of the ags from which the extents are allocated: 2 * sector
78 * the superblock free block counter: sector size
79 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
80 * And the bmap_finish transaction can free bmap blocks in a join:
81 * the agfs of the ags containing the blocks: 2 * sector size
82 * the agfls of the ags containing the blocks: 2 * sector size
83 * the super block free block counter: sector size
84 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
54 */ 85 */
55STATIC uint 86STATIC uint
56xfs_calc_write_reservation(xfs_mount_t *mp) 87xfs_calc_write_reservation(
88 struct xfs_mount *mp)
57{ 89{
58 return XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 90 return XFS_DQUOT_LOGRES(mp) +
91 MAX((mp->m_sb.sb_inodesize +
92 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) +
93 2 * mp->m_sb.sb_sectsize +
94 mp->m_sb.sb_sectsize +
95 XFS_ALLOCFREE_LOG_RES(mp, 2) +
96 128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) +
97 XFS_ALLOCFREE_LOG_COUNT(mp, 2))),
98 (2 * mp->m_sb.sb_sectsize +
99 2 * mp->m_sb.sb_sectsize +
100 mp->m_sb.sb_sectsize +
101 XFS_ALLOCFREE_LOG_RES(mp, 2) +
102 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));
59} 103}
60 104
105/*
106 * In truncating a file we free up to two extents at once. We can modify:
107 * the inode being truncated: inode size
108 * the inode's bmap btree: (max depth + 1) * block size
109 * And the bmap_finish transaction can free the blocks and bmap blocks:
110 * the agf for each of the ags: 4 * sector size
111 * the agfl for each of the ags: 4 * sector size
112 * the super block to reflect the freed blocks: sector size
113 * worst case split in allocation btrees per extent assuming 4 extents:
114 * 4 exts * 2 trees * (2 * max depth - 1) * block size
115 * the inode btree: max depth * blocksize
116 * the allocation btrees: 2 trees * (max depth - 1) * block size
117 */
61STATIC uint 118STATIC uint
62xfs_calc_itruncate_reservation(xfs_mount_t *mp) 119xfs_calc_itruncate_reservation(
120 struct xfs_mount *mp)
63{ 121{
64 return XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 122 return XFS_DQUOT_LOGRES(mp) +
123 MAX((mp->m_sb.sb_inodesize +
124 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) +
125 128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))),
126 (4 * mp->m_sb.sb_sectsize +
127 4 * mp->m_sb.sb_sectsize +
128 mp->m_sb.sb_sectsize +
129 XFS_ALLOCFREE_LOG_RES(mp, 4) +
130 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)) +
131 128 * 5 +
132 XFS_ALLOCFREE_LOG_RES(mp, 1) +
133 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +
134 XFS_ALLOCFREE_LOG_COUNT(mp, 1))));
65} 135}
66 136
137/*
138 * In renaming a files we can modify:
139 * the four inodes involved: 4 * inode size
140 * the two directory btrees: 2 * (max depth + v2) * dir block size
141 * the two directory bmap btrees: 2 * max depth * block size
142 * And the bmap_finish transaction can free dir and bmap blocks (two sets
143 * of bmap blocks) giving:
144 * the agf for the ags in which the blocks live: 3 * sector size
145 * the agfl for the ags in which the blocks live: 3 * sector size
146 * the superblock for the free block count: sector size
147 * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size
148 */
67STATIC uint 149STATIC uint
68xfs_calc_rename_reservation(xfs_mount_t *mp) 150xfs_calc_rename_reservation(
151 struct xfs_mount *mp)
69{ 152{
70 return XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 153 return XFS_DQUOT_LOGRES(mp) +
154 MAX((4 * mp->m_sb.sb_inodesize +
155 2 * XFS_DIROP_LOG_RES(mp) +
156 128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp))),
157 (3 * mp->m_sb.sb_sectsize +
158 3 * mp->m_sb.sb_sectsize +
159 mp->m_sb.sb_sectsize +
160 XFS_ALLOCFREE_LOG_RES(mp, 3) +
161 128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3))));
71} 162}
72 163
164/*
165 * For creating a link to an inode:
166 * the parent directory inode: inode size
167 * the linked inode: inode size
168 * the directory btree could split: (max depth + v2) * dir block size
169 * the directory bmap btree could join or split: (max depth + v2) * blocksize
170 * And the bmap_finish transaction can free some bmap blocks giving:
171 * the agf for the ag in which the blocks live: sector size
172 * the agfl for the ag in which the blocks live: sector size
173 * the superblock for the free block count: sector size
174 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
175 */
73STATIC uint 176STATIC uint
74xfs_calc_link_reservation(xfs_mount_t *mp) 177xfs_calc_link_reservation(
178 struct xfs_mount *mp)
75{ 179{
76 return XFS_CALC_LINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 180 return XFS_DQUOT_LOGRES(mp) +
181 MAX((mp->m_sb.sb_inodesize +
182 mp->m_sb.sb_inodesize +
183 XFS_DIROP_LOG_RES(mp) +
184 128 * (2 + XFS_DIROP_LOG_COUNT(mp))),
185 (mp->m_sb.sb_sectsize +
186 mp->m_sb.sb_sectsize +
187 mp->m_sb.sb_sectsize +
188 XFS_ALLOCFREE_LOG_RES(mp, 1) +
189 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))));
77} 190}
78 191
192/*
193 * For removing a directory entry we can modify:
194 * the parent directory inode: inode size
195 * the removed inode: inode size
196 * the directory btree could join: (max depth + v2) * dir block size
197 * the directory bmap btree could join or split: (max depth + v2) * blocksize
198 * And the bmap_finish transaction can free the dir and bmap blocks giving:
199 * the agf for the ag in which the blocks live: 2 * sector size
200 * the agfl for the ag in which the blocks live: 2 * sector size
201 * the superblock for the free block count: sector size
202 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
203 */
79STATIC uint 204STATIC uint
80xfs_calc_remove_reservation(xfs_mount_t *mp) 205xfs_calc_remove_reservation(
206 struct xfs_mount *mp)
81{ 207{
82 return XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 208 return XFS_DQUOT_LOGRES(mp) +
209 MAX((mp->m_sb.sb_inodesize +
210 mp->m_sb.sb_inodesize +
211 XFS_DIROP_LOG_RES(mp) +
212 128 * (2 + XFS_DIROP_LOG_COUNT(mp))),
213 (2 * mp->m_sb.sb_sectsize +
214 2 * mp->m_sb.sb_sectsize +
215 mp->m_sb.sb_sectsize +
216 XFS_ALLOCFREE_LOG_RES(mp, 2) +
217 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));
83} 218}
84 219
220/*
221 * For symlink we can modify:
222 * the parent directory inode: inode size
223 * the new inode: inode size
224 * the inode btree entry: 1 block
225 * the directory btree: (max depth + v2) * dir block size
226 * the directory inode's bmap btree: (max depth + v2) * block size
227 * the blocks for the symlink: 1 kB
228 * Or in the first xact we allocate some inodes giving:
229 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
230 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
231 * the inode btree: max depth * blocksize
232 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
233 */
85STATIC uint 234STATIC uint
86xfs_calc_symlink_reservation(xfs_mount_t *mp) 235xfs_calc_symlink_reservation(
236 struct xfs_mount *mp)
87{ 237{
88 return XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 238 return XFS_DQUOT_LOGRES(mp) +
239 MAX((mp->m_sb.sb_inodesize +
240 mp->m_sb.sb_inodesize +
241 XFS_FSB_TO_B(mp, 1) +
242 XFS_DIROP_LOG_RES(mp) +
243 1024 +
244 128 * (4 + XFS_DIROP_LOG_COUNT(mp))),
245 (2 * mp->m_sb.sb_sectsize +
246 XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) +
247 XFS_FSB_TO_B(mp, mp->m_in_maxlevels) +
248 XFS_ALLOCFREE_LOG_RES(mp, 1) +
249 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +
250 XFS_ALLOCFREE_LOG_COUNT(mp, 1))));
89} 251}
90 252
253/*
254 * For create we can modify:
255 * the parent directory inode: inode size
256 * the new inode: inode size
257 * the inode btree entry: block size
258 * the superblock for the nlink flag: sector size
259 * the directory btree: (max depth + v2) * dir block size
260 * the directory inode's bmap btree: (max depth + v2) * block size
261 * Or in the first xact we allocate some inodes giving:
262 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
263 * the superblock for the nlink flag: sector size
264 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
265 * the inode btree: max depth * blocksize
266 * the allocation btrees: 2 trees * (max depth - 1) * block size
267 */
91STATIC uint 268STATIC uint
92xfs_calc_create_reservation(xfs_mount_t *mp) 269xfs_calc_create_reservation(
270 struct xfs_mount *mp)
93{ 271{
94 return XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 272 return XFS_DQUOT_LOGRES(mp) +
273 MAX((mp->m_sb.sb_inodesize +
274 mp->m_sb.sb_inodesize +
275 mp->m_sb.sb_sectsize +
276 XFS_FSB_TO_B(mp, 1) +
277 XFS_DIROP_LOG_RES(mp) +
278 128 * (3 + XFS_DIROP_LOG_COUNT(mp))),
279 (3 * mp->m_sb.sb_sectsize +
280 XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) +
281 XFS_FSB_TO_B(mp, mp->m_in_maxlevels) +
282 XFS_ALLOCFREE_LOG_RES(mp, 1) +
283 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +
284 XFS_ALLOCFREE_LOG_COUNT(mp, 1))));
95} 285}
96 286
287/*
288 * Making a new directory is the same as creating a new file.
289 */
97STATIC uint 290STATIC uint
98xfs_calc_mkdir_reservation(xfs_mount_t *mp) 291xfs_calc_mkdir_reservation(
292 struct xfs_mount *mp)
99{ 293{
100 return XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 294 return xfs_calc_create_reservation(mp);
101} 295}
102 296
297/*
298 * In freeing an inode we can modify:
299 * the inode being freed: inode size
300 * the super block free inode counter: sector size
301 * the agi hash list and counters: sector size
302 * the inode btree entry: block size
303 * the on disk inode before ours in the agi hash list: inode cluster size
304 * the inode btree: max depth * blocksize
305 * the allocation btrees: 2 trees * (max depth - 1) * block size
306 */
103STATIC uint 307STATIC uint
104xfs_calc_ifree_reservation(xfs_mount_t *mp) 308xfs_calc_ifree_reservation(
309 struct xfs_mount *mp)
105{ 310{
106 return XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 311 return XFS_DQUOT_LOGRES(mp) +
312 mp->m_sb.sb_inodesize +
313 mp->m_sb.sb_sectsize +
314 mp->m_sb.sb_sectsize +
315 XFS_FSB_TO_B(mp, 1) +
316 MAX((__uint16_t)XFS_FSB_TO_B(mp, 1),
317 XFS_INODE_CLUSTER_SIZE(mp)) +
318 128 * 5 +
319 XFS_ALLOCFREE_LOG_RES(mp, 1) +
320 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +
321 XFS_ALLOCFREE_LOG_COUNT(mp, 1));
107} 322}
108 323
324/*
325 * When only changing the inode we log the inode and possibly the superblock
326 * We also add a bit of slop for the transaction stuff.
327 */
109STATIC uint 328STATIC uint
110xfs_calc_ichange_reservation(xfs_mount_t *mp) 329xfs_calc_ichange_reservation(
330 struct xfs_mount *mp)
111{ 331{
112 return XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 332 return XFS_DQUOT_LOGRES(mp) +
333 mp->m_sb.sb_inodesize +
334 mp->m_sb.sb_sectsize +
335 512;
336
113} 337}
114 338
339/*
340 * Growing the data section of the filesystem.
341 * superblock
342 * agi and agf
343 * allocation btrees
344 */
115STATIC uint 345STATIC uint
116xfs_calc_growdata_reservation(xfs_mount_t *mp) 346xfs_calc_growdata_reservation(
347 struct xfs_mount *mp)
117{ 348{
118 return XFS_CALC_GROWDATA_LOG_RES(mp); 349 return mp->m_sb.sb_sectsize * 3 +
350 XFS_ALLOCFREE_LOG_RES(mp, 1) +
351 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1));
119} 352}
120 353
354/*
355 * Growing the rt section of the filesystem.
356 * In the first set of transactions (ALLOC) we allocate space to the
357 * bitmap or summary files.
358 * superblock: sector size
359 * agf of the ag from which the extent is allocated: sector size
360 * bmap btree for bitmap/summary inode: max depth * blocksize
361 * bitmap/summary inode: inode size
362 * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize
363 */
121STATIC uint 364STATIC uint
122xfs_calc_growrtalloc_reservation(xfs_mount_t *mp) 365xfs_calc_growrtalloc_reservation(
366 struct xfs_mount *mp)
123{ 367{
124 return XFS_CALC_GROWRTALLOC_LOG_RES(mp); 368 return 2 * mp->m_sb.sb_sectsize +
369 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) +
370 mp->m_sb.sb_inodesize +
371 XFS_ALLOCFREE_LOG_RES(mp, 1) +
372 128 * (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) +
373 XFS_ALLOCFREE_LOG_COUNT(mp, 1));
125} 374}
126 375
376/*
377 * Growing the rt section of the filesystem.
378 * In the second set of transactions (ZERO) we zero the new metadata blocks.
379 * one bitmap/summary block: blocksize
380 */
127STATIC uint 381STATIC uint
128xfs_calc_growrtzero_reservation(xfs_mount_t *mp) 382xfs_calc_growrtzero_reservation(
383 struct xfs_mount *mp)
129{ 384{
130 return XFS_CALC_GROWRTZERO_LOG_RES(mp); 385 return mp->m_sb.sb_blocksize + 128;
131} 386}
132 387
388/*
389 * Growing the rt section of the filesystem.
390 * In the third set of transactions (FREE) we update metadata without
391 * allocating any new blocks.
392 * superblock: sector size
393 * bitmap inode: inode size
394 * summary inode: inode size
395 * one bitmap block: blocksize
396 * summary blocks: new summary size
397 */
133STATIC uint 398STATIC uint
134xfs_calc_growrtfree_reservation(xfs_mount_t *mp) 399xfs_calc_growrtfree_reservation(
400 struct xfs_mount *mp)
135{ 401{
136 return XFS_CALC_GROWRTFREE_LOG_RES(mp); 402 return mp->m_sb.sb_sectsize +
403 2 * mp->m_sb.sb_inodesize +
404 mp->m_sb.sb_blocksize +
405 mp->m_rsumsize +
406 128 * 5;
137} 407}
138 408
409/*
410 * Logging the inode modification timestamp on a synchronous write.
411 * inode
412 */
139STATIC uint 413STATIC uint
140xfs_calc_swrite_reservation(xfs_mount_t *mp) 414xfs_calc_swrite_reservation(
415 struct xfs_mount *mp)
141{ 416{
142 return XFS_CALC_SWRITE_LOG_RES(mp); 417 return mp->m_sb.sb_inodesize + 128;
143} 418}
144 419
420/*
421 * Logging the inode mode bits when writing a setuid/setgid file
422 * inode
423 */
145STATIC uint 424STATIC uint
146xfs_calc_writeid_reservation(xfs_mount_t *mp) 425xfs_calc_writeid_reservation(xfs_mount_t *mp)
147{ 426{
148 return XFS_CALC_WRITEID_LOG_RES(mp); 427 return mp->m_sb.sb_inodesize + 128;
149} 428}
150 429
430/*
431 * Converting the inode from non-attributed to attributed.
432 * the inode being converted: inode size
433 * agf block and superblock (for block allocation)
434 * the new block (directory sized)
435 * bmap blocks for the new directory block
436 * allocation btrees
437 */
151STATIC uint 438STATIC uint
152xfs_calc_addafork_reservation(xfs_mount_t *mp) 439xfs_calc_addafork_reservation(
440 struct xfs_mount *mp)
153{ 441{
154 return XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 442 return XFS_DQUOT_LOGRES(mp) +
443 mp->m_sb.sb_inodesize +
444 mp->m_sb.sb_sectsize * 2 +
445 mp->m_dirblksize +
446 XFS_FSB_TO_B(mp, XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) +
447 XFS_ALLOCFREE_LOG_RES(mp, 1) +
448 128 * (4 + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1 +
449 XFS_ALLOCFREE_LOG_COUNT(mp, 1));
155} 450}
156 451
452/*
453 * Removing the attribute fork of a file
454 * the inode being truncated: inode size
455 * the inode's bmap btree: max depth * block size
456 * And the bmap_finish transaction can free the blocks and bmap blocks:
457 * the agf for each of the ags: 4 * sector size
458 * the agfl for each of the ags: 4 * sector size
459 * the super block to reflect the freed blocks: sector size
460 * worst case split in allocation btrees per extent assuming 4 extents:
461 * 4 exts * 2 trees * (2 * max depth - 1) * block size
462 */
157STATIC uint 463STATIC uint
158xfs_calc_attrinval_reservation(xfs_mount_t *mp) 464xfs_calc_attrinval_reservation(
465 struct xfs_mount *mp)
159{ 466{
160 return XFS_CALC_ATTRINVAL_LOG_RES(mp); 467 return MAX((mp->m_sb.sb_inodesize +
468 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
469 128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))),
470 (4 * mp->m_sb.sb_sectsize +
471 4 * mp->m_sb.sb_sectsize +
472 mp->m_sb.sb_sectsize +
473 XFS_ALLOCFREE_LOG_RES(mp, 4) +
474 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))));
161} 475}
162 476
477/*
478 * Setting an attribute.
479 * the inode getting the attribute
480 * the superblock for allocations
481 * the agfs extents are allocated from
482 * the attribute btree * max depth
483 * the inode allocation btree
484 * Since attribute transaction space is dependent on the size of the attribute,
485 * the calculation is done partially at mount time and partially at runtime.
486 */
163STATIC uint 487STATIC uint
164xfs_calc_attrset_reservation(xfs_mount_t *mp) 488xfs_calc_attrset_reservation(
489 struct xfs_mount *mp)
165{ 490{
166 return XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 491 return XFS_DQUOT_LOGRES(mp) +
492 mp->m_sb.sb_inodesize +
493 mp->m_sb.sb_sectsize +
494 XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) +
495 128 * (2 + XFS_DA_NODE_MAXDEPTH);
167} 496}
168 497
498/*
499 * Removing an attribute.
500 * the inode: inode size
501 * the attribute btree could join: max depth * block size
502 * the inode bmap btree could join or split: max depth * block size
503 * And the bmap_finish transaction can free the attr blocks freed giving:
504 * the agf for the ag in which the blocks live: 2 * sector size
505 * the agfl for the ag in which the blocks live: 2 * sector size
506 * the superblock for the free block count: sector size
507 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
508 */
169STATIC uint 509STATIC uint
170xfs_calc_attrrm_reservation(xfs_mount_t *mp) 510xfs_calc_attrrm_reservation(
511 struct xfs_mount *mp)
171{ 512{
172 return XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 513 return XFS_DQUOT_LOGRES(mp) +
514 MAX((mp->m_sb.sb_inodesize +
515 XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) +
516 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
517 128 * (1 + XFS_DA_NODE_MAXDEPTH +
518 XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))),
519 (2 * mp->m_sb.sb_sectsize +
520 2 * mp->m_sb.sb_sectsize +
521 mp->m_sb.sb_sectsize +
522 XFS_ALLOCFREE_LOG_RES(mp, 2) +
523 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));
173} 524}
174 525
526/*
527 * Clearing a bad agino number in an agi hash bucket.
528 */
175STATIC uint 529STATIC uint
176xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp) 530xfs_calc_clear_agi_bucket_reservation(
531 struct xfs_mount *mp)
177{ 532{
178 return XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp); 533 return mp->m_sb.sb_sectsize + 128;
179} 534}
180 535
181/* 536/*
@@ -184,11 +539,10 @@ xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp)
184 */ 539 */
185void 540void
186xfs_trans_init( 541xfs_trans_init(
187 xfs_mount_t *mp) 542 struct xfs_mount *mp)
188{ 543{
189 xfs_trans_reservations_t *resp; 544 struct xfs_trans_reservations *resp = &mp->m_reservations;
190 545
191 resp = &(mp->m_reservations);
192 resp->tr_write = xfs_calc_write_reservation(mp); 546 resp->tr_write = xfs_calc_write_reservation(mp);
193 resp->tr_itruncate = xfs_calc_itruncate_reservation(mp); 547 resp->tr_itruncate = xfs_calc_itruncate_reservation(mp);
194 resp->tr_rename = xfs_calc_rename_reservation(mp); 548 resp->tr_rename = xfs_calc_rename_reservation(mp);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 8c69e7824f68..e639e8e9a2a9 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -300,24 +300,6 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
300 300
301 301
302/* 302/*
303 * Various log reservation values.
304 * These are based on the size of the file system block
305 * because that is what most transactions manipulate.
306 * Each adds in an additional 128 bytes per item logged to
307 * try to account for the overhead of the transaction mechanism.
308 *
309 * Note:
310 * Most of the reservations underestimate the number of allocation
311 * groups into which they could free extents in the xfs_bmap_finish()
312 * call. This is because the number in the worst case is quite high
313 * and quite unusual. In order to fix this we need to change
314 * xfs_bmap_finish() to free extents in only a single AG at a time.
315 * This will require changes to the EFI code as well, however, so that
316 * the EFI for the extents not freed is logged again in each transaction.
317 * See bug 261917.
318 */
319
320/*
321 * Per-extent log reservation for the allocation btree changes 303 * Per-extent log reservation for the allocation btree changes
322 * involved in freeing or allocating an extent. 304 * involved in freeing or allocating an extent.
323 * 2 trees * (2 blocks/level * max depth - 1) * block size 305 * 2 trees * (2 blocks/level * max depth - 1) * block size
@@ -341,429 +323,36 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
341 (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ 323 (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
342 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) 324 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
343 325
344/*
345 * In a write transaction we can allocate a maximum of 2
346 * extents. This gives:
347 * the inode getting the new extents: inode size
348 * the inode's bmap btree: max depth * block size
349 * the agfs of the ags from which the extents are allocated: 2 * sector
350 * the superblock free block counter: sector size
351 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
352 * And the bmap_finish transaction can free bmap blocks in a join:
353 * the agfs of the ags containing the blocks: 2 * sector size
354 * the agfls of the ags containing the blocks: 2 * sector size
355 * the super block free block counter: sector size
356 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
357 */
358#define XFS_CALC_WRITE_LOG_RES(mp) \
359 (MAX( \
360 ((mp)->m_sb.sb_inodesize + \
361 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \
362 (2 * (mp)->m_sb.sb_sectsize) + \
363 (mp)->m_sb.sb_sectsize + \
364 XFS_ALLOCFREE_LOG_RES(mp, 2) + \
365 (128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))),\
366 ((2 * (mp)->m_sb.sb_sectsize) + \
367 (2 * (mp)->m_sb.sb_sectsize) + \
368 (mp)->m_sb.sb_sectsize + \
369 XFS_ALLOCFREE_LOG_RES(mp, 2) + \
370 (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
371 326
372#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) 327#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write)
373
374/*
375 * In truncating a file we free up to two extents at once. We can modify:
376 * the inode being truncated: inode size
377 * the inode's bmap btree: (max depth + 1) * block size
378 * And the bmap_finish transaction can free the blocks and bmap blocks:
379 * the agf for each of the ags: 4 * sector size
380 * the agfl for each of the ags: 4 * sector size
381 * the super block to reflect the freed blocks: sector size
382 * worst case split in allocation btrees per extent assuming 4 extents:
383 * 4 exts * 2 trees * (2 * max depth - 1) * block size
384 * the inode btree: max depth * blocksize
385 * the allocation btrees: 2 trees * (max depth - 1) * block size
386 */
387#define XFS_CALC_ITRUNCATE_LOG_RES(mp) \
388 (MAX( \
389 ((mp)->m_sb.sb_inodesize + \
390 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + \
391 (128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \
392 ((4 * (mp)->m_sb.sb_sectsize) + \
393 (4 * (mp)->m_sb.sb_sectsize) + \
394 (mp)->m_sb.sb_sectsize + \
395 XFS_ALLOCFREE_LOG_RES(mp, 4) + \
396 (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \
397 (128 * 5) + \
398 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
399 (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
400 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
401
402#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) 328#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
403
404/*
405 * In renaming a files we can modify:
406 * the four inodes involved: 4 * inode size
407 * the two directory btrees: 2 * (max depth + v2) * dir block size
408 * the two directory bmap btrees: 2 * max depth * block size
409 * And the bmap_finish transaction can free dir and bmap blocks (two sets
410 * of bmap blocks) giving:
411 * the agf for the ags in which the blocks live: 3 * sector size
412 * the agfl for the ags in which the blocks live: 3 * sector size
413 * the superblock for the free block count: sector size
414 * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size
415 */
416#define XFS_CALC_RENAME_LOG_RES(mp) \
417 (MAX( \
418 ((4 * (mp)->m_sb.sb_inodesize) + \
419 (2 * XFS_DIROP_LOG_RES(mp)) + \
420 (128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp)))), \
421 ((3 * (mp)->m_sb.sb_sectsize) + \
422 (3 * (mp)->m_sb.sb_sectsize) + \
423 (mp)->m_sb.sb_sectsize + \
424 XFS_ALLOCFREE_LOG_RES(mp, 3) + \
425 (128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3))))))
426
427#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) 329#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename)
428
429/*
430 * For creating a link to an inode:
431 * the parent directory inode: inode size
432 * the linked inode: inode size
433 * the directory btree could split: (max depth + v2) * dir block size
434 * the directory bmap btree could join or split: (max depth + v2) * blocksize
435 * And the bmap_finish transaction can free some bmap blocks giving:
436 * the agf for the ag in which the blocks live: sector size
437 * the agfl for the ag in which the blocks live: sector size
438 * the superblock for the free block count: sector size
439 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
440 */
441#define XFS_CALC_LINK_LOG_RES(mp) \
442 (MAX( \
443 ((mp)->m_sb.sb_inodesize + \
444 (mp)->m_sb.sb_inodesize + \
445 XFS_DIROP_LOG_RES(mp) + \
446 (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \
447 ((mp)->m_sb.sb_sectsize + \
448 (mp)->m_sb.sb_sectsize + \
449 (mp)->m_sb.sb_sectsize + \
450 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
451 (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
452
453#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) 330#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link)
454
455/*
456 * For removing a directory entry we can modify:
457 * the parent directory inode: inode size
458 * the removed inode: inode size
459 * the directory btree could join: (max depth + v2) * dir block size
460 * the directory bmap btree could join or split: (max depth + v2) * blocksize
461 * And the bmap_finish transaction can free the dir and bmap blocks giving:
462 * the agf for the ag in which the blocks live: 2 * sector size
463 * the agfl for the ag in which the blocks live: 2 * sector size
464 * the superblock for the free block count: sector size
465 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
466 */
467#define XFS_CALC_REMOVE_LOG_RES(mp) \
468 (MAX( \
469 ((mp)->m_sb.sb_inodesize + \
470 (mp)->m_sb.sb_inodesize + \
471 XFS_DIROP_LOG_RES(mp) + \
472 (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \
473 ((2 * (mp)->m_sb.sb_sectsize) + \
474 (2 * (mp)->m_sb.sb_sectsize) + \
475 (mp)->m_sb.sb_sectsize + \
476 XFS_ALLOCFREE_LOG_RES(mp, 2) + \
477 (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
478
479#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) 331#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove)
480
481/*
482 * For symlink we can modify:
483 * the parent directory inode: inode size
484 * the new inode: inode size
485 * the inode btree entry: 1 block
486 * the directory btree: (max depth + v2) * dir block size
487 * the directory inode's bmap btree: (max depth + v2) * block size
488 * the blocks for the symlink: 1 kB
489 * Or in the first xact we allocate some inodes giving:
490 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
491 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
492 * the inode btree: max depth * blocksize
493 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
494 */
495#define XFS_CALC_SYMLINK_LOG_RES(mp) \
496 (MAX( \
497 ((mp)->m_sb.sb_inodesize + \
498 (mp)->m_sb.sb_inodesize + \
499 XFS_FSB_TO_B(mp, 1) + \
500 XFS_DIROP_LOG_RES(mp) + \
501 1024 + \
502 (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \
503 (2 * (mp)->m_sb.sb_sectsize + \
504 XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
505 XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \
506 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
507 (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
508 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
509
510#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) 332#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)
511
512/*
513 * For create we can modify:
514 * the parent directory inode: inode size
515 * the new inode: inode size
516 * the inode btree entry: block size
517 * the superblock for the nlink flag: sector size
518 * the directory btree: (max depth + v2) * dir block size
519 * the directory inode's bmap btree: (max depth + v2) * block size
520 * Or in the first xact we allocate some inodes giving:
521 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
522 * the superblock for the nlink flag: sector size
523 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
524 * the inode btree: max depth * blocksize
525 * the allocation btrees: 2 trees * (max depth - 1) * block size
526 */
527#define XFS_CALC_CREATE_LOG_RES(mp) \
528 (MAX( \
529 ((mp)->m_sb.sb_inodesize + \
530 (mp)->m_sb.sb_inodesize + \
531 (mp)->m_sb.sb_sectsize + \
532 XFS_FSB_TO_B(mp, 1) + \
533 XFS_DIROP_LOG_RES(mp) + \
534 (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \
535 (3 * (mp)->m_sb.sb_sectsize + \
536 XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
537 XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \
538 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
539 (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
540 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
541
542#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) 333#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)
543
544/*
545 * Making a new directory is the same as creating a new file.
546 */
547#define XFS_CALC_MKDIR_LOG_RES(mp) XFS_CALC_CREATE_LOG_RES(mp)
548
549#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) 334#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir)
550
551/*
552 * In freeing an inode we can modify:
553 * the inode being freed: inode size
554 * the super block free inode counter: sector size
555 * the agi hash list and counters: sector size
556 * the inode btree entry: block size
557 * the on disk inode before ours in the agi hash list: inode cluster size
558 * the inode btree: max depth * blocksize
559 * the allocation btrees: 2 trees * (max depth - 1) * block size
560 */
561#define XFS_CALC_IFREE_LOG_RES(mp) \
562 ((mp)->m_sb.sb_inodesize + \
563 (mp)->m_sb.sb_sectsize + \
564 (mp)->m_sb.sb_sectsize + \
565 XFS_FSB_TO_B((mp), 1) + \
566 MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \
567 (128 * 5) + \
568 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
569 (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
570 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
571
572
573#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) 335#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)
574
575/*
576 * When only changing the inode we log the inode and possibly the superblock
577 * We also add a bit of slop for the transaction stuff.
578 */
579#define XFS_CALC_ICHANGE_LOG_RES(mp) ((mp)->m_sb.sb_inodesize + \
580 (mp)->m_sb.sb_sectsize + 512)
581
582#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) 336#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange)
583
584/*
585 * Growing the data section of the filesystem.
586 * superblock
587 * agi and agf
588 * allocation btrees
589 */
590#define XFS_CALC_GROWDATA_LOG_RES(mp) \
591 ((mp)->m_sb.sb_sectsize * 3 + \
592 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
593 (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
594
595#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) 337#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata)
596
597/*
598 * Growing the rt section of the filesystem.
599 * In the first set of transactions (ALLOC) we allocate space to the
600 * bitmap or summary files.
601 * superblock: sector size
602 * agf of the ag from which the extent is allocated: sector size
603 * bmap btree for bitmap/summary inode: max depth * blocksize
604 * bitmap/summary inode: inode size
605 * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize
606 */
607#define XFS_CALC_GROWRTALLOC_LOG_RES(mp) \
608 (2 * (mp)->m_sb.sb_sectsize + \
609 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \
610 (mp)->m_sb.sb_inodesize + \
611 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
612 (128 * \
613 (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + \
614 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
615
616#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) 338#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc)
617
618/*
619 * Growing the rt section of the filesystem.
620 * In the second set of transactions (ZERO) we zero the new metadata blocks.
621 * one bitmap/summary block: blocksize
622 */
623#define XFS_CALC_GROWRTZERO_LOG_RES(mp) \
624 ((mp)->m_sb.sb_blocksize + 128)
625
626#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) 339#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero)
627
628/*
629 * Growing the rt section of the filesystem.
630 * In the third set of transactions (FREE) we update metadata without
631 * allocating any new blocks.
632 * superblock: sector size
633 * bitmap inode: inode size
634 * summary inode: inode size
635 * one bitmap block: blocksize
636 * summary blocks: new summary size
637 */
638#define XFS_CALC_GROWRTFREE_LOG_RES(mp) \
639 ((mp)->m_sb.sb_sectsize + \
640 2 * (mp)->m_sb.sb_inodesize + \
641 (mp)->m_sb.sb_blocksize + \
642 (mp)->m_rsumsize + \
643 (128 * 5))
644
645#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) 340#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree)
646
647/*
648 * Logging the inode modification timestamp on a synchronous write.
649 * inode
650 */
651#define XFS_CALC_SWRITE_LOG_RES(mp) \
652 ((mp)->m_sb.sb_inodesize + 128)
653
654#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 341#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
655
656/* 342/*
657 * Logging the inode timestamps on an fsync -- same as SWRITE 343 * Logging the inode timestamps on an fsync -- same as SWRITE
658 * as long as SWRITE logs the entire inode core 344 * as long as SWRITE logs the entire inode core
659 */ 345 */
660#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 346#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
661
662/*
663 * Logging the inode mode bits when writing a setuid/setgid file
664 * inode
665 */
666#define XFS_CALC_WRITEID_LOG_RES(mp) \
667 ((mp)->m_sb.sb_inodesize + 128)
668
669#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 347#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
670
671/*
672 * Converting the inode from non-attributed to attributed.
673 * the inode being converted: inode size
674 * agf block and superblock (for block allocation)
675 * the new block (directory sized)
676 * bmap blocks for the new directory block
677 * allocation btrees
678 */
679#define XFS_CALC_ADDAFORK_LOG_RES(mp) \
680 ((mp)->m_sb.sb_inodesize + \
681 (mp)->m_sb.sb_sectsize * 2 + \
682 (mp)->m_dirblksize + \
683 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \
684 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
685 (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
686 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
687
688#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) 348#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
689
690/*
691 * Removing the attribute fork of a file
692 * the inode being truncated: inode size
693 * the inode's bmap btree: max depth * block size
694 * And the bmap_finish transaction can free the blocks and bmap blocks:
695 * the agf for each of the ags: 4 * sector size
696 * the agfl for each of the ags: 4 * sector size
697 * the super block to reflect the freed blocks: sector size
698 * worst case split in allocation btrees per extent assuming 4 extents:
699 * 4 exts * 2 trees * (2 * max depth - 1) * block size
700 */
701#define XFS_CALC_ATTRINVAL_LOG_RES(mp) \
702 (MAX( \
703 ((mp)->m_sb.sb_inodesize + \
704 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \
705 (128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))), \
706 ((4 * (mp)->m_sb.sb_sectsize) + \
707 (4 * (mp)->m_sb.sb_sectsize) + \
708 (mp)->m_sb.sb_sectsize + \
709 XFS_ALLOCFREE_LOG_RES(mp, 4) + \
710 (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))))))
711
712#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) 349#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval)
713
714/*
715 * Setting an attribute.
716 * the inode getting the attribute
717 * the superblock for allocations
718 * the agfs extents are allocated from
719 * the attribute btree * max depth
720 * the inode allocation btree
721 * Since attribute transaction space is dependent on the size of the attribute,
722 * the calculation is done partially at mount time and partially at runtime.
723 */
724#define XFS_CALC_ATTRSET_LOG_RES(mp) \
725 ((mp)->m_sb.sb_inodesize + \
726 (mp)->m_sb.sb_sectsize + \
727 XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \
728 (128 * (2 + XFS_DA_NODE_MAXDEPTH)))
729
730#define XFS_ATTRSET_LOG_RES(mp, ext) \ 350#define XFS_ATTRSET_LOG_RES(mp, ext) \
731 ((mp)->m_reservations.tr_attrset + \ 351 ((mp)->m_reservations.tr_attrset + \
732 (ext * (mp)->m_sb.sb_sectsize) + \ 352 (ext * (mp)->m_sb.sb_sectsize) + \
733 (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ 353 (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \
734 (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) 354 (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))))
735
736/*
737 * Removing an attribute.
738 * the inode: inode size
739 * the attribute btree could join: max depth * block size
740 * the inode bmap btree could join or split: max depth * block size
741 * And the bmap_finish transaction can free the attr blocks freed giving:
742 * the agf for the ag in which the blocks live: 2 * sector size
743 * the agfl for the ag in which the blocks live: 2 * sector size
744 * the superblock for the free block count: sector size
745 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
746 */
747#define XFS_CALC_ATTRRM_LOG_RES(mp) \
748 (MAX( \
749 ((mp)->m_sb.sb_inodesize + \
750 XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \
751 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \
752 (128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \
753 ((2 * (mp)->m_sb.sb_sectsize) + \
754 (2 * (mp)->m_sb.sb_sectsize) + \
755 (mp)->m_sb.sb_sectsize + \
756 XFS_ALLOCFREE_LOG_RES(mp, 2) + \
757 (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
758
759#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) 355#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm)
760
761/*
762 * Clearing a bad agino number in an agi hash bucket.
763 */
764#define XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp) \
765 ((mp)->m_sb.sb_sectsize + 128)
766
767#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) 356#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi)
768 357
769 358
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 9d376be0ea38..a06bd62504fc 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -267,7 +267,7 @@ xfs_setattr(
267 if (code) { 267 if (code) {
268 ASSERT(tp == NULL); 268 ASSERT(tp == NULL);
269 lock_flags &= ~XFS_ILOCK_EXCL; 269 lock_flags &= ~XFS_ILOCK_EXCL;
270 ASSERT(lock_flags == XFS_IOLOCK_EXCL); 270 ASSERT(lock_flags == XFS_IOLOCK_EXCL || !need_iolock);
271 goto error_return; 271 goto error_return;
272 } 272 }
273 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); 273 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE);
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 04f91c2d3f7b..b5043a9890d8 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -80,7 +80,7 @@ extern void setup_per_cpu_areas(void);
80 80
81#ifndef PER_CPU_BASE_SECTION 81#ifndef PER_CPU_BASE_SECTION
82#ifdef CONFIG_SMP 82#ifdef CONFIG_SMP
83#define PER_CPU_BASE_SECTION ".data.percpu" 83#define PER_CPU_BASE_SECTION ".data..percpu"
84#else 84#else
85#define PER_CPU_BASE_SECTION ".data" 85#define PER_CPU_BASE_SECTION ".data"
86#endif 86#endif
@@ -92,15 +92,15 @@ extern void setup_per_cpu_areas(void);
92#define PER_CPU_SHARED_ALIGNED_SECTION "" 92#define PER_CPU_SHARED_ALIGNED_SECTION ""
93#define PER_CPU_ALIGNED_SECTION "" 93#define PER_CPU_ALIGNED_SECTION ""
94#else 94#else
95#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned" 95#define PER_CPU_SHARED_ALIGNED_SECTION "..shared_aligned"
96#define PER_CPU_ALIGNED_SECTION ".shared_aligned" 96#define PER_CPU_ALIGNED_SECTION "..shared_aligned"
97#endif 97#endif
98#define PER_CPU_FIRST_SECTION ".first" 98#define PER_CPU_FIRST_SECTION "..first"
99 99
100#else 100#else
101 101
102#define PER_CPU_SHARED_ALIGNED_SECTION "" 102#define PER_CPU_SHARED_ALIGNED_SECTION ""
103#define PER_CPU_ALIGNED_SECTION ".shared_aligned" 103#define PER_CPU_ALIGNED_SECTION "..shared_aligned"
104#define PER_CPU_FIRST_SECTION "" 104#define PER_CPU_FIRST_SECTION ""
105 105
106#endif 106#endif
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index ef779c6fc3d7..48c5299cbf26 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -175,25 +175,25 @@
175#define NOSAVE_DATA \ 175#define NOSAVE_DATA \
176 . = ALIGN(PAGE_SIZE); \ 176 . = ALIGN(PAGE_SIZE); \
177 VMLINUX_SYMBOL(__nosave_begin) = .; \ 177 VMLINUX_SYMBOL(__nosave_begin) = .; \
178 *(.data.nosave) \ 178 *(.data..nosave) \
179 . = ALIGN(PAGE_SIZE); \ 179 . = ALIGN(PAGE_SIZE); \
180 VMLINUX_SYMBOL(__nosave_end) = .; 180 VMLINUX_SYMBOL(__nosave_end) = .;
181 181
182#define PAGE_ALIGNED_DATA(page_align) \ 182#define PAGE_ALIGNED_DATA(page_align) \
183 . = ALIGN(page_align); \ 183 . = ALIGN(page_align); \
184 *(.data.page_aligned) 184 *(.data..page_aligned)
185 185
186#define READ_MOSTLY_DATA(align) \ 186#define READ_MOSTLY_DATA(align) \
187 . = ALIGN(align); \ 187 . = ALIGN(align); \
188 *(.data.read_mostly) 188 *(.data..read_mostly)
189 189
190#define CACHELINE_ALIGNED_DATA(align) \ 190#define CACHELINE_ALIGNED_DATA(align) \
191 . = ALIGN(align); \ 191 . = ALIGN(align); \
192 *(.data.cacheline_aligned) 192 *(.data..cacheline_aligned)
193 193
194#define INIT_TASK_DATA(align) \ 194#define INIT_TASK_DATA(align) \
195 . = ALIGN(align); \ 195 . = ALIGN(align); \
196 *(.data.init_task) 196 *(.data..init_task)
197 197
198/* 198/*
199 * Read only Data 199 * Read only Data
@@ -435,7 +435,7 @@
435 */ 435 */
436#define INIT_TASK_DATA_SECTION(align) \ 436#define INIT_TASK_DATA_SECTION(align) \
437 . = ALIGN(align); \ 437 . = ALIGN(align); \
438 .data.init_task : { \ 438 .data..init_task : { \
439 INIT_TASK_DATA(align) \ 439 INIT_TASK_DATA(align) \
440 } 440 }
441 441
@@ -499,7 +499,7 @@
499#define BSS(bss_align) \ 499#define BSS(bss_align) \
500 . = ALIGN(bss_align); \ 500 . = ALIGN(bss_align); \
501 .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \ 501 .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \
502 *(.bss.page_aligned) \ 502 *(.bss..page_aligned) \
503 *(.dynbss) \ 503 *(.dynbss) \
504 *(.bss) \ 504 *(.bss) \
505 *(COMMON) \ 505 *(COMMON) \
@@ -666,16 +666,16 @@
666 */ 666 */
667#define PERCPU_VADDR(vaddr, phdr) \ 667#define PERCPU_VADDR(vaddr, phdr) \
668 VMLINUX_SYMBOL(__per_cpu_load) = .; \ 668 VMLINUX_SYMBOL(__per_cpu_load) = .; \
669 .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \ 669 .data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
670 - LOAD_OFFSET) { \ 670 - LOAD_OFFSET) { \
671 VMLINUX_SYMBOL(__per_cpu_start) = .; \ 671 VMLINUX_SYMBOL(__per_cpu_start) = .; \
672 *(.data.percpu.first) \ 672 *(.data..percpu..first) \
673 *(.data.percpu.page_aligned) \ 673 *(.data..percpu..page_aligned) \
674 *(.data.percpu) \ 674 *(.data..percpu) \
675 *(.data.percpu.shared_aligned) \ 675 *(.data..percpu..shared_aligned) \
676 VMLINUX_SYMBOL(__per_cpu_end) = .; \ 676 VMLINUX_SYMBOL(__per_cpu_end) = .; \
677 } phdr \ 677 } phdr \
678 . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu); 678 . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu);
679 679
680/** 680/**
681 * PERCPU - define output section for percpu area, simple version 681 * PERCPU - define output section for percpu area, simple version
@@ -687,18 +687,18 @@
687 * 687 *
688 * This macro is equivalent to ALIGN(align); PERCPU_VADDR( , ) except 688 * This macro is equivalent to ALIGN(align); PERCPU_VADDR( , ) except
689 * that __per_cpu_load is defined as a relative symbol against 689 * that __per_cpu_load is defined as a relative symbol against
690 * .data.percpu which is required for relocatable x86_32 690 * .data..percpu which is required for relocatable x86_32
691 * configuration. 691 * configuration.
692 */ 692 */
693#define PERCPU(align) \ 693#define PERCPU(align) \
694 . = ALIGN(align); \ 694 . = ALIGN(align); \
695 .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \ 695 .data..percpu : AT(ADDR(.data..percpu) - LOAD_OFFSET) { \
696 VMLINUX_SYMBOL(__per_cpu_load) = .; \ 696 VMLINUX_SYMBOL(__per_cpu_load) = .; \
697 VMLINUX_SYMBOL(__per_cpu_start) = .; \ 697 VMLINUX_SYMBOL(__per_cpu_start) = .; \
698 *(.data.percpu.first) \ 698 *(.data..percpu..first) \
699 *(.data.percpu.page_aligned) \ 699 *(.data..percpu..page_aligned) \
700 *(.data.percpu) \ 700 *(.data..percpu) \
701 *(.data.percpu.shared_aligned) \ 701 *(.data..percpu..shared_aligned) \
702 VMLINUX_SYMBOL(__per_cpu_end) = .; \ 702 VMLINUX_SYMBOL(__per_cpu_end) = .; \
703 } 703 }
704 704
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index dc5873c21e45..1121f7799c6f 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -130,4 +130,7 @@ extern int drm_helper_resume_force_mode(struct drm_device *dev);
130extern void drm_kms_helper_poll_init(struct drm_device *dev); 130extern void drm_kms_helper_poll_init(struct drm_device *dev);
131extern void drm_kms_helper_poll_fini(struct drm_device *dev); 131extern void drm_kms_helper_poll_fini(struct drm_device *dev);
132extern void drm_helper_hpd_irq_event(struct drm_device *dev); 132extern void drm_helper_hpd_irq_event(struct drm_device *dev);
133
134extern void drm_kms_helper_poll_disable(struct drm_device *dev);
135extern void drm_kms_helper_poll_enable(struct drm_device *dev);
133#endif 136#endif
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index b64a8d7cdf6d..7f0028e1010b 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -275,6 +275,7 @@ typedef struct drm_i915_irq_wait {
275#define I915_PARAM_HAS_OVERLAY 7 275#define I915_PARAM_HAS_OVERLAY 7
276#define I915_PARAM_HAS_PAGEFLIPPING 8 276#define I915_PARAM_HAS_PAGEFLIPPING 8
277#define I915_PARAM_HAS_EXECBUF2 9 277#define I915_PARAM_HAS_EXECBUF2 9
278#define I915_PARAM_HAS_BSD 10
278 279
279typedef struct drm_i915_getparam { 280typedef struct drm_i915_getparam {
280 int param; 281 int param;
@@ -616,7 +617,9 @@ struct drm_i915_gem_execbuffer2 {
616 __u32 num_cliprects; 617 __u32 num_cliprects;
617 /** This is a struct drm_clip_rect *cliprects */ 618 /** This is a struct drm_clip_rect *cliprects */
618 __u64 cliprects_ptr; 619 __u64 cliprects_ptr;
619 __u64 flags; /* currently unused */ 620#define I915_EXEC_RENDER (1<<0)
621#define I915_EXEC_BSD (1<<1)
622 __u64 flags;
620 __u64 rsvd1; 623 __u64 rsvd1;
621 __u64 rsvd2; 624 __u64 rsvd2;
622}; 625};
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h
index a6a9f4af5ebd..fe917dee723a 100644
--- a/include/drm/nouveau_drm.h
+++ b/include/drm/nouveau_drm.h
@@ -79,6 +79,7 @@ struct drm_nouveau_gpuobj_free {
79#define NOUVEAU_GETPARAM_CHIPSET_ID 11 79#define NOUVEAU_GETPARAM_CHIPSET_ID 11
80#define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 80#define NOUVEAU_GETPARAM_VM_VRAM_BASE 12
81#define NOUVEAU_GETPARAM_GRAPH_UNITS 13 81#define NOUVEAU_GETPARAM_GRAPH_UNITS 13
82#define NOUVEAU_GETPARAM_PTIMER_TIME 14
82struct drm_nouveau_getparam { 83struct drm_nouveau_getparam {
83 uint64_t param; 84 uint64_t param;
84 uint64_t value; 85 uint64_t value;
diff --git a/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h
index c7645f480d12..4d0842391edc 100644
--- a/include/drm/vmwgfx_drm.h
+++ b/include/drm/vmwgfx_drm.h
@@ -50,6 +50,8 @@
50#define DRM_VMW_EXECBUF 12 50#define DRM_VMW_EXECBUF 12
51#define DRM_VMW_FIFO_DEBUG 13 51#define DRM_VMW_FIFO_DEBUG 13
52#define DRM_VMW_FENCE_WAIT 14 52#define DRM_VMW_FENCE_WAIT 14
53/* guarded by minor version >= 2 */
54#define DRM_VMW_UPDATE_LAYOUT 15
53 55
54 56
55/*************************************************************************/ 57/*************************************************************************/
@@ -585,4 +587,28 @@ struct drm_vmw_stream_arg {
585 * sure that the stream has been stopped. 587 * sure that the stream has been stopped.
586 */ 588 */
587 589
590/*************************************************************************/
591/**
592 * DRM_VMW_UPDATE_LAYOUT - Update layout
593 *
594 * Updates the prefered modes and connection status for connectors. The
595 * command conisits of one drm_vmw_update_layout_arg pointing out a array
596 * of num_outputs drm_vmw_rect's.
597 */
598
599/**
600 * struct drm_vmw_update_layout_arg
601 *
602 * @num_outputs: number of active
603 * @rects: pointer to array of drm_vmw_rect
604 *
605 * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl.
606 */
607
608struct drm_vmw_update_layout_arg {
609 uint32_t num_outputs;
610 uint32_t pad64;
611 uint64_t rects;
612};
613
588#endif 614#endif
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index e6e0cb5437e6..aee5f6ce166e 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -106,7 +106,7 @@ int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
106void bdi_unregister(struct backing_dev_info *bdi); 106void bdi_unregister(struct backing_dev_info *bdi);
107int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); 107int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
108void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, 108void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
109 long nr_pages, int sb_locked); 109 long nr_pages);
110int bdi_writeback_task(struct bdi_writeback *wb); 110int bdi_writeback_task(struct bdi_writeback *wb);
111int bdi_has_dirty_io(struct backing_dev_info *bdi); 111int bdi_has_dirty_io(struct backing_dev_info *bdi);
112void bdi_arm_supers_timer(void); 112void bdi_arm_supers_timer(void);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 8b7f5e0914ad..09a840264d6f 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1211,14 +1211,23 @@ struct work_struct;
1211int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); 1211int kblockd_schedule_work(struct request_queue *q, struct work_struct *work);
1212 1212
1213#ifdef CONFIG_BLK_CGROUP 1213#ifdef CONFIG_BLK_CGROUP
1214/*
1215 * This should not be using sched_clock(). A real patch is in progress
1216 * to fix this up, until that is in place we need to disable preemption
1217 * around sched_clock() in this function and set_io_start_time_ns().
1218 */
1214static inline void set_start_time_ns(struct request *req) 1219static inline void set_start_time_ns(struct request *req)
1215{ 1220{
1221 preempt_disable();
1216 req->start_time_ns = sched_clock(); 1222 req->start_time_ns = sched_clock();
1223 preempt_enable();
1217} 1224}
1218 1225
1219static inline void set_io_start_time_ns(struct request *req) 1226static inline void set_io_start_time_ns(struct request *req)
1220{ 1227{
1228 preempt_disable();
1221 req->io_start_time_ns = sched_clock(); 1229 req->io_start_time_ns = sched_clock();
1230 preempt_enable();
1222} 1231}
1223 1232
1224static inline uint64_t rq_start_time_ns(struct request *req) 1233static inline uint64_t rq_start_time_ns(struct request *req)
diff --git a/include/linux/cache.h b/include/linux/cache.h
index 97e24881c4c6..4c570653ab84 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -31,7 +31,7 @@
31#ifndef __cacheline_aligned 31#ifndef __cacheline_aligned
32#define __cacheline_aligned \ 32#define __cacheline_aligned \
33 __attribute__((__aligned__(SMP_CACHE_BYTES), \ 33 __attribute__((__aligned__(SMP_CACHE_BYTES), \
34 __section__(".data.cacheline_aligned"))) 34 __section__(".data..cacheline_aligned")))
35#endif /* __cacheline_aligned */ 35#endif /* __cacheline_aligned */
36 36
37#ifndef __cacheline_aligned_in_smp 37#ifndef __cacheline_aligned_in_smp
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 68530521ad00..30da4ae48972 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -53,7 +53,7 @@
53 53
54 54
55extern const char *drbd_buildtag(void); 55extern const char *drbd_buildtag(void);
56#define REL_VERSION "8.3.8rc1" 56#define REL_VERSION "8.3.8rc2"
57#define API_VERSION 88 57#define API_VERSION 88
58#define PRO_VERSION_MIN 86 58#define PRO_VERSION_MIN 86
59#define PRO_VERSION_MAX 94 59#define PRO_VERSION_MAX 94
diff --git a/include/linux/edac_mce.h b/include/linux/edac_mce.h
new file mode 100644
index 000000000000..f974fc035363
--- /dev/null
+++ b/include/linux/edac_mce.h
@@ -0,0 +1,31 @@
1/* Provides edac interface to mcelog events
2 *
3 * This file may be distributed under the terms of the
4 * GNU General Public License version 2.
5 *
6 * Copyright (c) 2009 by:
7 * Mauro Carvalho Chehab <mchehab@redhat.com>
8 *
9 * Red Hat Inc. http://www.redhat.com
10 */
11
12#if defined(CONFIG_EDAC_MCE) || \
13 (defined(CONFIG_EDAC_MCE_MODULE) && defined(MODULE))
14
15#include <asm/mce.h>
16#include <linux/list.h>
17
18struct edac_mce {
19 struct list_head list;
20
21 void *priv;
22 int (*check_error)(void *priv, struct mce *mce);
23};
24
25int edac_mce_register(struct edac_mce *edac_mce);
26void edac_mce_unregister(struct edac_mce *edac_mce);
27int edac_mce_parse(struct mce *mce);
28
29#else
30#define edac_mce_parse(mce) (0)
31#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3428393942a6..471e1ff5079a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2388,7 +2388,7 @@ extern const struct file_operations simple_dir_operations;
2388extern const struct inode_operations simple_dir_inode_operations; 2388extern const struct inode_operations simple_dir_inode_operations;
2389struct tree_descr { char *name; const struct file_operations *ops; int mode; }; 2389struct tree_descr { char *name; const struct file_operations *ops; int mode; };
2390struct dentry *d_alloc_name(struct dentry *, const char *); 2390struct dentry *d_alloc_name(struct dentry *, const char *);
2391extern int simple_fill_super(struct super_block *, int, struct tree_descr *); 2391extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);
2392extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count); 2392extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
2393extern void simple_release_fs(struct vfsmount **mount, int *count); 2393extern void simple_release_fs(struct vfsmount **mount, int *count);
2394 2394
diff --git a/include/linux/init.h b/include/linux/init.h
index ab1d31f9352b..de994304e0bb 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -301,7 +301,7 @@ void __init parse_early_options(char *cmdline);
301#endif 301#endif
302 302
303/* Data marked not to be saved by software suspend */ 303/* Data marked not to be saved by software suspend */
304#define __nosavedata __section(.data.nosave) 304#define __nosavedata __section(.data..nosave)
305 305
306/* This means "can be init if no module support, otherwise module load 306/* This means "can be init if no module support, otherwise module load
307 may call it." */ 307 may call it." */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 2beaa13492be..1f43fa56f600 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -183,7 +183,7 @@ extern struct cred init_cred;
183} 183}
184 184
185/* Attach to the init_task data structure for proper alignment */ 185/* Attach to the init_task data structure for proper alignment */
186#define __init_task_data __attribute__((__section__(".data.init_task"))) 186#define __init_task_data __attribute__((__section__(".data..init_task")))
187 187
188 188
189#endif 189#endif
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index a0bb301afac0..64d529133031 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -7,7 +7,6 @@
7struct cfq_queue; 7struct cfq_queue;
8struct cfq_io_context { 8struct cfq_io_context {
9 void *key; 9 void *key;
10 unsigned long dead_key;
11 10
12 struct cfq_queue *cfqq[2]; 11 struct cfq_queue *cfqq[2];
13 12
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 3bad2701bfa6..b85f3ff34d7d 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1023,6 +1023,7 @@ extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
1023extern int ata_std_bios_param(struct scsi_device *sdev, 1023extern int ata_std_bios_param(struct scsi_device *sdev,
1024 struct block_device *bdev, 1024 struct block_device *bdev,
1025 sector_t capacity, int geom[]); 1025 sector_t capacity, int geom[]);
1026extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev);
1026extern int ata_scsi_slave_config(struct scsi_device *sdev); 1027extern int ata_scsi_slave_config(struct scsi_device *sdev);
1027extern void ata_scsi_slave_destroy(struct scsi_device *sdev); 1028extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
1028extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, 1029extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
@@ -1174,6 +1175,7 @@ extern struct device_attribute *ata_common_sdev_attrs[];
1174 .slave_configure = ata_scsi_slave_config, \ 1175 .slave_configure = ata_scsi_slave_config, \
1175 .slave_destroy = ata_scsi_slave_destroy, \ 1176 .slave_destroy = ata_scsi_slave_destroy, \
1176 .bios_param = ata_std_bios_param, \ 1177 .bios_param = ata_std_bios_param, \
1178 .unlock_native_capacity = ata_scsi_unlock_native_capacity, \
1177 .sdev_attrs = ata_common_sdev_attrs 1179 .sdev_attrs = ata_common_sdev_attrs
1178 1180
1179#define ATA_NCQ_SHT(drv_name) \ 1181#define ATA_NCQ_SHT(drv_name) \
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index 5126cceb6ae9..7135ebc8428c 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -18,8 +18,8 @@
18# define asmregparm 18# define asmregparm
19#endif 19#endif
20 20
21#define __page_aligned_data __section(.data.page_aligned) __aligned(PAGE_SIZE) 21#define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE)
22#define __page_aligned_bss __section(.bss.page_aligned) __aligned(PAGE_SIZE) 22#define __page_aligned_bss __section(.bss..page_aligned) __aligned(PAGE_SIZE)
23 23
24/* 24/*
25 * For assembly routines. 25 * For assembly routines.
@@ -27,8 +27,8 @@
27 * Note when using these that you must specify the appropriate 27 * Note when using these that you must specify the appropriate
28 * alignment directives yourself 28 * alignment directives yourself
29 */ 29 */
30#define __PAGE_ALIGNED_DATA .section ".data.page_aligned", "aw" 30#define __PAGE_ALIGNED_DATA .section ".data..page_aligned", "aw"
31#define __PAGE_ALIGNED_BSS .section ".bss.page_aligned", "aw" 31#define __PAGE_ALIGNED_BSS .section ".bss..page_aligned", "aw"
32 32
33/* 33/*
34 * This is used by architectures to keep arguments on the stack 34 * This is used by architectures to keep arguments on the stack
diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h
index aafe832f18aa..d4a2ebbdab4b 100644
--- a/include/linux/mmc/sh_mmcif.h
+++ b/include/linux/mmc/sh_mmcif.h
@@ -14,6 +14,9 @@
14#ifndef __SH_MMCIF_H__ 14#ifndef __SH_MMCIF_H__
15#define __SH_MMCIF_H__ 15#define __SH_MMCIF_H__
16 16
17#include <linux/platform_device.h>
18#include <linux/io.h>
19
17/* 20/*
18 * MMCIF : CE_CLK_CTRL [19:16] 21 * MMCIF : CE_CLK_CTRL [19:16]
19 * 1000 : Peripheral clock / 512 22 * 1000 : Peripheral clock / 512
@@ -36,4 +39,162 @@ struct sh_mmcif_plat_data {
36 u32 ocr; 39 u32 ocr;
37}; 40};
38 41
42#define MMCIF_CE_CMD_SET 0x00000000
43#define MMCIF_CE_ARG 0x00000008
44#define MMCIF_CE_ARG_CMD12 0x0000000C
45#define MMCIF_CE_CMD_CTRL 0x00000010
46#define MMCIF_CE_BLOCK_SET 0x00000014
47#define MMCIF_CE_CLK_CTRL 0x00000018
48#define MMCIF_CE_BUF_ACC 0x0000001C
49#define MMCIF_CE_RESP3 0x00000020
50#define MMCIF_CE_RESP2 0x00000024
51#define MMCIF_CE_RESP1 0x00000028
52#define MMCIF_CE_RESP0 0x0000002C
53#define MMCIF_CE_RESP_CMD12 0x00000030
54#define MMCIF_CE_DATA 0x00000034
55#define MMCIF_CE_INT 0x00000040
56#define MMCIF_CE_INT_MASK 0x00000044
57#define MMCIF_CE_HOST_STS1 0x00000048
58#define MMCIF_CE_HOST_STS2 0x0000004C
59#define MMCIF_CE_VERSION 0x0000007C
60
61extern inline u32 sh_mmcif_readl(void __iomem *addr, int reg)
62{
63 return readl(addr + reg);
64}
65
66extern inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val)
67{
68 writel(val, addr + reg);
69}
70
71#define SH_MMCIF_BBS 512 /* boot block size */
72
73extern inline void sh_mmcif_boot_cmd_send(void __iomem *base,
74 unsigned long cmd, unsigned long arg)
75{
76 sh_mmcif_writel(base, MMCIF_CE_INT, 0);
77 sh_mmcif_writel(base, MMCIF_CE_ARG, arg);
78 sh_mmcif_writel(base, MMCIF_CE_CMD_SET, cmd);
79}
80
81extern inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask)
82{
83 unsigned long tmp;
84 int cnt;
85
86 for (cnt = 0; cnt < 1000000; cnt++) {
87 tmp = sh_mmcif_readl(base, MMCIF_CE_INT);
88 if (tmp & mask) {
89 sh_mmcif_writel(base, MMCIF_CE_INT, tmp & ~mask);
90 return 0;
91 }
92 }
93
94 return -1;
95}
96
97extern inline int sh_mmcif_boot_cmd(void __iomem *base,
98 unsigned long cmd, unsigned long arg)
99{
100 sh_mmcif_boot_cmd_send(base, cmd, arg);
101 return sh_mmcif_boot_cmd_poll(base, 0x00010000);
102}
103
104extern inline int sh_mmcif_boot_do_read_single(void __iomem *base,
105 unsigned int block_nr,
106 unsigned long *buf)
107{
108 int k;
109
110 /* CMD13 - Status */
111 sh_mmcif_boot_cmd(base, 0x0d400000, 0x00010000);
112
113 if (sh_mmcif_readl(base, MMCIF_CE_RESP0) != 0x0900)
114 return -1;
115
116 /* CMD17 - Read */
117 sh_mmcif_boot_cmd(base, 0x11480000, block_nr * SH_MMCIF_BBS);
118 if (sh_mmcif_boot_cmd_poll(base, 0x00100000) < 0)
119 return -1;
120
121 for (k = 0; k < (SH_MMCIF_BBS / 4); k++)
122 buf[k] = sh_mmcif_readl(base, MMCIF_CE_DATA);
123
124 return 0;
125}
126
127extern inline int sh_mmcif_boot_do_read(void __iomem *base,
128 unsigned long first_block,
129 unsigned long nr_blocks,
130 void *buf)
131{
132 unsigned long k;
133 int ret = 0;
134
135 /* CMD16 - Set the block size */
136 sh_mmcif_boot_cmd(base, 0x10400000, SH_MMCIF_BBS);
137
138 for (k = 0; !ret && k < nr_blocks; k++)
139 ret = sh_mmcif_boot_do_read_single(base, first_block + k,
140 buf + (k * SH_MMCIF_BBS));
141
142 return ret;
143}
144
145extern inline void sh_mmcif_boot_init(void __iomem *base)
146{
147 unsigned long tmp;
148
149 /* reset */
150 tmp = sh_mmcif_readl(base, MMCIF_CE_VERSION);
151 sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp | 0x80000000);
152 sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp & ~0x80000000);
153
154 /* byte swap */
155 sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, 0x00010000);
156
157 /* Set block size in MMCIF hardware */
158 sh_mmcif_writel(base, MMCIF_CE_BLOCK_SET, SH_MMCIF_BBS);
159
160 /* Enable the clock, set it to Bus clock/256 (about 325Khz)*/
161 sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01072fff);
162
163 /* CMD0 */
164 sh_mmcif_boot_cmd(base, 0x00000040, 0);
165
166 /* CMD1 - Get OCR */
167 do {
168 sh_mmcif_boot_cmd(base, 0x01405040, 0x40300000); /* CMD1 */
169 } while ((sh_mmcif_readl(base, MMCIF_CE_RESP0) & 0x80000000)
170 != 0x80000000);
171
172 /* CMD2 - Get CID */
173 sh_mmcif_boot_cmd(base, 0x02806040, 0);
174
175 /* CMD3 - Set card relative address */
176 sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000);
177}
178
179extern inline void sh_mmcif_boot_slurp(void __iomem *base,
180 unsigned char *buf,
181 unsigned long no_bytes)
182{
183 unsigned long tmp;
184
185 /* In data transfer mode: Set clock to Bus clock/4 (about 20Mhz) */
186 sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01012fff);
187
188 /* CMD9 - Get CSD */
189 sh_mmcif_boot_cmd(base, 0x09806000, 0x00010000);
190
191 /* CMD7 - Select the card */
192 sh_mmcif_boot_cmd(base, 0x07400000, 0x00010000);
193
194 tmp = no_bytes / SH_MMCIF_BBS;
195 tmp += (no_bytes % SH_MMCIF_BBS) ? 1 : 0;
196
197 sh_mmcif_boot_do_read(base, 512, tmp, buf);
198}
199
39#endif /* __SH_MMCIF_H__ */ 200#endif /* __SH_MMCIF_H__ */
diff --git a/include/linux/module.h b/include/linux/module.h
index 6914fcad4673..8a6b9fdc7ffa 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -181,6 +181,13 @@ void *__symbol_get(const char *symbol);
181void *__symbol_get_gpl(const char *symbol); 181void *__symbol_get_gpl(const char *symbol);
182#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) 182#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
183 183
184/* modules using other modules: kdb wants to see this. */
185struct module_use {
186 struct list_head source_list;
187 struct list_head target_list;
188 struct module *source, *target;
189};
190
184#ifndef __GENKSYMS__ 191#ifndef __GENKSYMS__
185#ifdef CONFIG_MODVERSIONS 192#ifdef CONFIG_MODVERSIONS
186/* Mark the CRC weak since genksyms apparently decides not to 193/* Mark the CRC weak since genksyms apparently decides not to
@@ -359,7 +366,9 @@ struct module
359 366
360#ifdef CONFIG_MODULE_UNLOAD 367#ifdef CONFIG_MODULE_UNLOAD
361 /* What modules depend on me? */ 368 /* What modules depend on me? */
362 struct list_head modules_which_use_me; 369 struct list_head source_list;
370 /* What modules do I depend on? */
371 struct list_head target_list;
363 372
364 /* Who is waiting for us to be unloaded */ 373 /* Who is waiting for us to be unloaded */
365 struct task_struct *waiter; 374 struct task_struct *waiter;
@@ -663,43 +672,10 @@ static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter)
663 672
664#endif /* CONFIG_MODULES */ 673#endif /* CONFIG_MODULES */
665 674
666struct device_driver;
667#ifdef CONFIG_SYSFS 675#ifdef CONFIG_SYSFS
668struct module;
669
670extern struct kset *module_kset; 676extern struct kset *module_kset;
671extern struct kobj_type module_ktype; 677extern struct kobj_type module_ktype;
672extern int module_sysfs_initialized; 678extern int module_sysfs_initialized;
673
674int mod_sysfs_init(struct module *mod);
675int mod_sysfs_setup(struct module *mod,
676 struct kernel_param *kparam,
677 unsigned int num_params);
678int module_add_modinfo_attrs(struct module *mod);
679void module_remove_modinfo_attrs(struct module *mod);
680
681#else /* !CONFIG_SYSFS */
682
683static inline int mod_sysfs_init(struct module *mod)
684{
685 return 0;
686}
687
688static inline int mod_sysfs_setup(struct module *mod,
689 struct kernel_param *kparam,
690 unsigned int num_params)
691{
692 return 0;
693}
694
695static inline int module_add_modinfo_attrs(struct module *mod)
696{
697 return 0;
698}
699
700static inline void module_remove_modinfo_attrs(struct module *mod)
701{ }
702
703#endif /* CONFIG_SYSFS */ 679#endif /* CONFIG_SYSFS */
704 680
705#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) 681#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index c00cc0c4d0b7..24e5d01d27d0 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -397,7 +397,7 @@ struct xt_table_info {
397 * @stacksize jumps (number of user chains) can possibly be made. 397 * @stacksize jumps (number of user chains) can possibly be made.
398 */ 398 */
399 unsigned int stacksize; 399 unsigned int stacksize;
400 unsigned int *stackptr; 400 unsigned int __percpu *stackptr;
401 void ***jumpstack; 401 void ***jumpstack;
402 /* ipt_entry tables: one per CPU */ 402 /* ipt_entry tables: one per CPU */
403 /* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */ 403 /* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6a471aba3b07..7cb00845f150 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -632,6 +632,7 @@ void pci_fixup_cardbus(struct pci_bus *);
632 632
633/* Generic PCI functions used internally */ 633/* Generic PCI functions used internally */
634 634
635void pcibios_scan_specific_bus(int busn);
635extern struct pci_bus *pci_find_bus(int domain, int busnr); 636extern struct pci_bus *pci_find_bus(int domain, int busnr);
636void pci_bus_add_devices(const struct pci_bus *bus); 637void pci_bus_add_devices(const struct pci_bus *bus);
637struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, 638struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ae66851870be..f149dd10908b 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2532,11 +2532,63 @@
2532#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930 2532#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
2533#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916 2533#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
2534#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918 2534#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
2535#define PCI_DEVICE_ID_INTEL_I7_MCR 0x2c18
2536#define PCI_DEVICE_ID_INTEL_I7_MC_TAD 0x2c19
2537#define PCI_DEVICE_ID_INTEL_I7_MC_RAS 0x2c1a
2538#define PCI_DEVICE_ID_INTEL_I7_MC_TEST 0x2c1c
2539#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL 0x2c20
2540#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR 0x2c21
2541#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK 0x2c22
2542#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC 0x2c23
2543#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL 0x2c28
2544#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR 0x2c29
2545#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK 0x2c2a
2546#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC 0x2c2b
2547#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL 0x2c30
2548#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR 0x2c31
2549#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK 0x2c32
2550#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c33
2551#define PCI_DEVICE_ID_INTEL_I7_NONCORE 0x2c41
2552#define PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT 0x2c40
2553#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE 0x2c50
2554#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT 0x2c51
2555#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2 0x2c70
2556#define PCI_DEVICE_ID_INTEL_LYNNFIELD_SAD 0x2c81
2557#define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0 0x2c90
2558#define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_PHY0 0x2c91
2559#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR 0x2c98
2560#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD 0x2c99
2561#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST 0x2c9C
2562#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL 0x2ca0
2563#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR 0x2ca1
2564#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK 0x2ca2
2565#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC 0x2ca3
2566#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL 0x2ca8
2567#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR 0x2ca9
2568#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK 0x2caa
2569#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC 0x2cab
2570#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2 0x2d98
2571#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2 0x2d99
2572#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2 0x2d9a
2573#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2 0x2d9c
2574#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2 0x2da0
2575#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2 0x2da1
2576#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2 0x2da2
2577#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2 0x2da3
2578#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2 0x2da8
2579#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2 0x2da9
2580#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2 0x2daa
2581#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2 0x2dab
2582#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2 0x2db0
2583#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2 0x2db1
2584#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2 0x2db2
2585#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2 0x2db3
2535#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 2586#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
2536#define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 2587#define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429
2537#define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a 2588#define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a
2538#define PCI_DEVICE_ID_INTEL_IOAT_TBG6 0x342b 2589#define PCI_DEVICE_ID_INTEL_IOAT_TBG6 0x342b
2539#define PCI_DEVICE_ID_INTEL_IOAT_TBG7 0x342c 2590#define PCI_DEVICE_ID_INTEL_IOAT_TBG7 0x342c
2591#define PCI_DEVICE_ID_INTEL_X58_HUB_MGMT 0x342e
2540#define PCI_DEVICE_ID_INTEL_IOAT_TBG0 0x3430 2592#define PCI_DEVICE_ID_INTEL_IOAT_TBG0 0x3430
2541#define PCI_DEVICE_ID_INTEL_IOAT_TBG1 0x3431 2593#define PCI_DEVICE_ID_INTEL_IOAT_TBG1 0x3431
2542#define PCI_DEVICE_ID_INTEL_IOAT_TBG2 0x3432 2594#define PCI_DEVICE_ID_INTEL_IOAT_TBG2 0x3432
diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h
index 68567c0b3a5d..ce2dc655cd1d 100644
--- a/include/linux/percpu-defs.h
+++ b/include/linux/percpu-defs.h
@@ -131,11 +131,11 @@
131 * Declaration/definition used for per-CPU variables that must be page aligned. 131 * Declaration/definition used for per-CPU variables that must be page aligned.
132 */ 132 */
133#define DECLARE_PER_CPU_PAGE_ALIGNED(type, name) \ 133#define DECLARE_PER_CPU_PAGE_ALIGNED(type, name) \
134 DECLARE_PER_CPU_SECTION(type, name, ".page_aligned") \ 134 DECLARE_PER_CPU_SECTION(type, name, "..page_aligned") \
135 __aligned(PAGE_SIZE) 135 __aligned(PAGE_SIZE)
136 136
137#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ 137#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \
138 DEFINE_PER_CPU_SECTION(type, name, ".page_aligned") \ 138 DEFINE_PER_CPU_SECTION(type, name, "..page_aligned") \
139 __aligned(PAGE_SIZE) 139 __aligned(PAGE_SIZE)
140 140
141/* 141/*
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index fb6c91eac7e3..5d0266d94985 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -585,6 +585,7 @@ enum perf_event_active_state {
585struct file; 585struct file;
586 586
587struct perf_mmap_data { 587struct perf_mmap_data {
588 atomic_t refcount;
588 struct rcu_head rcu_head; 589 struct rcu_head rcu_head;
589#ifdef CONFIG_PERF_USE_VMALLOC 590#ifdef CONFIG_PERF_USE_VMALLOC
590 struct work_struct work; 591 struct work_struct work;
@@ -592,7 +593,6 @@ struct perf_mmap_data {
592#endif 593#endif
593 int nr_pages; /* nr of data pages */ 594 int nr_pages; /* nr of data pages */
594 int writable; /* are we writable */ 595 int writable; /* are we writable */
595 int nr_locked; /* nr pages mlocked */
596 596
597 atomic_t poll; /* POLL_ for wakeups */ 597 atomic_t poll; /* POLL_ for wakeups */
598 598
@@ -631,6 +631,9 @@ struct swevent_hlist {
631 struct rcu_head rcu_head; 631 struct rcu_head rcu_head;
632}; 632};
633 633
634#define PERF_ATTACH_CONTEXT 0x01
635#define PERF_ATTACH_GROUP 0x02
636
634/** 637/**
635 * struct perf_event - performance event kernel representation: 638 * struct perf_event - performance event kernel representation:
636 */ 639 */
@@ -643,10 +646,10 @@ struct perf_event {
643 int nr_siblings; 646 int nr_siblings;
644 int group_flags; 647 int group_flags;
645 struct perf_event *group_leader; 648 struct perf_event *group_leader;
646 struct perf_event *output;
647 const struct pmu *pmu; 649 const struct pmu *pmu;
648 650
649 enum perf_event_active_state state; 651 enum perf_event_active_state state;
652 unsigned int attach_state;
650 atomic64_t count; 653 atomic64_t count;
651 654
652 /* 655 /*
@@ -704,6 +707,8 @@ struct perf_event {
704 /* mmap bits */ 707 /* mmap bits */
705 struct mutex mmap_mutex; 708 struct mutex mmap_mutex;
706 atomic_t mmap_count; 709 atomic_t mmap_count;
710 int mmap_locked;
711 struct user_struct *mmap_user;
707 struct perf_mmap_data *data; 712 struct perf_mmap_data *data;
708 713
709 /* poll related */ 714 /* poll related */
diff --git a/include/linux/personality.h b/include/linux/personality.h
index 126120819a0d..eec3bae164d4 100644
--- a/include/linux/personality.h
+++ b/include/linux/personality.h
@@ -12,7 +12,7 @@ struct pt_regs;
12 12
13extern int register_exec_domain(struct exec_domain *); 13extern int register_exec_domain(struct exec_domain *);
14extern int unregister_exec_domain(struct exec_domain *); 14extern int unregister_exec_domain(struct exec_domain *);
15extern int __set_personality(unsigned long); 15extern int __set_personality(unsigned int);
16 16
17#endif /* __KERNEL__ */ 17#endif /* __KERNEL__ */
18 18
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 16de3933c45e..445796945ac9 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -139,7 +139,9 @@ void pipe_lock(struct pipe_inode_info *);
139void pipe_unlock(struct pipe_inode_info *); 139void pipe_unlock(struct pipe_inode_info *);
140void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *); 140void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *);
141 141
142extern unsigned int pipe_max_pages; 142extern unsigned int pipe_max_size, pipe_min_size;
143int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *);
144
143 145
144/* Drop the inode semaphore and wait for a pipe event, atomically */ 146/* Drop the inode semaphore and wait for a pipe event, atomically */
145void pipe_wait(struct pipe_inode_info *pipe); 147void pipe_wait(struct pipe_inode_info *pipe);
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index f5364a1de68b..baed2122c5a6 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -2,9 +2,7 @@
2#define __LINUX_SERIAL_SCI_H 2#define __LINUX_SERIAL_SCI_H
3 3
4#include <linux/serial_core.h> 4#include <linux/serial_core.h>
5#ifdef CONFIG_SERIAL_SH_SCI_DMA 5#include <linux/sh_dma.h>
6#include <asm/dmaengine.h>
7#endif
8 6
9/* 7/*
10 * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) 8 * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7cdfb4d52847..bf243fc54959 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -501,7 +501,7 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
501 return __alloc_skb(size, priority, 1, -1); 501 return __alloc_skb(size, priority, 1, -1);
502} 502}
503 503
504extern int skb_recycle_check(struct sk_buff *skb, int skb_size); 504extern bool skb_recycle_check(struct sk_buff *skb, int skb_size);
505 505
506extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src); 506extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
507extern struct sk_buff *skb_clone(struct sk_buff *skb, 507extern struct sk_buff *skb_clone(struct sk_buff *skb,
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 89fac6a3f78b..f8854655860e 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -60,7 +60,7 @@
60/* 60/*
61 * Must define these before including other files, inline functions need them 61 * Must define these before including other files, inline functions need them
62 */ 62 */
63#define LOCK_SECTION_NAME ".text.lock."KBUILD_BASENAME 63#define LOCK_SECTION_NAME ".text..lock."KBUILD_BASENAME
64 64
65#define LOCK_SECTION_START(extra) \ 65#define LOCK_SECTION_START(extra) \
66 ".subsection 1\n\t" \ 66 ".subsection 1\n\t" \
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a1a86a53bc73..7f614ce274a9 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -289,7 +289,7 @@ asmlinkage long sys_capget(cap_user_header_t header,
289 cap_user_data_t dataptr); 289 cap_user_data_t dataptr);
290asmlinkage long sys_capset(cap_user_header_t header, 290asmlinkage long sys_capset(cap_user_header_t header,
291 const cap_user_data_t data); 291 const cap_user_data_t data);
292asmlinkage long sys_personality(u_long personality); 292asmlinkage long sys_personality(unsigned int personality);
293 293
294asmlinkage long sys_sigpending(old_sigset_t __user *set); 294asmlinkage long sys_sigpending(old_sigset_t __user *set);
295asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set, 295asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set,
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h
index 92f1d99f0f17..383b94ba8c20 100644
--- a/include/linux/usb/audio-v2.h
+++ b/include/linux/usb/audio-v2.h
@@ -18,6 +18,16 @@
18/* v1.0 and v2.0 of this standard have many things in common. For the rest 18/* v1.0 and v2.0 of this standard have many things in common. For the rest
19 * of the definitions, please refer to audio.h */ 19 * of the definitions, please refer to audio.h */
20 20
21static inline bool uac2_control_is_readable(u32 bmControls, u8 control)
22{
23 return (bmControls >> (control * 2)) & 0x1;
24}
25
26static inline bool uac2_control_is_writeable(u32 bmControls, u8 control)
27{
28 return (bmControls >> (control * 2)) & 0x2;
29}
30
21/* 4.7.2.1 Clock Source Descriptor */ 31/* 4.7.2.1 Clock Source Descriptor */
22 32
23struct uac_clock_source_descriptor { 33struct uac_clock_source_descriptor {
@@ -31,6 +41,13 @@ struct uac_clock_source_descriptor {
31 __u8 iClockSource; 41 __u8 iClockSource;
32} __attribute__((packed)); 42} __attribute__((packed));
33 43
44/* bmAttribute fields */
45#define UAC_CLOCK_SOURCE_TYPE_EXT 0x0
46#define UAC_CLOCK_SOURCE_TYPE_INT_FIXED 0x1
47#define UAC_CLOCK_SOURCE_TYPE_INT_VAR 0x2
48#define UAC_CLOCK_SOURCE_TYPE_INT_PROG 0x3
49#define UAC_CLOCK_SOURCE_SYNCED_TO_SOF (1 << 2)
50
34/* 4.7.2.2 Clock Source Descriptor */ 51/* 4.7.2.2 Clock Source Descriptor */
35 52
36struct uac_clock_selector_descriptor { 53struct uac_clock_selector_descriptor {
@@ -39,8 +56,20 @@ struct uac_clock_selector_descriptor {
39 __u8 bDescriptorSubtype; 56 __u8 bDescriptorSubtype;
40 __u8 bClockID; 57 __u8 bClockID;
41 __u8 bNrInPins; 58 __u8 bNrInPins;
42 __u8 bmControls;
43 __u8 baCSourceID[]; 59 __u8 baCSourceID[];
60 /* bmControls, bAssocTerminal and iClockSource omitted */
61} __attribute__((packed));
62
63/* 4.7.2.3 Clock Multiplier Descriptor */
64
65struct uac_clock_multiplier_descriptor {
66 __u8 bLength;
67 __u8 bDescriptorType;
68 __u8 bDescriptorSubtype;
69 __u8 bClockID;
70 __u8 bCSourceID;
71 __u8 bmControls;
72 __u8 iClockMultiplier;
44} __attribute__((packed)); 73} __attribute__((packed));
45 74
46/* 4.7.2.4 Input terminal descriptor */ 75/* 4.7.2.4 Input terminal descriptor */
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h
index 5d646c388752..c51200c715e5 100644
--- a/include/linux/usb/audio.h
+++ b/include/linux/usb/audio.h
@@ -47,6 +47,15 @@
47#define UAC_FORMAT_TYPE 0x02 47#define UAC_FORMAT_TYPE 0x02
48#define UAC_FORMAT_SPECIFIC 0x03 48#define UAC_FORMAT_SPECIFIC 0x03
49 49
50/* A.7 Processing Unit Process Types */
51#define UAC_PROCESS_UNDEFINED 0x00
52#define UAC_PROCESS_UP_DOWNMIX 0x01
53#define UAC_PROCESS_DOLBY_PROLOGIC 0x02
54#define UAC_PROCESS_STEREO_EXTENDER 0x03
55#define UAC_PROCESS_REVERB 0x04
56#define UAC_PROCESS_CHORUS 0x05
57#define UAC_PROCESS_DYN_RANGE_COMP 0x06
58
50/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */ 59/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */
51#define UAC_EP_GENERAL 0x01 60#define UAC_EP_GENERAL 0x01
52 61
@@ -73,6 +82,60 @@
73 82
74#define UAC_GET_STAT 0xff 83#define UAC_GET_STAT 0xff
75 84
85/* A.10 Control Selector Codes */
86
87/* A.10.1 Terminal Control Selectors */
88#define UAC_TERM_COPY_PROTECT 0x01
89
90/* A.10.2 Feature Unit Control Selectors */
91#define UAC_FU_MUTE 0x01
92#define UAC_FU_VOLUME 0x02
93#define UAC_FU_BASS 0x03
94#define UAC_FU_MID 0x04
95#define UAC_FU_TREBLE 0x05
96#define UAC_FU_GRAPHIC_EQUALIZER 0x06
97#define UAC_FU_AUTOMATIC_GAIN 0x07
98#define UAC_FU_DELAY 0x08
99#define UAC_FU_BASS_BOOST 0x09
100#define UAC_FU_LOUDNESS 0x0a
101
102#define UAC_CONTROL_BIT(CS) (1 << ((CS) - 1))
103
104/* A.10.3.1 Up/Down-mix Processing Unit Controls Selectors */
105#define UAC_UD_ENABLE 0x01
106#define UAC_UD_MODE_SELECT 0x02
107
108/* A.10.3.2 Dolby Prologic (tm) Processing Unit Controls Selectors */
109#define UAC_DP_ENABLE 0x01
110#define UAC_DP_MODE_SELECT 0x02
111
112/* A.10.3.3 3D Stereo Extender Processing Unit Control Selectors */
113#define UAC_3D_ENABLE 0x01
114#define UAC_3D_SPACE 0x02
115
116/* A.10.3.4 Reverberation Processing Unit Control Selectors */
117#define UAC_REVERB_ENABLE 0x01
118#define UAC_REVERB_LEVEL 0x02
119#define UAC_REVERB_TIME 0x03
120#define UAC_REVERB_FEEDBACK 0x04
121
122/* A.10.3.5 Chorus Processing Unit Control Selectors */
123#define UAC_CHORUS_ENABLE 0x01
124#define UAC_CHORUS_LEVEL 0x02
125#define UAC_CHORUS_RATE 0x03
126#define UAC_CHORUS_DEPTH 0x04
127
128/* A.10.3.6 Dynamic Range Compressor Unit Control Selectors */
129#define UAC_DCR_ENABLE 0x01
130#define UAC_DCR_RATE 0x02
131#define UAC_DCR_MAXAMPL 0x03
132#define UAC_DCR_THRESHOLD 0x04
133#define UAC_DCR_ATTACK_TIME 0x05
134#define UAC_DCR_RELEASE_TIME 0x06
135
136/* A.10.4 Extension Unit Control Selectors */
137#define UAC_XU_ENABLE 0x01
138
76/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */ 139/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
77#define UAC_MS_HEADER 0x01 140#define UAC_MS_HEADER 0x01
78#define UAC_MIDI_IN_JACK 0x02 141#define UAC_MIDI_IN_JACK 0x02
@@ -244,7 +307,7 @@ struct uac_selector_unit_descriptor {
244static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc) 307static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
245{ 308{
246 __u8 *raw = (__u8 *) desc; 309 __u8 *raw = (__u8 *) desc;
247 return raw[9 + desc->bLength - 1]; 310 return raw[desc->bLength - 1];
248} 311}
249 312
250/* 4.3.2.5 Feature Unit Descriptor */ 313/* 4.3.2.5 Feature Unit Descriptor */
@@ -463,31 +526,6 @@ struct uac_iso_endpoint_descriptor {
463#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02 526#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02
464#define UAC_EP_CS_ATTR_FILL_MAX 0x80 527#define UAC_EP_CS_ATTR_FILL_MAX 0x80
465 528
466/* A.10.2 Feature Unit Control Selectors */
467
468#define UAC_FU_CONTROL_UNDEFINED 0x00
469#define UAC_MUTE_CONTROL 0x01
470#define UAC_VOLUME_CONTROL 0x02
471#define UAC_BASS_CONTROL 0x03
472#define UAC_MID_CONTROL 0x04
473#define UAC_TREBLE_CONTROL 0x05
474#define UAC_GRAPHIC_EQUALIZER_CONTROL 0x06
475#define UAC_AUTOMATIC_GAIN_CONTROL 0x07
476#define UAC_DELAY_CONTROL 0x08
477#define UAC_BASS_BOOST_CONTROL 0x09
478#define UAC_LOUDNESS_CONTROL 0x0a
479
480#define UAC_FU_MUTE (1 << (UAC_MUTE_CONTROL - 1))
481#define UAC_FU_VOLUME (1 << (UAC_VOLUME_CONTROL - 1))
482#define UAC_FU_BASS (1 << (UAC_BASS_CONTROL - 1))
483#define UAC_FU_MID (1 << (UAC_MID_CONTROL - 1))
484#define UAC_FU_TREBLE (1 << (UAC_TREBLE_CONTROL - 1))
485#define UAC_FU_GRAPHIC_EQ (1 << (UAC_GRAPHIC_EQUALIZER_CONTROL - 1))
486#define UAC_FU_AUTO_GAIN (1 << (UAC_AUTOMATIC_GAIN_CONTROL - 1))
487#define UAC_FU_DELAY (1 << (UAC_DELAY_CONTROL - 1))
488#define UAC_FU_BASS_BOOST (1 << (UAC_BASS_BOOST_CONTROL - 1))
489#define UAC_FU_LOUDNESS (1 << (UAC_LOUDNESS_CONTROL - 1))
490
491/* status word format (3.7.1.1) */ 529/* status word format (3.7.1.1) */
492 530
493#define UAC1_STATUS_TYPE_ORIG_MASK 0x0f 531#define UAC1_STATUS_TYPE_ORIG_MASK 0x0f
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
index 2dfaa293ae8c..c9a975976995 100644
--- a/include/linux/vgaarb.h
+++ b/include/linux/vgaarb.h
@@ -5,6 +5,27 @@
5 * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> 5 * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
6 * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com> 6 * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com>
7 * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org> 7 * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS
27 * IN THE SOFTWARE.
28 *
8 */ 29 */
9 30
10#ifndef LINUX_VGA_H 31#ifndef LINUX_VGA_H
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index cc97d6caf2b3..f64134653a8c 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -65,15 +65,6 @@ struct writeback_control {
65 * so we use a single control to update them 65 * so we use a single control to update them
66 */ 66 */
67 unsigned no_nrwrite_index_update:1; 67 unsigned no_nrwrite_index_update:1;
68
69 /*
70 * For WB_SYNC_ALL, the sb must always be pinned. For WB_SYNC_NONE,
71 * the writeback code will pin the sb for the caller. However,
72 * for eg umount, the caller does WB_SYNC_NONE but already has
73 * the sb pinned. If the below is set, caller already has the
74 * sb pinned.
75 */
76 unsigned sb_pinned:1;
77}; 68};
78 69
79/* 70/*
@@ -82,7 +73,6 @@ struct writeback_control {
82struct bdi_writeback; 73struct bdi_writeback;
83int inode_wait(void *); 74int inode_wait(void *);
84void writeback_inodes_sb(struct super_block *); 75void writeback_inodes_sb(struct super_block *);
85void writeback_inodes_sb_locked(struct super_block *);
86int writeback_inodes_sb_if_idle(struct super_block *); 76int writeback_inodes_sb_if_idle(struct super_block *);
87void sync_inodes_sb(struct super_block *); 77void sync_inodes_sb(struct super_block *);
88void writeback_inodes_wbc(struct writeback_control *wbc); 78void writeback_inodes_wbc(struct writeback_control *wbc);
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 5833966a7100..c78e99a435b6 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -55,7 +55,8 @@ void rc_map_init(void);
55#define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d" 55#define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d"
56#define RC_MAP_AVERMEDIA_CARDBUS "rc-avermedia-cardbus" 56#define RC_MAP_AVERMEDIA_CARDBUS "rc-avermedia-cardbus"
57#define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt" 57#define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt"
58#define RC_MAP_AVERMEDIA_M135A_RM_JX "rc-avermedia-m135a-rm-jx" 58#define RC_MAP_AVERMEDIA_M135A "rc-avermedia-m135a"
59#define RC_MAP_AVERMEDIA_M733A_RM_K6 "rc-avermedia-m733a-rm-k6"
59#define RC_MAP_AVERMEDIA "rc-avermedia" 60#define RC_MAP_AVERMEDIA "rc-avermedia"
60#define RC_MAP_AVERTV_303 "rc-avertv-303" 61#define RC_MAP_AVERTV_303 "rc-avertv-303"
61#define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus" 62#define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus"
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index c9a5bbfa6ab5..b8289c2f609b 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -66,7 +66,7 @@ struct soc_camera_host_ops {
66 * .get_formats() fail, .put_formats() will not be called at all, the 66 * .get_formats() fail, .put_formats() will not be called at all, the
67 * failing .get_formats() must then clean up internally. 67 * failing .get_formats() must then clean up internally.
68 */ 68 */
69 int (*get_formats)(struct soc_camera_device *, int, 69 int (*get_formats)(struct soc_camera_device *, unsigned int,
70 struct soc_camera_format_xlate *); 70 struct soc_camera_format_xlate *);
71 void (*put_formats)(struct soc_camera_device *); 71 void (*put_formats)(struct soc_camera_device *);
72 int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *); 72 int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *);
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h
index 0dbe02ada259..865cda7cd611 100644
--- a/include/media/v4l2-mediabus.h
+++ b/include/media/v4l2-mediabus.h
@@ -40,6 +40,7 @@ enum v4l2_mbus_pixelcode {
40 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, 40 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
41 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, 41 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
42 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, 42 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
43 V4L2_MBUS_FMT_SGRBG8_1X8,
43}; 44};
44 45
45/** 46/**
@@ -58,4 +59,24 @@ struct v4l2_mbus_framefmt {
58 enum v4l2_colorspace colorspace; 59 enum v4l2_colorspace colorspace;
59}; 60};
60 61
62static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
63 const struct v4l2_mbus_framefmt *mbus_fmt)
64{
65 pix_fmt->width = mbus_fmt->width;
66 pix_fmt->height = mbus_fmt->height;
67 pix_fmt->field = mbus_fmt->field;
68 pix_fmt->colorspace = mbus_fmt->colorspace;
69}
70
71static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
72 const struct v4l2_pix_format *pix_fmt,
73 enum v4l2_mbus_pixelcode code)
74{
75 mbus_fmt->width = pix_fmt->width;
76 mbus_fmt->height = pix_fmt->height;
77 mbus_fmt->field = pix_fmt->field;
78 mbus_fmt->colorspace = pix_fmt->colorspace;
79 mbus_fmt->code = code;
80}
81
61#endif 82#endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index a88889355ae0..02c6f4d11ed3 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -246,7 +246,7 @@ struct v4l2_subdev_video_ops {
246 struct v4l2_dv_timings *timings); 246 struct v4l2_dv_timings *timings);
247 int (*g_dv_timings)(struct v4l2_subdev *sd, 247 int (*g_dv_timings)(struct v4l2_subdev *sd,
248 struct v4l2_dv_timings *timings); 248 struct v4l2_dv_timings *timings);
249 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, int index, 249 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index,
250 enum v4l2_mbus_pixelcode *code); 250 enum v4l2_mbus_pixelcode *code);
251 int (*g_mbus_fmt)(struct v4l2_subdev *sd, 251 int (*g_mbus_fmt)(struct v4l2_subdev *sd,
252 struct v4l2_mbus_framefmt *fmt); 252 struct v4l2_mbus_framefmt *fmt);
diff --git a/include/net/dst.h b/include/net/dst.h
index 612069beda73..81d1413a8701 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -250,11 +250,11 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
250 * Linux networking. Thus, destinations are stackable. 250 * Linux networking. Thus, destinations are stackable.
251 */ 251 */
252 252
253static inline struct dst_entry *dst_pop(struct dst_entry *dst) 253static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
254{ 254{
255 struct dst_entry *child = dst_clone(dst->child); 255 struct dst_entry *child = skb_dst(skb)->child;
256 256
257 dst_release(dst); 257 skb_dst_drop(skb);
258 return child; 258 return child;
259} 259}
260 260
diff --git a/include/net/sock.h b/include/net/sock.h
index ca241ea14875..731150d52799 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1524,20 +1524,7 @@ extern void sk_stop_timer(struct sock *sk, struct timer_list* timer);
1524 1524
1525extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); 1525extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
1526 1526
1527static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) 1527extern int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb);
1528{
1529 /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
1530 number of warnings when compiling with -W --ANK
1531 */
1532 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
1533 (unsigned)sk->sk_rcvbuf)
1534 return -ENOMEM;
1535 skb_set_owner_r(skb, sk);
1536 skb_queue_tail(&sk->sk_error_queue, skb);
1537 if (!sock_flag(sk, SOCK_DEAD))
1538 sk->sk_data_ready(sk, skb->len);
1539 return 0;
1540}
1541 1528
1542/* 1529/*
1543 * Recover an error report and clear atomically 1530 * Recover an error report and clear atomically
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index c50a97fc76f9..b7bdecb7b76e 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -327,6 +327,14 @@ struct scsi_host_template {
327 sector_t, int []); 327 sector_t, int []);
328 328
329 /* 329 /*
330 * This function is called when one or more partitions on the
331 * device reach beyond the end of the device.
332 *
333 * Status: OPTIONAL
334 */
335 void (*unlock_native_capacity)(struct scsi_device *);
336
337 /*
330 * Can be used to export driver statistics and other infos to the 338 * Can be used to export driver statistics and other infos to the
331 * world outside the kernel ie. userspace and it also provides an 339 * world outside the kernel ie. userspace and it also provides an
332 * interface to feed the driver with information. 340 * interface to feed the driver with information.
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 4f733ecea46e..b9e1dd6c6208 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -115,6 +115,23 @@ DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new,
115 TP_PROTO(struct task_struct *p, int success), 115 TP_PROTO(struct task_struct *p, int success),
116 TP_ARGS(p, success)); 116 TP_ARGS(p, success));
117 117
118#ifdef CREATE_TRACE_POINTS
119static inline long __trace_sched_switch_state(struct task_struct *p)
120{
121 long state = p->state;
122
123#ifdef CONFIG_PREEMPT
124 /*
125 * For all intents and purposes a preempted task is a running task.
126 */
127 if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE)
128 state = TASK_RUNNING;
129#endif
130
131 return state;
132}
133#endif
134
118/* 135/*
119 * Tracepoint for task switches, performed by the scheduler: 136 * Tracepoint for task switches, performed by the scheduler:
120 */ 137 */
@@ -139,7 +156,7 @@ TRACE_EVENT(sched_switch,
139 memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); 156 memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
140 __entry->prev_pid = prev->pid; 157 __entry->prev_pid = prev->pid;
141 __entry->prev_prio = prev->prio; 158 __entry->prev_prio = prev->prio;
142 __entry->prev_state = prev->state; 159 __entry->prev_state = __trace_sched_switch_state(prev);
143 memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); 160 memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
144 __entry->next_pid = next->pid; 161 __entry->next_pid = next->pid;
145 __entry->next_prio = next->prio; 162 __entry->next_prio = next->prio;
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 3d685d1f2a03..5a64905d7278 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -725,7 +725,7 @@ perf_trace_##call(void *__data, proto) \
725 \ 725 \
726 { assign; } \ 726 { assign; } \
727 \ 727 \
728 head = per_cpu_ptr(event_call->perf_events, smp_processor_id());\ 728 head = this_cpu_ptr(event_call->perf_events); \
729 perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ 729 perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \
730 __count, &__regs, head); \ 730 __count, &__regs, head); \
731} 731}
diff --git a/init/Kconfig b/init/Kconfig
index 2cce9f343ad0..5cff9a980c39 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -76,6 +76,14 @@ config INIT_ENV_ARG_LIMIT
76 variables passed to init from the kernel command line. 76 variables passed to init from the kernel command line.
77 77
78 78
79config CROSS_COMPILE
80 string "Cross-compiler tool prefix"
81 help
82 Same as running 'make CROSS_COMPILE=prefix-' but stored for
83 default make runs in this kernel build directory. You don't
84 need to set this unless you want the configured kernel build
85 directory to select the cross-compiler automatically.
86
79config LOCALVERSION 87config LOCALVERSION
80 string "Local version - append to kernel release" 88 string "Local version - append to kernel release"
81 help 89 help
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 5108232f93d4..c93fd3faac2d 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -176,7 +176,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
176 } 176 }
177 return inode; 177 return inode;
178out_inode: 178out_inode:
179 make_bad_inode(inode);
180 iput(inode); 179 iput(inode);
181 return NULL; 180 return NULL;
182} 181}
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 422cb19f156e..3ac6f5b0a64b 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4598,7 +4598,7 @@ static int alloc_css_id(struct cgroup_subsys *ss, struct cgroup *parent,
4598 parent_css = parent->subsys[subsys_id]; 4598 parent_css = parent->subsys[subsys_id];
4599 child_css = child->subsys[subsys_id]; 4599 child_css = child->subsys[subsys_id];
4600 parent_id = parent_css->id; 4600 parent_id = parent_css->id;
4601 depth = parent_id->depth; 4601 depth = parent_id->depth + 1;
4602 4602
4603 child_id = get_new_cssid(ss, depth); 4603 child_id = get_new_cssid(ss, depth);
4604 if (IS_ERR(child_id)) 4604 if (IS_ERR(child_id))
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 8b92539b4754..97d1b426a4ac 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -34,7 +34,7 @@ void cpu_maps_update_done(void)
34 mutex_unlock(&cpu_add_remove_lock); 34 mutex_unlock(&cpu_add_remove_lock);
35} 35}
36 36
37static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain); 37static RAW_NOTIFIER_HEAD(cpu_chain);
38 38
39/* If set, cpu_up and cpu_down will return -EBUSY and do nothing. 39/* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
40 * Should always be manipulated under cpu_add_remove_lock 40 * Should always be manipulated under cpu_add_remove_lock
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index b724c791b6d4..184cd8209c36 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -1857,12 +1857,6 @@ static int kdb_ef(int argc, const char **argv)
1857} 1857}
1858 1858
1859#if defined(CONFIG_MODULES) 1859#if defined(CONFIG_MODULES)
1860/* modules using other modules */
1861struct module_use {
1862 struct list_head list;
1863 struct module *module_which_uses;
1864};
1865
1866/* 1860/*
1867 * kdb_lsmod - This function implements the 'lsmod' command. Lists 1861 * kdb_lsmod - This function implements the 'lsmod' command. Lists
1868 * currently loaded kernel modules. 1862 * currently loaded kernel modules.
@@ -1894,9 +1888,9 @@ static int kdb_lsmod(int argc, const char **argv)
1894 { 1888 {
1895 struct module_use *use; 1889 struct module_use *use;
1896 kdb_printf(" [ "); 1890 kdb_printf(" [ ");
1897 list_for_each_entry(use, &mod->modules_which_use_me, 1891 list_for_each_entry(use, &mod->source_list,
1898 list) 1892 source_list)
1899 kdb_printf("%s ", use->module_which_uses->name); 1893 kdb_printf("%s ", use->target->name);
1900 kdb_printf("]\n"); 1894 kdb_printf("]\n");
1901 } 1895 }
1902#endif 1896#endif
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index c35452cadded..dd62f8e714ca 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -27,7 +27,7 @@ static struct exec_domain *exec_domains = &default_exec_domain;
27static DEFINE_RWLOCK(exec_domains_lock); 27static DEFINE_RWLOCK(exec_domains_lock);
28 28
29 29
30static u_long ident_map[32] = { 30static unsigned long ident_map[32] = {
31 0, 1, 2, 3, 4, 5, 6, 7, 31 0, 1, 2, 3, 4, 5, 6, 7,
32 8, 9, 10, 11, 12, 13, 14, 15, 32 8, 9, 10, 11, 12, 13, 14, 15,
33 16, 17, 18, 19, 20, 21, 22, 23, 33 16, 17, 18, 19, 20, 21, 22, 23,
@@ -56,10 +56,10 @@ default_handler(int segment, struct pt_regs *regp)
56} 56}
57 57
58static struct exec_domain * 58static struct exec_domain *
59lookup_exec_domain(u_long personality) 59lookup_exec_domain(unsigned int personality)
60{ 60{
61 struct exec_domain * ep; 61 unsigned int pers = personality(personality);
62 u_long pers = personality(personality); 62 struct exec_domain *ep;
63 63
64 read_lock(&exec_domains_lock); 64 read_lock(&exec_domains_lock);
65 for (ep = exec_domains; ep; ep = ep->next) { 65 for (ep = exec_domains; ep; ep = ep->next) {
@@ -70,7 +70,7 @@ lookup_exec_domain(u_long personality)
70 70
71#ifdef CONFIG_MODULES 71#ifdef CONFIG_MODULES
72 read_unlock(&exec_domains_lock); 72 read_unlock(&exec_domains_lock);
73 request_module("personality-%ld", pers); 73 request_module("personality-%d", pers);
74 read_lock(&exec_domains_lock); 74 read_lock(&exec_domains_lock);
75 75
76 for (ep = exec_domains; ep; ep = ep->next) { 76 for (ep = exec_domains; ep; ep = ep->next) {
@@ -135,7 +135,7 @@ unregister:
135} 135}
136 136
137int 137int
138__set_personality(u_long personality) 138__set_personality(unsigned int personality)
139{ 139{
140 struct exec_domain *ep, *oep; 140 struct exec_domain *ep, *oep;
141 141
@@ -188,9 +188,9 @@ static int __init proc_execdomains_init(void)
188module_init(proc_execdomains_init); 188module_init(proc_execdomains_init);
189#endif 189#endif
190 190
191SYSCALL_DEFINE1(personality, u_long, personality) 191SYSCALL_DEFINE1(personality, unsigned int, personality)
192{ 192{
193 u_long old = current->personality; 193 unsigned int old = current->personality;
194 194
195 if (personality != 0xffffffff) { 195 if (personality != 0xffffffff) {
196 set_personality(personality); 196 set_personality(personality);
@@ -198,7 +198,7 @@ SYSCALL_DEFINE1(personality, u_long, personality)
198 return -EINVAL; 198 return -EINVAL;
199 } 199 }
200 200
201 return (long)old; 201 return old;
202} 202}
203 203
204 204
diff --git a/kernel/module.c b/kernel/module.c
index 333fbcc96978..8c6b42840dd1 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -72,7 +72,11 @@
72/* If this is set, the section belongs in the init part of the module */ 72/* If this is set, the section belongs in the init part of the module */
73#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) 73#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
74 74
75/* List of modules, protected by module_mutex or preempt_disable 75/*
76 * Mutex protects:
77 * 1) List of modules (also safely readable with preempt_disable),
78 * 2) module_use links,
79 * 3) module_addr_min/module_addr_max.
76 * (delete uses stop_machine/add uses RCU list operations). */ 80 * (delete uses stop_machine/add uses RCU list operations). */
77DEFINE_MUTEX(module_mutex); 81DEFINE_MUTEX(module_mutex);
78EXPORT_SYMBOL_GPL(module_mutex); 82EXPORT_SYMBOL_GPL(module_mutex);
@@ -90,7 +94,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq);
90 94
91static BLOCKING_NOTIFIER_HEAD(module_notify_list); 95static BLOCKING_NOTIFIER_HEAD(module_notify_list);
92 96
93/* Bounds of module allocation, for speeding __module_address */ 97/* Bounds of module allocation, for speeding __module_address.
98 * Protected by module_mutex. */
94static unsigned long module_addr_min = -1UL, module_addr_max = 0; 99static unsigned long module_addr_min = -1UL, module_addr_max = 0;
95 100
96int register_module_notifier(struct notifier_block * nb) 101int register_module_notifier(struct notifier_block * nb)
@@ -329,7 +334,7 @@ static bool find_symbol_in_section(const struct symsearch *syms,
329} 334}
330 335
331/* Find a symbol and return it, along with, (optional) crc and 336/* Find a symbol and return it, along with, (optional) crc and
332 * (optional) module which owns it */ 337 * (optional) module which owns it. Needs preempt disabled or module_mutex. */
333const struct kernel_symbol *find_symbol(const char *name, 338const struct kernel_symbol *find_symbol(const char *name,
334 struct module **owner, 339 struct module **owner,
335 const unsigned long **crc, 340 const unsigned long **crc,
@@ -403,7 +408,7 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr,
403 Elf_Shdr *sechdrs, 408 Elf_Shdr *sechdrs,
404 const char *secstrings) 409 const char *secstrings)
405{ 410{
406 return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); 411 return find_sec(hdr, sechdrs, secstrings, ".data..percpu");
407} 412}
408 413
409static void percpu_modcopy(struct module *mod, 414static void percpu_modcopy(struct module *mod,
@@ -523,7 +528,8 @@ static void module_unload_init(struct module *mod)
523{ 528{
524 int cpu; 529 int cpu;
525 530
526 INIT_LIST_HEAD(&mod->modules_which_use_me); 531 INIT_LIST_HEAD(&mod->source_list);
532 INIT_LIST_HEAD(&mod->target_list);
527 for_each_possible_cpu(cpu) { 533 for_each_possible_cpu(cpu) {
528 per_cpu_ptr(mod->refptr, cpu)->incs = 0; 534 per_cpu_ptr(mod->refptr, cpu)->incs = 0;
529 per_cpu_ptr(mod->refptr, cpu)->decs = 0; 535 per_cpu_ptr(mod->refptr, cpu)->decs = 0;
@@ -535,20 +541,13 @@ static void module_unload_init(struct module *mod)
535 mod->waiter = current; 541 mod->waiter = current;
536} 542}
537 543
538/* modules using other modules */
539struct module_use
540{
541 struct list_head list;
542 struct module *module_which_uses;
543};
544
545/* Does a already use b? */ 544/* Does a already use b? */
546static int already_uses(struct module *a, struct module *b) 545static int already_uses(struct module *a, struct module *b)
547{ 546{
548 struct module_use *use; 547 struct module_use *use;
549 548
550 list_for_each_entry(use, &b->modules_which_use_me, list) { 549 list_for_each_entry(use, &b->source_list, source_list) {
551 if (use->module_which_uses == a) { 550 if (use->source == a) {
552 DEBUGP("%s uses %s!\n", a->name, b->name); 551 DEBUGP("%s uses %s!\n", a->name, b->name);
553 return 1; 552 return 1;
554 } 553 }
@@ -557,62 +556,68 @@ static int already_uses(struct module *a, struct module *b)
557 return 0; 556 return 0;
558} 557}
559 558
560/* Module a uses b */ 559/*
561int use_module(struct module *a, struct module *b) 560 * Module a uses b
561 * - we add 'a' as a "source", 'b' as a "target" of module use
562 * - the module_use is added to the list of 'b' sources (so
563 * 'b' can walk the list to see who sourced them), and of 'a'
564 * targets (so 'a' can see what modules it targets).
565 */
566static int add_module_usage(struct module *a, struct module *b)
562{ 567{
563 struct module_use *use; 568 struct module_use *use;
564 int no_warn, err;
565 569
566 if (b == NULL || already_uses(a, b)) return 1; 570 DEBUGP("Allocating new usage for %s.\n", a->name);
571 use = kmalloc(sizeof(*use), GFP_ATOMIC);
572 if (!use) {
573 printk(KERN_WARNING "%s: out of memory loading\n", a->name);
574 return -ENOMEM;
575 }
576
577 use->source = a;
578 use->target = b;
579 list_add(&use->source_list, &b->source_list);
580 list_add(&use->target_list, &a->target_list);
581 return 0;
582}
583
584/* Module a uses b: caller needs module_mutex() */
585int ref_module(struct module *a, struct module *b)
586{
587 int err;
567 588
568 /* If we're interrupted or time out, we fail. */ 589 if (b == NULL || already_uses(a, b))
569 if (wait_event_interruptible_timeout(
570 module_wq, (err = strong_try_module_get(b)) != -EBUSY,
571 30 * HZ) <= 0) {
572 printk("%s: gave up waiting for init of module %s.\n",
573 a->name, b->name);
574 return 0; 590 return 0;
575 }
576 591
577 /* If strong_try_module_get() returned a different error, we fail. */ 592 /* If module isn't available, we fail. */
593 err = strong_try_module_get(b);
578 if (err) 594 if (err)
579 return 0; 595 return err;
580 596
581 DEBUGP("Allocating new usage for %s.\n", a->name); 597 err = add_module_usage(a, b);
582 use = kmalloc(sizeof(*use), GFP_ATOMIC); 598 if (err) {
583 if (!use) {
584 printk("%s: out of memory loading\n", a->name);
585 module_put(b); 599 module_put(b);
586 return 0; 600 return err;
587 } 601 }
588 602 return 0;
589 use->module_which_uses = a;
590 list_add(&use->list, &b->modules_which_use_me);
591 no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
592 return 1;
593} 603}
594EXPORT_SYMBOL_GPL(use_module); 604EXPORT_SYMBOL_GPL(ref_module);
595 605
596/* Clear the unload stuff of the module. */ 606/* Clear the unload stuff of the module. */
597static void module_unload_free(struct module *mod) 607static void module_unload_free(struct module *mod)
598{ 608{
599 struct module *i; 609 struct module_use *use, *tmp;
600 610
601 list_for_each_entry(i, &modules, list) { 611 mutex_lock(&module_mutex);
602 struct module_use *use; 612 list_for_each_entry_safe(use, tmp, &mod->target_list, target_list) {
603 613 struct module *i = use->target;
604 list_for_each_entry(use, &i->modules_which_use_me, list) { 614 DEBUGP("%s unusing %s\n", mod->name, i->name);
605 if (use->module_which_uses == mod) { 615 module_put(i);
606 DEBUGP("%s unusing %s\n", mod->name, i->name); 616 list_del(&use->source_list);
607 module_put(i); 617 list_del(&use->target_list);
608 list_del(&use->list); 618 kfree(use);
609 kfree(use);
610 sysfs_remove_link(i->holders_dir, mod->name);
611 /* There can be at most one match. */
612 break;
613 }
614 }
615 } 619 }
620 mutex_unlock(&module_mutex);
616} 621}
617 622
618#ifdef CONFIG_MODULE_FORCE_UNLOAD 623#ifdef CONFIG_MODULE_FORCE_UNLOAD
@@ -735,7 +740,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
735 goto out; 740 goto out;
736 } 741 }
737 742
738 if (!list_empty(&mod->modules_which_use_me)) { 743 if (!list_empty(&mod->source_list)) {
739 /* Other modules depend on us: get rid of them first. */ 744 /* Other modules depend on us: get rid of them first. */
740 ret = -EWOULDBLOCK; 745 ret = -EWOULDBLOCK;
741 goto out; 746 goto out;
@@ -779,13 +784,14 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
779 blocking_notifier_call_chain(&module_notify_list, 784 blocking_notifier_call_chain(&module_notify_list,
780 MODULE_STATE_GOING, mod); 785 MODULE_STATE_GOING, mod);
781 async_synchronize_full(); 786 async_synchronize_full();
782 mutex_lock(&module_mutex); 787
783 /* Store the name of the last unloaded module for diagnostic purposes */ 788 /* Store the name of the last unloaded module for diagnostic purposes */
784 strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); 789 strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
785 ddebug_remove_module(mod->name); 790 ddebug_remove_module(mod->name);
786 free_module(mod);
787 791
788 out: 792 free_module(mod);
793 return 0;
794out:
789 mutex_unlock(&module_mutex); 795 mutex_unlock(&module_mutex);
790 return ret; 796 return ret;
791} 797}
@@ -799,9 +805,9 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod)
799 805
800 /* Always include a trailing , so userspace can differentiate 806 /* Always include a trailing , so userspace can differentiate
801 between this and the old multi-field proc format. */ 807 between this and the old multi-field proc format. */
802 list_for_each_entry(use, &mod->modules_which_use_me, list) { 808 list_for_each_entry(use, &mod->source_list, source_list) {
803 printed_something = 1; 809 printed_something = 1;
804 seq_printf(m, "%s,", use->module_which_uses->name); 810 seq_printf(m, "%s,", use->source->name);
805 } 811 }
806 812
807 if (mod->init != NULL && mod->exit == NULL) { 813 if (mod->init != NULL && mod->exit == NULL) {
@@ -880,11 +886,11 @@ static inline void module_unload_free(struct module *mod)
880{ 886{
881} 887}
882 888
883int use_module(struct module *a, struct module *b) 889int ref_module(struct module *a, struct module *b)
884{ 890{
885 return strong_try_module_get(b) == 0; 891 return strong_try_module_get(b);
886} 892}
887EXPORT_SYMBOL_GPL(use_module); 893EXPORT_SYMBOL_GPL(ref_module);
888 894
889static inline void module_unload_init(struct module *mod) 895static inline void module_unload_init(struct module *mod)
890{ 896{
@@ -1001,6 +1007,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
1001{ 1007{
1002 const unsigned long *crc; 1008 const unsigned long *crc;
1003 1009
1010 /* Since this should be found in kernel (which can't be removed),
1011 * no locking is necessary. */
1004 if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, 1012 if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
1005 &crc, true, false)) 1013 &crc, true, false))
1006 BUG(); 1014 BUG();
@@ -1043,29 +1051,62 @@ static inline int same_magic(const char *amagic, const char *bmagic,
1043} 1051}
1044#endif /* CONFIG_MODVERSIONS */ 1052#endif /* CONFIG_MODVERSIONS */
1045 1053
1046/* Resolve a symbol for this module. I.e. if we find one, record usage. 1054/* Resolve a symbol for this module. I.e. if we find one, record usage. */
1047 Must be holding module_mutex. */
1048static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, 1055static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
1049 unsigned int versindex, 1056 unsigned int versindex,
1050 const char *name, 1057 const char *name,
1051 struct module *mod) 1058 struct module *mod,
1059 char ownername[])
1052{ 1060{
1053 struct module *owner; 1061 struct module *owner;
1054 const struct kernel_symbol *sym; 1062 const struct kernel_symbol *sym;
1055 const unsigned long *crc; 1063 const unsigned long *crc;
1064 int err;
1056 1065
1066 mutex_lock(&module_mutex);
1057 sym = find_symbol(name, &owner, &crc, 1067 sym = find_symbol(name, &owner, &crc,
1058 !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); 1068 !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
1059 /* use_module can fail due to OOM, 1069 if (!sym)
1060 or module initialization or unloading */ 1070 goto unlock;
1061 if (sym) { 1071
1062 if (!check_version(sechdrs, versindex, name, mod, crc, owner) 1072 if (!check_version(sechdrs, versindex, name, mod, crc, owner)) {
1063 || !use_module(mod, owner)) 1073 sym = ERR_PTR(-EINVAL);
1064 sym = NULL; 1074 goto getname;
1075 }
1076
1077 err = ref_module(mod, owner);
1078 if (err) {
1079 sym = ERR_PTR(err);
1080 goto getname;
1065 } 1081 }
1082
1083getname:
1084 /* We must make copy under the lock if we failed to get ref. */
1085 strncpy(ownername, module_name(owner), MODULE_NAME_LEN);
1086unlock:
1087 mutex_unlock(&module_mutex);
1066 return sym; 1088 return sym;
1067} 1089}
1068 1090
1091static const struct kernel_symbol *resolve_symbol_wait(Elf_Shdr *sechdrs,
1092 unsigned int versindex,
1093 const char *name,
1094 struct module *mod)
1095{
1096 const struct kernel_symbol *ksym;
1097 char ownername[MODULE_NAME_LEN];
1098
1099 if (wait_event_interruptible_timeout(module_wq,
1100 !IS_ERR(ksym = resolve_symbol(sechdrs, versindex, name,
1101 mod, ownername)) ||
1102 PTR_ERR(ksym) != -EBUSY,
1103 30 * HZ) <= 0) {
1104 printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n",
1105 mod->name, ownername);
1106 }
1107 return ksym;
1108}
1109
1069/* 1110/*
1070 * /sys/module/foo/sections stuff 1111 * /sys/module/foo/sections stuff
1071 * J. Corbet <corbet@lwn.net> 1112 * J. Corbet <corbet@lwn.net>
@@ -1295,7 +1336,34 @@ static inline void remove_notes_attrs(struct module *mod)
1295#endif 1336#endif
1296 1337
1297#ifdef CONFIG_SYSFS 1338#ifdef CONFIG_SYSFS
1298int module_add_modinfo_attrs(struct module *mod) 1339static void add_usage_links(struct module *mod)
1340{
1341#ifdef CONFIG_MODULE_UNLOAD
1342 struct module_use *use;
1343 int nowarn;
1344
1345 mutex_lock(&module_mutex);
1346 list_for_each_entry(use, &mod->target_list, target_list) {
1347 nowarn = sysfs_create_link(use->target->holders_dir,
1348 &mod->mkobj.kobj, mod->name);
1349 }
1350 mutex_unlock(&module_mutex);
1351#endif
1352}
1353
1354static void del_usage_links(struct module *mod)
1355{
1356#ifdef CONFIG_MODULE_UNLOAD
1357 struct module_use *use;
1358
1359 mutex_lock(&module_mutex);
1360 list_for_each_entry(use, &mod->target_list, target_list)
1361 sysfs_remove_link(use->target->holders_dir, mod->name);
1362 mutex_unlock(&module_mutex);
1363#endif
1364}
1365
1366static int module_add_modinfo_attrs(struct module *mod)
1299{ 1367{
1300 struct module_attribute *attr; 1368 struct module_attribute *attr;
1301 struct module_attribute *temp_attr; 1369 struct module_attribute *temp_attr;
@@ -1321,7 +1389,7 @@ int module_add_modinfo_attrs(struct module *mod)
1321 return error; 1389 return error;
1322} 1390}
1323 1391
1324void module_remove_modinfo_attrs(struct module *mod) 1392static void module_remove_modinfo_attrs(struct module *mod)
1325{ 1393{
1326 struct module_attribute *attr; 1394 struct module_attribute *attr;
1327 int i; 1395 int i;
@@ -1337,7 +1405,7 @@ void module_remove_modinfo_attrs(struct module *mod)
1337 kfree(mod->modinfo_attrs); 1405 kfree(mod->modinfo_attrs);
1338} 1406}
1339 1407
1340int mod_sysfs_init(struct module *mod) 1408static int mod_sysfs_init(struct module *mod)
1341{ 1409{
1342 int err; 1410 int err;
1343 struct kobject *kobj; 1411 struct kobject *kobj;
@@ -1371,12 +1439,16 @@ out:
1371 return err; 1439 return err;
1372} 1440}
1373 1441
1374int mod_sysfs_setup(struct module *mod, 1442static int mod_sysfs_setup(struct module *mod,
1375 struct kernel_param *kparam, 1443 struct kernel_param *kparam,
1376 unsigned int num_params) 1444 unsigned int num_params)
1377{ 1445{
1378 int err; 1446 int err;
1379 1447
1448 err = mod_sysfs_init(mod);
1449 if (err)
1450 goto out;
1451
1380 mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj); 1452 mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj);
1381 if (!mod->holders_dir) { 1453 if (!mod->holders_dir) {
1382 err = -ENOMEM; 1454 err = -ENOMEM;
@@ -1391,6 +1463,8 @@ int mod_sysfs_setup(struct module *mod,
1391 if (err) 1463 if (err)
1392 goto out_unreg_param; 1464 goto out_unreg_param;
1393 1465
1466 add_usage_links(mod);
1467
1394 kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); 1468 kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
1395 return 0; 1469 return 0;
1396 1470
@@ -1400,6 +1474,7 @@ out_unreg_holders:
1400 kobject_put(mod->holders_dir); 1474 kobject_put(mod->holders_dir);
1401out_unreg: 1475out_unreg:
1402 kobject_put(&mod->mkobj.kobj); 1476 kobject_put(&mod->mkobj.kobj);
1477out:
1403 return err; 1478 return err;
1404} 1479}
1405 1480
@@ -1410,14 +1485,40 @@ static void mod_sysfs_fini(struct module *mod)
1410 1485
1411#else /* CONFIG_SYSFS */ 1486#else /* CONFIG_SYSFS */
1412 1487
1488static inline int mod_sysfs_init(struct module *mod)
1489{
1490 return 0;
1491}
1492
1493static inline int mod_sysfs_setup(struct module *mod,
1494 struct kernel_param *kparam,
1495 unsigned int num_params)
1496{
1497 return 0;
1498}
1499
1500static inline int module_add_modinfo_attrs(struct module *mod)
1501{
1502 return 0;
1503}
1504
1505static inline void module_remove_modinfo_attrs(struct module *mod)
1506{
1507}
1508
1413static void mod_sysfs_fini(struct module *mod) 1509static void mod_sysfs_fini(struct module *mod)
1414{ 1510{
1415} 1511}
1416 1512
1513static void del_usage_links(struct module *mod)
1514{
1515}
1516
1417#endif /* CONFIG_SYSFS */ 1517#endif /* CONFIG_SYSFS */
1418 1518
1419static void mod_kobject_remove(struct module *mod) 1519static void mod_kobject_remove(struct module *mod)
1420{ 1520{
1521 del_usage_links(mod);
1421 module_remove_modinfo_attrs(mod); 1522 module_remove_modinfo_attrs(mod);
1422 module_param_sysfs_remove(mod); 1523 module_param_sysfs_remove(mod);
1423 kobject_put(mod->mkobj.drivers_dir); 1524 kobject_put(mod->mkobj.drivers_dir);
@@ -1436,13 +1537,15 @@ static int __unlink_module(void *_mod)
1436 return 0; 1537 return 0;
1437} 1538}
1438 1539
1439/* Free a module, remove from lists, etc (must hold module_mutex). */ 1540/* Free a module, remove from lists, etc. */
1440static void free_module(struct module *mod) 1541static void free_module(struct module *mod)
1441{ 1542{
1442 trace_module_free(mod); 1543 trace_module_free(mod);
1443 1544
1444 /* Delete from various lists */ 1545 /* Delete from various lists */
1546 mutex_lock(&module_mutex);
1445 stop_machine(__unlink_module, mod, NULL); 1547 stop_machine(__unlink_module, mod, NULL);
1548 mutex_unlock(&module_mutex);
1446 remove_notes_attrs(mod); 1549 remove_notes_attrs(mod);
1447 remove_sect_attrs(mod); 1550 remove_sect_attrs(mod);
1448 mod_kobject_remove(mod); 1551 mod_kobject_remove(mod);
@@ -1493,6 +1596,8 @@ EXPORT_SYMBOL_GPL(__symbol_get);
1493/* 1596/*
1494 * Ensure that an exported symbol [global namespace] does not already exist 1597 * Ensure that an exported symbol [global namespace] does not already exist
1495 * in the kernel or in some other module's exported symbol table. 1598 * in the kernel or in some other module's exported symbol table.
1599 *
1600 * You must hold the module_mutex.
1496 */ 1601 */
1497static int verify_export_symbols(struct module *mod) 1602static int verify_export_symbols(struct module *mod)
1498{ 1603{
@@ -1558,21 +1663,23 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
1558 break; 1663 break;
1559 1664
1560 case SHN_UNDEF: 1665 case SHN_UNDEF:
1561 ksym = resolve_symbol(sechdrs, versindex, 1666 ksym = resolve_symbol_wait(sechdrs, versindex,
1562 strtab + sym[i].st_name, mod); 1667 strtab + sym[i].st_name,
1668 mod);
1563 /* Ok if resolved. */ 1669 /* Ok if resolved. */
1564 if (ksym) { 1670 if (ksym && !IS_ERR(ksym)) {
1565 sym[i].st_value = ksym->value; 1671 sym[i].st_value = ksym->value;
1566 break; 1672 break;
1567 } 1673 }
1568 1674
1569 /* Ok if weak. */ 1675 /* Ok if weak. */
1570 if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK) 1676 if (!ksym && ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
1571 break; 1677 break;
1572 1678
1573 printk(KERN_WARNING "%s: Unknown symbol %s\n", 1679 printk(KERN_WARNING "%s: Unknown symbol %s (err %li)\n",
1574 mod->name, strtab + sym[i].st_name); 1680 mod->name, strtab + sym[i].st_name,
1575 ret = -ENOENT; 1681 PTR_ERR(ksym));
1682 ret = PTR_ERR(ksym) ?: -ENOENT;
1576 break; 1683 break;
1577 1684
1578 default: 1685 default:
@@ -1960,11 +2067,13 @@ static void *module_alloc_update_bounds(unsigned long size)
1960 void *ret = module_alloc(size); 2067 void *ret = module_alloc(size);
1961 2068
1962 if (ret) { 2069 if (ret) {
2070 mutex_lock(&module_mutex);
1963 /* Update module bounds. */ 2071 /* Update module bounds. */
1964 if ((unsigned long)ret < module_addr_min) 2072 if ((unsigned long)ret < module_addr_min)
1965 module_addr_min = (unsigned long)ret; 2073 module_addr_min = (unsigned long)ret;
1966 if ((unsigned long)ret + size > module_addr_max) 2074 if ((unsigned long)ret + size > module_addr_max)
1967 module_addr_max = (unsigned long)ret + size; 2075 module_addr_max = (unsigned long)ret + size;
2076 mutex_unlock(&module_mutex);
1968 } 2077 }
1969 return ret; 2078 return ret;
1970} 2079}
@@ -2014,6 +2123,7 @@ static noinline struct module *load_module(void __user *umod,
2014 long err = 0; 2123 long err = 0;
2015 void *ptr = NULL; /* Stops spurious gcc warning */ 2124 void *ptr = NULL; /* Stops spurious gcc warning */
2016 unsigned long symoffs, stroffs, *strmap; 2125 unsigned long symoffs, stroffs, *strmap;
2126 void __percpu *percpu;
2017 2127
2018 mm_segment_t old_fs; 2128 mm_segment_t old_fs;
2019 2129
@@ -2138,11 +2248,6 @@ static noinline struct module *load_module(void __user *umod,
2138 goto free_mod; 2248 goto free_mod;
2139 } 2249 }
2140 2250
2141 if (find_module(mod->name)) {
2142 err = -EEXIST;
2143 goto free_mod;
2144 }
2145
2146 mod->state = MODULE_STATE_COMING; 2251 mod->state = MODULE_STATE_COMING;
2147 2252
2148 /* Allow arches to frob section contents and sizes. */ 2253 /* Allow arches to frob section contents and sizes. */
@@ -2158,6 +2263,8 @@ static noinline struct module *load_module(void __user *umod,
2158 goto free_mod; 2263 goto free_mod;
2159 sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; 2264 sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
2160 } 2265 }
2266 /* Keep this around for failure path. */
2267 percpu = mod_percpu(mod);
2161 2268
2162 /* Determine total sizes, and put offsets in sh_entsize. For now 2269 /* Determine total sizes, and put offsets in sh_entsize. For now
2163 this is done generically; there doesn't appear to be any 2270 this is done generically; there doesn't appear to be any
@@ -2231,11 +2338,6 @@ static noinline struct module *load_module(void __user *umod,
2231 /* Now we've moved module, initialize linked lists, etc. */ 2338 /* Now we've moved module, initialize linked lists, etc. */
2232 module_unload_init(mod); 2339 module_unload_init(mod);
2233 2340
2234 /* add kobject, so we can reference it. */
2235 err = mod_sysfs_init(mod);
2236 if (err)
2237 goto free_unload;
2238
2239 /* Set up license info based on the info section */ 2341 /* Set up license info based on the info section */
2240 set_license(mod, get_modinfo(sechdrs, infoindex, "license")); 2342 set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
2241 2343
@@ -2360,11 +2462,6 @@ static noinline struct module *load_module(void __user *umod,
2360 goto cleanup; 2462 goto cleanup;
2361 } 2463 }
2362 2464
2363 /* Find duplicate symbols */
2364 err = verify_export_symbols(mod);
2365 if (err < 0)
2366 goto cleanup;
2367
2368 /* Set up and sort exception table */ 2465 /* Set up and sort exception table */
2369 mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table", 2466 mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table",
2370 sizeof(*mod->extable), &mod->num_exentries); 2467 sizeof(*mod->extable), &mod->num_exentries);
@@ -2423,7 +2520,19 @@ static noinline struct module *load_module(void __user *umod,
2423 * function to insert in a way safe to concurrent readers. 2520 * function to insert in a way safe to concurrent readers.
2424 * The mutex protects against concurrent writers. 2521 * The mutex protects against concurrent writers.
2425 */ 2522 */
2523 mutex_lock(&module_mutex);
2524 if (find_module(mod->name)) {
2525 err = -EEXIST;
2526 goto unlock;
2527 }
2528
2529 /* Find duplicate symbols */
2530 err = verify_export_symbols(mod);
2531 if (err < 0)
2532 goto unlock;
2533
2426 list_add_rcu(&mod->list, &modules); 2534 list_add_rcu(&mod->list, &modules);
2535 mutex_unlock(&module_mutex);
2427 2536
2428 err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL); 2537 err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
2429 if (err < 0) 2538 if (err < 0)
@@ -2432,6 +2541,7 @@ static noinline struct module *load_module(void __user *umod,
2432 err = mod_sysfs_setup(mod, mod->kp, mod->num_kp); 2541 err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
2433 if (err < 0) 2542 if (err < 0)
2434 goto unlink; 2543 goto unlink;
2544
2435 add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); 2545 add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
2436 add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); 2546 add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
2437 2547
@@ -2444,15 +2554,15 @@ static noinline struct module *load_module(void __user *umod,
2444 return mod; 2554 return mod;
2445 2555
2446 unlink: 2556 unlink:
2557 mutex_lock(&module_mutex);
2447 /* Unlink carefully: kallsyms could be walking list. */ 2558 /* Unlink carefully: kallsyms could be walking list. */
2448 list_del_rcu(&mod->list); 2559 list_del_rcu(&mod->list);
2560 unlock:
2561 mutex_unlock(&module_mutex);
2449 synchronize_sched(); 2562 synchronize_sched();
2450 module_arch_cleanup(mod); 2563 module_arch_cleanup(mod);
2451 cleanup: 2564 cleanup:
2452 free_modinfo(mod); 2565 free_modinfo(mod);
2453 kobject_del(&mod->mkobj.kobj);
2454 kobject_put(&mod->mkobj.kobj);
2455 free_unload:
2456 module_unload_free(mod); 2566 module_unload_free(mod);
2457#if defined(CONFIG_MODULE_UNLOAD) 2567#if defined(CONFIG_MODULE_UNLOAD)
2458 free_percpu(mod->refptr); 2568 free_percpu(mod->refptr);
@@ -2463,7 +2573,7 @@ static noinline struct module *load_module(void __user *umod,
2463 module_free(mod, mod->module_core); 2573 module_free(mod, mod->module_core);
2464 /* mod will be freed with core. Don't access it beyond this line! */ 2574 /* mod will be freed with core. Don't access it beyond this line! */
2465 free_percpu: 2575 free_percpu:
2466 percpu_modfree(mod); 2576 free_percpu(percpu);
2467 free_mod: 2577 free_mod:
2468 kfree(args); 2578 kfree(args);
2469 kfree(strmap); 2579 kfree(strmap);
@@ -2499,19 +2609,10 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
2499 if (!capable(CAP_SYS_MODULE) || modules_disabled) 2609 if (!capable(CAP_SYS_MODULE) || modules_disabled)
2500 return -EPERM; 2610 return -EPERM;
2501 2611
2502 /* Only one module load at a time, please */
2503 if (mutex_lock_interruptible(&module_mutex) != 0)
2504 return -EINTR;
2505
2506 /* Do all the hard work */ 2612 /* Do all the hard work */
2507 mod = load_module(umod, len, uargs); 2613 mod = load_module(umod, len, uargs);
2508 if (IS_ERR(mod)) { 2614 if (IS_ERR(mod))
2509 mutex_unlock(&module_mutex);
2510 return PTR_ERR(mod); 2615 return PTR_ERR(mod);
2511 }
2512
2513 /* Drop lock so they can recurse */
2514 mutex_unlock(&module_mutex);
2515 2616
2516 blocking_notifier_call_chain(&module_notify_list, 2617 blocking_notifier_call_chain(&module_notify_list,
2517 MODULE_STATE_COMING, mod); 2618 MODULE_STATE_COMING, mod);
@@ -2528,9 +2629,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
2528 module_put(mod); 2629 module_put(mod);
2529 blocking_notifier_call_chain(&module_notify_list, 2630 blocking_notifier_call_chain(&module_notify_list,
2530 MODULE_STATE_GOING, mod); 2631 MODULE_STATE_GOING, mod);
2531 mutex_lock(&module_mutex);
2532 free_module(mod); 2632 free_module(mod);
2533 mutex_unlock(&module_mutex);
2534 wake_up(&module_wq); 2633 wake_up(&module_wq);
2535 return ret; 2634 return ret;
2536 } 2635 }
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index bd7ce8ca5bb9..31d6afe92594 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -283,14 +283,15 @@ ctx_group_list(struct perf_event *event, struct perf_event_context *ctx)
283static void 283static void
284list_add_event(struct perf_event *event, struct perf_event_context *ctx) 284list_add_event(struct perf_event *event, struct perf_event_context *ctx)
285{ 285{
286 struct perf_event *group_leader = event->group_leader; 286 WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT);
287 event->attach_state |= PERF_ATTACH_CONTEXT;
287 288
288 /* 289 /*
289 * Depending on whether it is a standalone or sibling event, 290 * If we're a stand alone event or group leader, we go to the context
290 * add it straight to the context's event list, or to the group 291 * list, group events are kept attached to the group so that
291 * leader's sibling list: 292 * perf_group_detach can, at all times, locate all siblings.
292 */ 293 */
293 if (group_leader == event) { 294 if (event->group_leader == event) {
294 struct list_head *list; 295 struct list_head *list;
295 296
296 if (is_software_event(event)) 297 if (is_software_event(event))
@@ -298,13 +299,6 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
298 299
299 list = ctx_group_list(event, ctx); 300 list = ctx_group_list(event, ctx);
300 list_add_tail(&event->group_entry, list); 301 list_add_tail(&event->group_entry, list);
301 } else {
302 if (group_leader->group_flags & PERF_GROUP_SOFTWARE &&
303 !is_software_event(event))
304 group_leader->group_flags &= ~PERF_GROUP_SOFTWARE;
305
306 list_add_tail(&event->group_entry, &group_leader->sibling_list);
307 group_leader->nr_siblings++;
308 } 302 }
309 303
310 list_add_rcu(&event->event_entry, &ctx->event_list); 304 list_add_rcu(&event->event_entry, &ctx->event_list);
@@ -313,6 +307,24 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
313 ctx->nr_stat++; 307 ctx->nr_stat++;
314} 308}
315 309
310static void perf_group_attach(struct perf_event *event)
311{
312 struct perf_event *group_leader = event->group_leader;
313
314 WARN_ON_ONCE(event->attach_state & PERF_ATTACH_GROUP);
315 event->attach_state |= PERF_ATTACH_GROUP;
316
317 if (group_leader == event)
318 return;
319
320 if (group_leader->group_flags & PERF_GROUP_SOFTWARE &&
321 !is_software_event(event))
322 group_leader->group_flags &= ~PERF_GROUP_SOFTWARE;
323
324 list_add_tail(&event->group_entry, &group_leader->sibling_list);
325 group_leader->nr_siblings++;
326}
327
316/* 328/*
317 * Remove a event from the lists for its context. 329 * Remove a event from the lists for its context.
318 * Must be called with ctx->mutex and ctx->lock held. 330 * Must be called with ctx->mutex and ctx->lock held.
@@ -320,17 +332,22 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
320static void 332static void
321list_del_event(struct perf_event *event, struct perf_event_context *ctx) 333list_del_event(struct perf_event *event, struct perf_event_context *ctx)
322{ 334{
323 if (list_empty(&event->group_entry)) 335 /*
336 * We can have double detach due to exit/hot-unplug + close.
337 */
338 if (!(event->attach_state & PERF_ATTACH_CONTEXT))
324 return; 339 return;
340
341 event->attach_state &= ~PERF_ATTACH_CONTEXT;
342
325 ctx->nr_events--; 343 ctx->nr_events--;
326 if (event->attr.inherit_stat) 344 if (event->attr.inherit_stat)
327 ctx->nr_stat--; 345 ctx->nr_stat--;
328 346
329 list_del_init(&event->group_entry);
330 list_del_rcu(&event->event_entry); 347 list_del_rcu(&event->event_entry);
331 348
332 if (event->group_leader != event) 349 if (event->group_leader == event)
333 event->group_leader->nr_siblings--; 350 list_del_init(&event->group_entry);
334 351
335 update_group_times(event); 352 update_group_times(event);
336 353
@@ -345,21 +362,39 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
345 event->state = PERF_EVENT_STATE_OFF; 362 event->state = PERF_EVENT_STATE_OFF;
346} 363}
347 364
348static void 365static void perf_group_detach(struct perf_event *event)
349perf_destroy_group(struct perf_event *event, struct perf_event_context *ctx)
350{ 366{
351 struct perf_event *sibling, *tmp; 367 struct perf_event *sibling, *tmp;
368 struct list_head *list = NULL;
369
370 /*
371 * We can have double detach due to exit/hot-unplug + close.
372 */
373 if (!(event->attach_state & PERF_ATTACH_GROUP))
374 return;
375
376 event->attach_state &= ~PERF_ATTACH_GROUP;
377
378 /*
379 * If this is a sibling, remove it from its group.
380 */
381 if (event->group_leader != event) {
382 list_del_init(&event->group_entry);
383 event->group_leader->nr_siblings--;
384 return;
385 }
386
387 if (!list_empty(&event->group_entry))
388 list = &event->group_entry;
352 389
353 /* 390 /*
354 * If this was a group event with sibling events then 391 * If this was a group event with sibling events then
355 * upgrade the siblings to singleton events by adding them 392 * upgrade the siblings to singleton events by adding them
356 * to the context list directly: 393 * to whatever list we are on.
357 */ 394 */
358 list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) { 395 list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) {
359 struct list_head *list; 396 if (list)
360 397 list_move_tail(&sibling->group_entry, list);
361 list = ctx_group_list(event, ctx);
362 list_move_tail(&sibling->group_entry, list);
363 sibling->group_leader = sibling; 398 sibling->group_leader = sibling;
364 399
365 /* Inherit group flags from the previous leader */ 400 /* Inherit group flags from the previous leader */
@@ -652,8 +687,11 @@ group_sched_in(struct perf_event *group_event,
652 if (txn) 687 if (txn)
653 pmu->start_txn(pmu); 688 pmu->start_txn(pmu);
654 689
655 if (event_sched_in(group_event, cpuctx, ctx)) 690 if (event_sched_in(group_event, cpuctx, ctx)) {
691 if (txn)
692 pmu->cancel_txn(pmu);
656 return -EAGAIN; 693 return -EAGAIN;
694 }
657 695
658 /* 696 /*
659 * Schedule in siblings as one group (if any): 697 * Schedule in siblings as one group (if any):
@@ -675,9 +713,6 @@ group_sched_in(struct perf_event *group_event,
675 } 713 }
676 714
677group_error: 715group_error:
678 if (txn)
679 pmu->cancel_txn(pmu);
680
681 /* 716 /*
682 * Groups can be scheduled in as one unit only, so undo any 717 * Groups can be scheduled in as one unit only, so undo any
683 * partial group before returning: 718 * partial group before returning:
@@ -689,6 +724,9 @@ group_error:
689 } 724 }
690 event_sched_out(group_event, cpuctx, ctx); 725 event_sched_out(group_event, cpuctx, ctx);
691 726
727 if (txn)
728 pmu->cancel_txn(pmu);
729
692 return -EAGAIN; 730 return -EAGAIN;
693} 731}
694 732
@@ -727,6 +765,7 @@ static void add_event_to_ctx(struct perf_event *event,
727 struct perf_event_context *ctx) 765 struct perf_event_context *ctx)
728{ 766{
729 list_add_event(event, ctx); 767 list_add_event(event, ctx);
768 perf_group_attach(event);
730 event->tstamp_enabled = ctx->time; 769 event->tstamp_enabled = ctx->time;
731 event->tstamp_running = ctx->time; 770 event->tstamp_running = ctx->time;
732 event->tstamp_stopped = ctx->time; 771 event->tstamp_stopped = ctx->time;
@@ -1841,6 +1880,7 @@ static void free_event_rcu(struct rcu_head *head)
1841} 1880}
1842 1881
1843static void perf_pending_sync(struct perf_event *event); 1882static void perf_pending_sync(struct perf_event *event);
1883static void perf_mmap_data_put(struct perf_mmap_data *data);
1844 1884
1845static void free_event(struct perf_event *event) 1885static void free_event(struct perf_event *event)
1846{ 1886{
@@ -1856,9 +1896,9 @@ static void free_event(struct perf_event *event)
1856 atomic_dec(&nr_task_events); 1896 atomic_dec(&nr_task_events);
1857 } 1897 }
1858 1898
1859 if (event->output) { 1899 if (event->data) {
1860 fput(event->output->filp); 1900 perf_mmap_data_put(event->data);
1861 event->output = NULL; 1901 event->data = NULL;
1862 } 1902 }
1863 1903
1864 if (event->destroy) 1904 if (event->destroy)
@@ -1893,8 +1933,8 @@ int perf_event_release_kernel(struct perf_event *event)
1893 */ 1933 */
1894 mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING); 1934 mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING);
1895 raw_spin_lock_irq(&ctx->lock); 1935 raw_spin_lock_irq(&ctx->lock);
1936 perf_group_detach(event);
1896 list_del_event(event, ctx); 1937 list_del_event(event, ctx);
1897 perf_destroy_group(event, ctx);
1898 raw_spin_unlock_irq(&ctx->lock); 1938 raw_spin_unlock_irq(&ctx->lock);
1899 mutex_unlock(&ctx->mutex); 1939 mutex_unlock(&ctx->mutex);
1900 1940
@@ -2175,7 +2215,27 @@ unlock:
2175 return ret; 2215 return ret;
2176} 2216}
2177 2217
2178static int perf_event_set_output(struct perf_event *event, int output_fd); 2218static const struct file_operations perf_fops;
2219
2220static struct perf_event *perf_fget_light(int fd, int *fput_needed)
2221{
2222 struct file *file;
2223
2224 file = fget_light(fd, fput_needed);
2225 if (!file)
2226 return ERR_PTR(-EBADF);
2227
2228 if (file->f_op != &perf_fops) {
2229 fput_light(file, *fput_needed);
2230 *fput_needed = 0;
2231 return ERR_PTR(-EBADF);
2232 }
2233
2234 return file->private_data;
2235}
2236
2237static int perf_event_set_output(struct perf_event *event,
2238 struct perf_event *output_event);
2179static int perf_event_set_filter(struct perf_event *event, void __user *arg); 2239static int perf_event_set_filter(struct perf_event *event, void __user *arg);
2180 2240
2181static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 2241static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -2202,7 +2262,23 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2202 return perf_event_period(event, (u64 __user *)arg); 2262 return perf_event_period(event, (u64 __user *)arg);
2203 2263
2204 case PERF_EVENT_IOC_SET_OUTPUT: 2264 case PERF_EVENT_IOC_SET_OUTPUT:
2205 return perf_event_set_output(event, arg); 2265 {
2266 struct perf_event *output_event = NULL;
2267 int fput_needed = 0;
2268 int ret;
2269
2270 if (arg != -1) {
2271 output_event = perf_fget_light(arg, &fput_needed);
2272 if (IS_ERR(output_event))
2273 return PTR_ERR(output_event);
2274 }
2275
2276 ret = perf_event_set_output(event, output_event);
2277 if (output_event)
2278 fput_light(output_event->filp, fput_needed);
2279
2280 return ret;
2281 }
2206 2282
2207 case PERF_EVENT_IOC_SET_FILTER: 2283 case PERF_EVENT_IOC_SET_FILTER:
2208 return perf_event_set_filter(event, (void __user *)arg); 2284 return perf_event_set_filter(event, (void __user *)arg);
@@ -2335,8 +2411,6 @@ perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
2335 unsigned long size; 2411 unsigned long size;
2336 int i; 2412 int i;
2337 2413
2338 WARN_ON(atomic_read(&event->mmap_count));
2339
2340 size = sizeof(struct perf_mmap_data); 2414 size = sizeof(struct perf_mmap_data);
2341 size += nr_pages * sizeof(void *); 2415 size += nr_pages * sizeof(void *);
2342 2416
@@ -2452,8 +2526,6 @@ perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
2452 unsigned long size; 2526 unsigned long size;
2453 void *all_buf; 2527 void *all_buf;
2454 2528
2455 WARN_ON(atomic_read(&event->mmap_count));
2456
2457 size = sizeof(struct perf_mmap_data); 2529 size = sizeof(struct perf_mmap_data);
2458 size += sizeof(void *); 2530 size += sizeof(void *);
2459 2531
@@ -2536,7 +2608,7 @@ perf_mmap_data_init(struct perf_event *event, struct perf_mmap_data *data)
2536 if (!data->watermark) 2608 if (!data->watermark)
2537 data->watermark = max_size / 2; 2609 data->watermark = max_size / 2;
2538 2610
2539 2611 atomic_set(&data->refcount, 1);
2540 rcu_assign_pointer(event->data, data); 2612 rcu_assign_pointer(event->data, data);
2541} 2613}
2542 2614
@@ -2548,13 +2620,26 @@ static void perf_mmap_data_free_rcu(struct rcu_head *rcu_head)
2548 perf_mmap_data_free(data); 2620 perf_mmap_data_free(data);
2549} 2621}
2550 2622
2551static void perf_mmap_data_release(struct perf_event *event) 2623static struct perf_mmap_data *perf_mmap_data_get(struct perf_event *event)
2552{ 2624{
2553 struct perf_mmap_data *data = event->data; 2625 struct perf_mmap_data *data;
2554 2626
2555 WARN_ON(atomic_read(&event->mmap_count)); 2627 rcu_read_lock();
2628 data = rcu_dereference(event->data);
2629 if (data) {
2630 if (!atomic_inc_not_zero(&data->refcount))
2631 data = NULL;
2632 }
2633 rcu_read_unlock();
2634
2635 return data;
2636}
2637
2638static void perf_mmap_data_put(struct perf_mmap_data *data)
2639{
2640 if (!atomic_dec_and_test(&data->refcount))
2641 return;
2556 2642
2557 rcu_assign_pointer(event->data, NULL);
2558 call_rcu(&data->rcu_head, perf_mmap_data_free_rcu); 2643 call_rcu(&data->rcu_head, perf_mmap_data_free_rcu);
2559} 2644}
2560 2645
@@ -2569,15 +2654,18 @@ static void perf_mmap_close(struct vm_area_struct *vma)
2569{ 2654{
2570 struct perf_event *event = vma->vm_file->private_data; 2655 struct perf_event *event = vma->vm_file->private_data;
2571 2656
2572 WARN_ON_ONCE(event->ctx->parent_ctx);
2573 if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) { 2657 if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) {
2574 unsigned long size = perf_data_size(event->data); 2658 unsigned long size = perf_data_size(event->data);
2575 struct user_struct *user = current_user(); 2659 struct user_struct *user = event->mmap_user;
2660 struct perf_mmap_data *data = event->data;
2576 2661
2577 atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm); 2662 atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm);
2578 vma->vm_mm->locked_vm -= event->data->nr_locked; 2663 vma->vm_mm->locked_vm -= event->mmap_locked;
2579 perf_mmap_data_release(event); 2664 rcu_assign_pointer(event->data, NULL);
2580 mutex_unlock(&event->mmap_mutex); 2665 mutex_unlock(&event->mmap_mutex);
2666
2667 perf_mmap_data_put(data);
2668 free_uid(user);
2581 } 2669 }
2582} 2670}
2583 2671
@@ -2629,13 +2717,10 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
2629 2717
2630 WARN_ON_ONCE(event->ctx->parent_ctx); 2718 WARN_ON_ONCE(event->ctx->parent_ctx);
2631 mutex_lock(&event->mmap_mutex); 2719 mutex_lock(&event->mmap_mutex);
2632 if (event->output) { 2720 if (event->data) {
2633 ret = -EINVAL; 2721 if (event->data->nr_pages == nr_pages)
2634 goto unlock; 2722 atomic_inc(&event->data->refcount);
2635 } 2723 else
2636
2637 if (atomic_inc_not_zero(&event->mmap_count)) {
2638 if (nr_pages != event->data->nr_pages)
2639 ret = -EINVAL; 2724 ret = -EINVAL;
2640 goto unlock; 2725 goto unlock;
2641 } 2726 }
@@ -2667,21 +2752,23 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
2667 WARN_ON(event->data); 2752 WARN_ON(event->data);
2668 2753
2669 data = perf_mmap_data_alloc(event, nr_pages); 2754 data = perf_mmap_data_alloc(event, nr_pages);
2670 ret = -ENOMEM; 2755 if (!data) {
2671 if (!data) 2756 ret = -ENOMEM;
2672 goto unlock; 2757 goto unlock;
2758 }
2673 2759
2674 ret = 0;
2675 perf_mmap_data_init(event, data); 2760 perf_mmap_data_init(event, data);
2676
2677 atomic_set(&event->mmap_count, 1);
2678 atomic_long_add(user_extra, &user->locked_vm);
2679 vma->vm_mm->locked_vm += extra;
2680 event->data->nr_locked = extra;
2681 if (vma->vm_flags & VM_WRITE) 2761 if (vma->vm_flags & VM_WRITE)
2682 event->data->writable = 1; 2762 event->data->writable = 1;
2683 2763
2764 atomic_long_add(user_extra, &user->locked_vm);
2765 event->mmap_locked = extra;
2766 event->mmap_user = get_current_user();
2767 vma->vm_mm->locked_vm += event->mmap_locked;
2768
2684unlock: 2769unlock:
2770 if (!ret)
2771 atomic_inc(&event->mmap_count);
2685 mutex_unlock(&event->mmap_mutex); 2772 mutex_unlock(&event->mmap_mutex);
2686 2773
2687 vma->vm_flags |= VM_RESERVED; 2774 vma->vm_flags |= VM_RESERVED;
@@ -2977,6 +3064,7 @@ __always_inline void perf_output_copy(struct perf_output_handle *handle,
2977 3064
2978 len -= size; 3065 len -= size;
2979 handle->addr += size; 3066 handle->addr += size;
3067 buf += size;
2980 handle->size -= size; 3068 handle->size -= size;
2981 if (!handle->size) { 3069 if (!handle->size) {
2982 struct perf_mmap_data *data = handle->data; 3070 struct perf_mmap_data *data = handle->data;
@@ -2993,7 +3081,6 @@ int perf_output_begin(struct perf_output_handle *handle,
2993 struct perf_event *event, unsigned int size, 3081 struct perf_event *event, unsigned int size,
2994 int nmi, int sample) 3082 int nmi, int sample)
2995{ 3083{
2996 struct perf_event *output_event;
2997 struct perf_mmap_data *data; 3084 struct perf_mmap_data *data;
2998 unsigned long tail, offset, head; 3085 unsigned long tail, offset, head;
2999 int have_lost; 3086 int have_lost;
@@ -3010,10 +3097,6 @@ int perf_output_begin(struct perf_output_handle *handle,
3010 if (event->parent) 3097 if (event->parent)
3011 event = event->parent; 3098 event = event->parent;
3012 3099
3013 output_event = rcu_dereference(event->output);
3014 if (output_event)
3015 event = output_event;
3016
3017 data = rcu_dereference(event->data); 3100 data = rcu_dereference(event->data);
3018 if (!data) 3101 if (!data)
3019 goto out; 3102 goto out;
@@ -3972,13 +4055,6 @@ static void perf_swevent_overflow(struct perf_event *event, u64 overflow,
3972 } 4055 }
3973} 4056}
3974 4057
3975static void perf_swevent_unthrottle(struct perf_event *event)
3976{
3977 /*
3978 * Nothing to do, we already reset hwc->interrupts.
3979 */
3980}
3981
3982static void perf_swevent_add(struct perf_event *event, u64 nr, 4058static void perf_swevent_add(struct perf_event *event, u64 nr,
3983 int nmi, struct perf_sample_data *data, 4059 int nmi, struct perf_sample_data *data,
3984 struct pt_regs *regs) 4060 struct pt_regs *regs)
@@ -4193,11 +4269,22 @@ static void perf_swevent_disable(struct perf_event *event)
4193 hlist_del_rcu(&event->hlist_entry); 4269 hlist_del_rcu(&event->hlist_entry);
4194} 4270}
4195 4271
4272static void perf_swevent_void(struct perf_event *event)
4273{
4274}
4275
4276static int perf_swevent_int(struct perf_event *event)
4277{
4278 return 0;
4279}
4280
4196static const struct pmu perf_ops_generic = { 4281static const struct pmu perf_ops_generic = {
4197 .enable = perf_swevent_enable, 4282 .enable = perf_swevent_enable,
4198 .disable = perf_swevent_disable, 4283 .disable = perf_swevent_disable,
4284 .start = perf_swevent_int,
4285 .stop = perf_swevent_void,
4199 .read = perf_swevent_read, 4286 .read = perf_swevent_read,
4200 .unthrottle = perf_swevent_unthrottle, 4287 .unthrottle = perf_swevent_void, /* hwc->interrupts already reset */
4201}; 4288};
4202 4289
4203/* 4290/*
@@ -4478,8 +4565,10 @@ static int swevent_hlist_get(struct perf_event *event)
4478static const struct pmu perf_ops_tracepoint = { 4565static const struct pmu perf_ops_tracepoint = {
4479 .enable = perf_trace_enable, 4566 .enable = perf_trace_enable,
4480 .disable = perf_trace_disable, 4567 .disable = perf_trace_disable,
4568 .start = perf_swevent_int,
4569 .stop = perf_swevent_void,
4481 .read = perf_swevent_read, 4570 .read = perf_swevent_read,
4482 .unthrottle = perf_swevent_unthrottle, 4571 .unthrottle = perf_swevent_void,
4483}; 4572};
4484 4573
4485static int perf_tp_filter_match(struct perf_event *event, 4574static int perf_tp_filter_match(struct perf_event *event,
@@ -4912,39 +5001,17 @@ err_size:
4912 goto out; 5001 goto out;
4913} 5002}
4914 5003
4915static int perf_event_set_output(struct perf_event *event, int output_fd) 5004static int
5005perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
4916{ 5006{
4917 struct perf_event *output_event = NULL; 5007 struct perf_mmap_data *data = NULL, *old_data = NULL;
4918 struct file *output_file = NULL;
4919 struct perf_event *old_output;
4920 int fput_needed = 0;
4921 int ret = -EINVAL; 5008 int ret = -EINVAL;
4922 5009
4923 /* 5010 if (!output_event)
4924 * Don't allow output of inherited per-task events. This would
4925 * create performance issues due to cross cpu access.
4926 */
4927 if (event->cpu == -1 && event->attr.inherit)
4928 return -EINVAL;
4929
4930 if (!output_fd)
4931 goto set; 5011 goto set;
4932 5012
4933 output_file = fget_light(output_fd, &fput_needed); 5013 /* don't allow circular references */
4934 if (!output_file) 5014 if (event == output_event)
4935 return -EBADF;
4936
4937 if (output_file->f_op != &perf_fops)
4938 goto out;
4939
4940 output_event = output_file->private_data;
4941
4942 /* Don't chain output fds */
4943 if (output_event->output)
4944 goto out;
4945
4946 /* Don't set an output fd when we already have an output channel */
4947 if (event->data)
4948 goto out; 5015 goto out;
4949 5016
4950 /* 5017 /*
@@ -4959,26 +5026,28 @@ static int perf_event_set_output(struct perf_event *event, int output_fd)
4959 if (output_event->cpu == -1 && output_event->ctx != event->ctx) 5026 if (output_event->cpu == -1 && output_event->ctx != event->ctx)
4960 goto out; 5027 goto out;
4961 5028
4962 atomic_long_inc(&output_file->f_count);
4963
4964set: 5029set:
4965 mutex_lock(&event->mmap_mutex); 5030 mutex_lock(&event->mmap_mutex);
4966 old_output = event->output; 5031 /* Can't redirect output if we've got an active mmap() */
4967 rcu_assign_pointer(event->output, output_event); 5032 if (atomic_read(&event->mmap_count))
4968 mutex_unlock(&event->mmap_mutex); 5033 goto unlock;
4969 5034
4970 if (old_output) { 5035 if (output_event) {
4971 /* 5036 /* get the buffer we want to redirect to */
4972 * we need to make sure no existing perf_output_*() 5037 data = perf_mmap_data_get(output_event);
4973 * is still referencing this event. 5038 if (!data)
4974 */ 5039 goto unlock;
4975 synchronize_rcu();
4976 fput(old_output->filp);
4977 } 5040 }
4978 5041
5042 old_data = event->data;
5043 rcu_assign_pointer(event->data, data);
4979 ret = 0; 5044 ret = 0;
5045unlock:
5046 mutex_unlock(&event->mmap_mutex);
5047
5048 if (old_data)
5049 perf_mmap_data_put(old_data);
4980out: 5050out:
4981 fput_light(output_file, fput_needed);
4982 return ret; 5051 return ret;
4983} 5052}
4984 5053
@@ -4994,7 +5063,7 @@ SYSCALL_DEFINE5(perf_event_open,
4994 struct perf_event_attr __user *, attr_uptr, 5063 struct perf_event_attr __user *, attr_uptr,
4995 pid_t, pid, int, cpu, int, group_fd, unsigned long, flags) 5064 pid_t, pid, int, cpu, int, group_fd, unsigned long, flags)
4996{ 5065{
4997 struct perf_event *event, *group_leader; 5066 struct perf_event *event, *group_leader = NULL, *output_event = NULL;
4998 struct perf_event_attr attr; 5067 struct perf_event_attr attr;
4999 struct perf_event_context *ctx; 5068 struct perf_event_context *ctx;
5000 struct file *event_file = NULL; 5069 struct file *event_file = NULL;
@@ -5034,19 +5103,25 @@ SYSCALL_DEFINE5(perf_event_open,
5034 goto err_fd; 5103 goto err_fd;
5035 } 5104 }
5036 5105
5106 if (group_fd != -1) {
5107 group_leader = perf_fget_light(group_fd, &fput_needed);
5108 if (IS_ERR(group_leader)) {
5109 err = PTR_ERR(group_leader);
5110 goto err_put_context;
5111 }
5112 group_file = group_leader->filp;
5113 if (flags & PERF_FLAG_FD_OUTPUT)
5114 output_event = group_leader;
5115 if (flags & PERF_FLAG_FD_NO_GROUP)
5116 group_leader = NULL;
5117 }
5118
5037 /* 5119 /*
5038 * Look up the group leader (we will attach this event to it): 5120 * Look up the group leader (we will attach this event to it):
5039 */ 5121 */
5040 group_leader = NULL; 5122 if (group_leader) {
5041 if (group_fd != -1 && !(flags & PERF_FLAG_FD_NO_GROUP)) {
5042 err = -EINVAL; 5123 err = -EINVAL;
5043 group_file = fget_light(group_fd, &fput_needed);
5044 if (!group_file)
5045 goto err_put_context;
5046 if (group_file->f_op != &perf_fops)
5047 goto err_put_context;
5048 5124
5049 group_leader = group_file->private_data;
5050 /* 5125 /*
5051 * Do not allow a recursive hierarchy (this new sibling 5126 * Do not allow a recursive hierarchy (this new sibling
5052 * becoming part of another group-sibling): 5127 * becoming part of another group-sibling):
@@ -5068,9 +5143,16 @@ SYSCALL_DEFINE5(perf_event_open,
5068 5143
5069 event = perf_event_alloc(&attr, cpu, ctx, group_leader, 5144 event = perf_event_alloc(&attr, cpu, ctx, group_leader,
5070 NULL, NULL, GFP_KERNEL); 5145 NULL, NULL, GFP_KERNEL);
5071 err = PTR_ERR(event); 5146 if (IS_ERR(event)) {
5072 if (IS_ERR(event)) 5147 err = PTR_ERR(event);
5073 goto err_put_context; 5148 goto err_put_context;
5149 }
5150
5151 if (output_event) {
5152 err = perf_event_set_output(event, output_event);
5153 if (err)
5154 goto err_free_put_context;
5155 }
5074 5156
5075 event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR); 5157 event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR);
5076 if (IS_ERR(event_file)) { 5158 if (IS_ERR(event_file)) {
@@ -5078,12 +5160,6 @@ SYSCALL_DEFINE5(perf_event_open,
5078 goto err_free_put_context; 5160 goto err_free_put_context;
5079 } 5161 }
5080 5162
5081 if (flags & PERF_FLAG_FD_OUTPUT) {
5082 err = perf_event_set_output(event, group_fd);
5083 if (err)
5084 goto err_fput_free_put_context;
5085 }
5086
5087 event->filp = event_file; 5163 event->filp = event_file;
5088 WARN_ON_ONCE(ctx->parent_ctx); 5164 WARN_ON_ONCE(ctx->parent_ctx);
5089 mutex_lock(&ctx->mutex); 5165 mutex_lock(&ctx->mutex);
@@ -5097,12 +5173,16 @@ SYSCALL_DEFINE5(perf_event_open,
5097 list_add_tail(&event->owner_entry, &current->perf_event_list); 5173 list_add_tail(&event->owner_entry, &current->perf_event_list);
5098 mutex_unlock(&current->perf_event_mutex); 5174 mutex_unlock(&current->perf_event_mutex);
5099 5175
5176 /*
5177 * Drop the reference on the group_event after placing the
5178 * new event on the sibling_list. This ensures destruction
5179 * of the group leader will find the pointer to itself in
5180 * perf_group_detach().
5181 */
5100 fput_light(group_file, fput_needed); 5182 fput_light(group_file, fput_needed);
5101 fd_install(event_fd, event_file); 5183 fd_install(event_fd, event_file);
5102 return event_fd; 5184 return event_fd;
5103 5185
5104err_fput_free_put_context:
5105 fput(event_file);
5106err_free_put_context: 5186err_free_put_context:
5107 free_event(event); 5187 free_event(event);
5108err_put_context: 5188err_put_context:
@@ -5420,6 +5500,7 @@ static void perf_free_event(struct perf_event *event,
5420 5500
5421 fput(parent->filp); 5501 fput(parent->filp);
5422 5502
5503 perf_group_detach(event);
5423 list_del_event(event, ctx); 5504 list_del_event(event, ctx);
5424 free_event(event); 5505 free_event(event);
5425} 5506}
diff --git a/kernel/sched.c b/kernel/sched.c
index d48408142503..f8b8996228dd 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -544,6 +544,8 @@ struct rq {
544 struct root_domain *rd; 544 struct root_domain *rd;
545 struct sched_domain *sd; 545 struct sched_domain *sd;
546 546
547 unsigned long cpu_power;
548
547 unsigned char idle_at_tick; 549 unsigned char idle_at_tick;
548 /* For active balancing */ 550 /* For active balancing */
549 int post_schedule; 551 int post_schedule;
@@ -1499,24 +1501,9 @@ static unsigned long target_load(int cpu, int type)
1499 return max(rq->cpu_load[type-1], total); 1501 return max(rq->cpu_load[type-1], total);
1500} 1502}
1501 1503
1502static struct sched_group *group_of(int cpu)
1503{
1504 struct sched_domain *sd = rcu_dereference_sched(cpu_rq(cpu)->sd);
1505
1506 if (!sd)
1507 return NULL;
1508
1509 return sd->groups;
1510}
1511
1512static unsigned long power_of(int cpu) 1504static unsigned long power_of(int cpu)
1513{ 1505{
1514 struct sched_group *group = group_of(cpu); 1506 return cpu_rq(cpu)->cpu_power;
1515
1516 if (!group)
1517 return SCHED_LOAD_SCALE;
1518
1519 return group->cpu_power;
1520} 1507}
1521 1508
1522static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd); 1509static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd);
@@ -1854,8 +1841,8 @@ static void dec_nr_running(struct rq *rq)
1854static void set_load_weight(struct task_struct *p) 1841static void set_load_weight(struct task_struct *p)
1855{ 1842{
1856 if (task_has_rt_policy(p)) { 1843 if (task_has_rt_policy(p)) {
1857 p->se.load.weight = prio_to_weight[0] * 2; 1844 p->se.load.weight = 0;
1858 p->se.load.inv_weight = prio_to_wmult[0] >> 1; 1845 p->se.load.inv_weight = WMULT_CONST;
1859 return; 1846 return;
1860 } 1847 }
1861 1848
@@ -7605,6 +7592,7 @@ void __init sched_init(void)
7605#ifdef CONFIG_SMP 7592#ifdef CONFIG_SMP
7606 rq->sd = NULL; 7593 rq->sd = NULL;
7607 rq->rd = NULL; 7594 rq->rd = NULL;
7595 rq->cpu_power = SCHED_LOAD_SCALE;
7608 rq->post_schedule = 0; 7596 rq->post_schedule = 0;
7609 rq->active_balance = 0; 7597 rq->active_balance = 0;
7610 rq->next_balance = jiffies; 7598 rq->next_balance = jiffies;
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 217e4a9393e4..eed35eded602 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -1225,7 +1225,6 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
1225 unsigned long this_load, load; 1225 unsigned long this_load, load;
1226 int idx, this_cpu, prev_cpu; 1226 int idx, this_cpu, prev_cpu;
1227 unsigned long tl_per_task; 1227 unsigned long tl_per_task;
1228 unsigned int imbalance;
1229 struct task_group *tg; 1228 struct task_group *tg;
1230 unsigned long weight; 1229 unsigned long weight;
1231 int balanced; 1230 int balanced;
@@ -1252,8 +1251,6 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
1252 tg = task_group(p); 1251 tg = task_group(p);
1253 weight = p->se.load.weight; 1252 weight = p->se.load.weight;
1254 1253
1255 imbalance = 100 + (sd->imbalance_pct - 100) / 2;
1256
1257 /* 1254 /*
1258 * In low-load situations, where prev_cpu is idle and this_cpu is idle 1255 * In low-load situations, where prev_cpu is idle and this_cpu is idle
1259 * due to the sync cause above having dropped this_load to 0, we'll 1256 * due to the sync cause above having dropped this_load to 0, we'll
@@ -1263,9 +1260,21 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
1263 * Otherwise check if either cpus are near enough in load to allow this 1260 * Otherwise check if either cpus are near enough in load to allow this
1264 * task to be woken on this_cpu. 1261 * task to be woken on this_cpu.
1265 */ 1262 */
1266 balanced = !this_load || 1263 if (this_load) {
1267 100*(this_load + effective_load(tg, this_cpu, weight, weight)) <= 1264 unsigned long this_eff_load, prev_eff_load;
1268 imbalance*(load + effective_load(tg, prev_cpu, 0, weight)); 1265
1266 this_eff_load = 100;
1267 this_eff_load *= power_of(prev_cpu);
1268 this_eff_load *= this_load +
1269 effective_load(tg, this_cpu, weight, weight);
1270
1271 prev_eff_load = 100 + (sd->imbalance_pct - 100) / 2;
1272 prev_eff_load *= power_of(this_cpu);
1273 prev_eff_load *= load + effective_load(tg, prev_cpu, 0, weight);
1274
1275 balanced = this_eff_load <= prev_eff_load;
1276 } else
1277 balanced = true;
1269 1278
1270 /* 1279 /*
1271 * If the currently running task will sleep within 1280 * If the currently running task will sleep within
@@ -2298,6 +2307,7 @@ static void update_cpu_power(struct sched_domain *sd, int cpu)
2298 if (!power) 2307 if (!power)
2299 power = 1; 2308 power = 1;
2300 2309
2310 cpu_rq(cpu)->cpu_power = power;
2301 sdg->cpu_power = power; 2311 sdg->cpu_power = power;
2302} 2312}
2303 2313
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 825e1126008f..07b4f1b1a73a 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -850,7 +850,7 @@ static __init int spawn_ksoftirqd(void)
850 void *cpu = (void *)(long)smp_processor_id(); 850 void *cpu = (void *)(long)smp_processor_id();
851 int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); 851 int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
852 852
853 BUG_ON(err == NOTIFY_BAD); 853 BUG_ON(err != NOTIFY_OK);
854 cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); 854 cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
855 register_cpu_notifier(&cpu_nfb); 855 register_cpu_notifier(&cpu_nfb);
856 return 0; 856 return 0;
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index b4e7431e7c78..70f8d90331e9 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -321,7 +321,7 @@ static int __cpuinit cpu_stop_cpu_callback(struct notifier_block *nfb,
321 321
322#ifdef CONFIG_HOTPLUG_CPU 322#ifdef CONFIG_HOTPLUG_CPU
323 case CPU_UP_CANCELED: 323 case CPU_UP_CANCELED:
324 case CPU_DEAD: 324 case CPU_POST_DEAD:
325 { 325 {
326 struct cpu_stop_work *work; 326 struct cpu_stop_work *work;
327 327
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 997080f00e0b..d24f761f4876 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1471,12 +1471,12 @@ static struct ctl_table fs_table[] = {
1471 }, 1471 },
1472#endif 1472#endif
1473 { 1473 {
1474 .procname = "pipe-max-pages", 1474 .procname = "pipe-max-size",
1475 .data = &pipe_max_pages, 1475 .data = &pipe_max_size,
1476 .maxlen = sizeof(int), 1476 .maxlen = sizeof(int),
1477 .mode = 0644, 1477 .mode = 0644,
1478 .proc_handler = &proc_dointvec_minmax, 1478 .proc_handler = &pipe_proc_fn,
1479 .extra1 = &two, 1479 .extra1 = &pipe_min_size,
1480 }, 1480 },
1481/* 1481/*
1482 * NOTE: do not add new entries to this table unless you have read 1482 * NOTE: do not add new entries to this table unless you have read
diff --git a/kernel/timer.c b/kernel/timer.c
index 2454172a80d3..ee305c8d4e18 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1717,7 +1717,7 @@ void __init init_timers(void)
1717 1717
1718 init_timer_stats(); 1718 init_timer_stats();
1719 1719
1720 BUG_ON(err == NOTIFY_BAD); 1720 BUG_ON(err != NOTIFY_OK);
1721 register_cpu_notifier(&timers_nb); 1721 register_cpu_notifier(&timers_nb);
1722 open_softirq(TIMER_SOFTIRQ, run_timer_softirq); 1722 open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
1723} 1723}
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 36ea2b65dcdc..638711c17504 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -842,6 +842,7 @@ static void blk_add_trace_split(void *ignore,
842 842
843/** 843/**
844 * blk_add_trace_remap - Add a trace for a remap operation 844 * blk_add_trace_remap - Add a trace for a remap operation
845 * @ignore: trace callback data parameter (not used)
845 * @q: queue the io is for 846 * @q: queue the io is for
846 * @bio: the source bio 847 * @bio: the source bio
847 * @dev: target device 848 * @dev: target device
@@ -873,6 +874,7 @@ static void blk_add_trace_remap(void *ignore,
873 874
874/** 875/**
875 * blk_add_trace_rq_remap - Add a trace for a request-remap operation 876 * blk_add_trace_rq_remap - Add a trace for a request-remap operation
877 * @ignore: trace callback data parameter (not used)
876 * @q: queue the io is for 878 * @q: queue the io is for
877 * @rq: the source request 879 * @rq: the source request
878 * @dev: target device 880 * @dev: target device
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
index cb6f365016e4..e6f65887842c 100644
--- a/kernel/trace/trace_event_perf.c
+++ b/kernel/trace/trace_event_perf.c
@@ -116,7 +116,7 @@ int perf_trace_enable(struct perf_event *p_event)
116 if (WARN_ON_ONCE(!list)) 116 if (WARN_ON_ONCE(!list))
117 return -EINVAL; 117 return -EINVAL;
118 118
119 list = per_cpu_ptr(list, smp_processor_id()); 119 list = this_cpu_ptr(list);
120 hlist_add_head_rcu(&p_event->hlist_entry, list); 120 hlist_add_head_rcu(&p_event->hlist_entry, list);
121 121
122 return 0; 122 return 0;
@@ -132,8 +132,9 @@ void perf_trace_destroy(struct perf_event *p_event)
132 struct ftrace_event_call *tp_event = p_event->tp_event; 132 struct ftrace_event_call *tp_event = p_event->tp_event;
133 int i; 133 int i;
134 134
135 mutex_lock(&event_mutex);
135 if (--tp_event->perf_refcount > 0) 136 if (--tp_event->perf_refcount > 0)
136 return; 137 goto out;
137 138
138 if (tp_event->class->reg) 139 if (tp_event->class->reg)
139 tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER); 140 tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER);
@@ -142,6 +143,12 @@ void perf_trace_destroy(struct perf_event *p_event)
142 tp_event->class->perf_probe, 143 tp_event->class->perf_probe,
143 tp_event); 144 tp_event);
144 145
146 /*
147 * Ensure our callback won't be called anymore. See
148 * tracepoint_probe_unregister() and __DO_TRACE().
149 */
150 synchronize_sched();
151
145 free_percpu(tp_event->perf_events); 152 free_percpu(tp_event->perf_events);
146 tp_event->perf_events = NULL; 153 tp_event->perf_events = NULL;
147 154
@@ -151,6 +158,8 @@ void perf_trace_destroy(struct perf_event *p_event)
151 perf_trace_buf[i] = NULL; 158 perf_trace_buf[i] = NULL;
152 } 159 }
153 } 160 }
161out:
162 mutex_unlock(&event_mutex);
154} 163}
155 164
156__kprobes void *perf_trace_buf_prepare(int size, unsigned short type, 165__kprobes void *perf_trace_buf_prepare(int size, unsigned short type,
@@ -169,7 +178,7 @@ __kprobes void *perf_trace_buf_prepare(int size, unsigned short type,
169 if (*rctxp < 0) 178 if (*rctxp < 0)
170 return NULL; 179 return NULL;
171 180
172 raw_data = per_cpu_ptr(perf_trace_buf[*rctxp], smp_processor_id()); 181 raw_data = this_cpu_ptr(perf_trace_buf[*rctxp]);
173 182
174 /* zero the dead bytes from align to not leak stack to user */ 183 /* zero the dead bytes from align to not leak stack to user */
175 memset(&raw_data[size - sizeof(u64)], 0, sizeof(u64)); 184 memset(&raw_data[size - sizeof(u64)], 0, sizeof(u64));
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index faf7cefd15da..f52b5f50299d 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1359,7 +1359,7 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
1359 for (i = 0; i < tp->nr_args; i++) 1359 for (i = 0; i < tp->nr_args; i++)
1360 call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset); 1360 call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
1361 1361
1362 head = per_cpu_ptr(call->perf_events, smp_processor_id()); 1362 head = this_cpu_ptr(call->perf_events);
1363 perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head); 1363 perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head);
1364} 1364}
1365 1365
@@ -1392,7 +1392,7 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
1392 for (i = 0; i < tp->nr_args; i++) 1392 for (i = 0; i < tp->nr_args; i++)
1393 call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset); 1393 call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
1394 1394
1395 head = per_cpu_ptr(call->perf_events, smp_processor_id()); 1395 head = this_cpu_ptr(call->perf_events);
1396 perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head); 1396 perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head);
1397} 1397}
1398 1398
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index d2c859cec9ea..34e35804304b 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -519,7 +519,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
519 syscall_get_arguments(current, regs, 0, sys_data->nb_args, 519 syscall_get_arguments(current, regs, 0, sys_data->nb_args,
520 (unsigned long *)&rec->args); 520 (unsigned long *)&rec->args);
521 521
522 head = per_cpu_ptr(sys_data->enter_event->perf_events, smp_processor_id()); 522 head = this_cpu_ptr(sys_data->enter_event->perf_events);
523 perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head); 523 perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head);
524} 524}
525 525
@@ -595,7 +595,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
595 rec->nr = syscall_nr; 595 rec->nr = syscall_nr;
596 rec->ret = syscall_get_return_value(current, regs); 596 rec->ret = syscall_get_return_value(current, regs);
597 597
598 head = per_cpu_ptr(sys_data->exit_event->perf_events, smp_processor_id()); 598 head = this_cpu_ptr(sys_data->exit_event->perf_events);
599 perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head); 599 perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head);
600} 600}
601 601
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
index 9087d71537dd..250ed11d3ed2 100644
--- a/lib/atomic64_test.c
+++ b/lib/atomic64_test.c
@@ -113,7 +113,8 @@ static __init int test_atomic64(void)
113 r += one; 113 r += one;
114 BUG_ON(v.counter != r); 114 BUG_ON(v.counter != r);
115 115
116#if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H) 116#if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || \
117 defined(CONFIG_S390) || defined(_ASM_GENERIC_ATOMIC64_H)
117 INIT(onestwos); 118 INIT(onestwos);
118 BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1)); 119 BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1));
119 r -= one; 120 r -= one;
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 59c15511d58a..b93579504dfa 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -83,6 +83,7 @@ out:
83 return ret; 83 return ret;
84} 84}
85 85
86#ifdef CONFIG_NET
86static int kobj_bcast_filter(struct sock *dsk, struct sk_buff *skb, void *data) 87static int kobj_bcast_filter(struct sock *dsk, struct sk_buff *skb, void *data)
87{ 88{
88 struct kobject *kobj = data; 89 struct kobject *kobj = data;
@@ -98,6 +99,7 @@ static int kobj_bcast_filter(struct sock *dsk, struct sk_buff *skb, void *data)
98 99
99 return 0; 100 return 0;
100} 101}
102#endif
101 103
102static int kobj_usermode_filter(struct kobject *kobj) 104static int kobj_usermode_filter(struct kobject *kobj)
103{ 105{
@@ -378,6 +380,7 @@ static int uevent_net_init(struct net *net)
378 if (!ue_sk->sk) { 380 if (!ue_sk->sk) {
379 printk(KERN_ERR 381 printk(KERN_ERR
380 "kobject_uevent: unable to create netlink socket!\n"); 382 "kobject_uevent: unable to create netlink socket!\n");
383 kfree(ue_sk);
381 return -ENODEV; 384 return -ENODEV;
382 } 385 }
383 mutex_lock(&uevent_sock_mutex); 386 mutex_lock(&uevent_sock_mutex);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index b289310e2c89..5fa63bdf52e4 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -597,7 +597,7 @@ static void balance_dirty_pages(struct address_space *mapping,
597 (!laptop_mode && ((global_page_state(NR_FILE_DIRTY) 597 (!laptop_mode && ((global_page_state(NR_FILE_DIRTY)
598 + global_page_state(NR_UNSTABLE_NFS)) 598 + global_page_state(NR_UNSTABLE_NFS))
599 > background_thresh))) 599 > background_thresh)))
600 bdi_start_writeback(bdi, NULL, 0, 0); 600 bdi_start_writeback(bdi, NULL, 0);
601} 601}
602 602
603void set_page_dirty_balance(struct page *page, int page_mkwrite) 603void set_page_dirty_balance(struct page *page, int page_mkwrite)
@@ -707,7 +707,7 @@ void laptop_mode_timer_fn(unsigned long data)
707 */ 707 */
708 708
709 if (bdi_has_dirty_io(&q->backing_dev_info)) 709 if (bdi_has_dirty_io(&q->backing_dev_info))
710 bdi_start_writeback(&q->backing_dev_info, NULL, nr_pages, 0); 710 bdi_start_writeback(&q->backing_dev_info, NULL, nr_pages);
711} 711}
712 712
713/* 713/*
diff --git a/mm/shmem.c b/mm/shmem.c
index 7e5030ae18ff..f65f84062db5 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -764,10 +764,11 @@ done2:
764static int shmem_notify_change(struct dentry *dentry, struct iattr *attr) 764static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
765{ 765{
766 struct inode *inode = dentry->d_inode; 766 struct inode *inode = dentry->d_inode;
767 loff_t newsize = attr->ia_size;
767 int error; 768 int error;
768 769
769 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { 770 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)
770 loff_t newsize = attr->ia_size; 771 && newsize != inode->i_size) {
771 struct page *page = NULL; 772 struct page *page = NULL;
772 773
773 if (newsize < inode->i_size) { 774 if (newsize < inode->i_size) {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 915dceb487c1..9c7e57cc63a3 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1724,13 +1724,13 @@ static void shrink_zone(int priority, struct zone *zone,
1724 * If a zone is deemed to be full of pinned pages then just give it a light 1724 * If a zone is deemed to be full of pinned pages then just give it a light
1725 * scan then give up on it. 1725 * scan then give up on it.
1726 */ 1726 */
1727static int shrink_zones(int priority, struct zonelist *zonelist, 1727static bool shrink_zones(int priority, struct zonelist *zonelist,
1728 struct scan_control *sc) 1728 struct scan_control *sc)
1729{ 1729{
1730 enum zone_type high_zoneidx = gfp_zone(sc->gfp_mask); 1730 enum zone_type high_zoneidx = gfp_zone(sc->gfp_mask);
1731 struct zoneref *z; 1731 struct zoneref *z;
1732 struct zone *zone; 1732 struct zone *zone;
1733 int progress = 0; 1733 bool all_unreclaimable = true;
1734 1734
1735 for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx, 1735 for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx,
1736 sc->nodemask) { 1736 sc->nodemask) {
@@ -1757,9 +1757,9 @@ static int shrink_zones(int priority, struct zonelist *zonelist,
1757 } 1757 }
1758 1758
1759 shrink_zone(priority, zone, sc); 1759 shrink_zone(priority, zone, sc);
1760 progress = 1; 1760 all_unreclaimable = false;
1761 } 1761 }
1762 return progress; 1762 return all_unreclaimable;
1763} 1763}
1764 1764
1765/* 1765/*
@@ -1782,7 +1782,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
1782 struct scan_control *sc) 1782 struct scan_control *sc)
1783{ 1783{
1784 int priority; 1784 int priority;
1785 unsigned long ret = 0; 1785 bool all_unreclaimable;
1786 unsigned long total_scanned = 0; 1786 unsigned long total_scanned = 0;
1787 struct reclaim_state *reclaim_state = current->reclaim_state; 1787 struct reclaim_state *reclaim_state = current->reclaim_state;
1788 unsigned long lru_pages = 0; 1788 unsigned long lru_pages = 0;
@@ -1813,7 +1813,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
1813 sc->nr_scanned = 0; 1813 sc->nr_scanned = 0;
1814 if (!priority) 1814 if (!priority)
1815 disable_swap_token(); 1815 disable_swap_token();
1816 ret = shrink_zones(priority, zonelist, sc); 1816 all_unreclaimable = shrink_zones(priority, zonelist, sc);
1817 /* 1817 /*
1818 * Don't shrink slabs when reclaiming memory from 1818 * Don't shrink slabs when reclaiming memory from
1819 * over limit cgroups 1819 * over limit cgroups
@@ -1826,10 +1826,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
1826 } 1826 }
1827 } 1827 }
1828 total_scanned += sc->nr_scanned; 1828 total_scanned += sc->nr_scanned;
1829 if (sc->nr_reclaimed >= sc->nr_to_reclaim) { 1829 if (sc->nr_reclaimed >= sc->nr_to_reclaim)
1830 ret = sc->nr_reclaimed;
1831 goto out; 1830 goto out;
1832 }
1833 1831
1834 /* 1832 /*
1835 * Try to write back as many pages as we just scanned. This 1833 * Try to write back as many pages as we just scanned. This
@@ -1849,9 +1847,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
1849 priority < DEF_PRIORITY - 2) 1847 priority < DEF_PRIORITY - 2)
1850 congestion_wait(BLK_RW_ASYNC, HZ/10); 1848 congestion_wait(BLK_RW_ASYNC, HZ/10);
1851 } 1849 }
1852 /* top priority shrink_zones still had more to do? don't OOM, then */ 1850
1853 if (ret && scanning_global_lru(sc))
1854 ret = sc->nr_reclaimed;
1855out: 1851out:
1856 /* 1852 /*
1857 * Now that we've scanned all the zones at this priority level, note 1853 * Now that we've scanned all the zones at this priority level, note
@@ -1877,7 +1873,14 @@ out:
1877 delayacct_freepages_end(); 1873 delayacct_freepages_end();
1878 put_mems_allowed(); 1874 put_mems_allowed();
1879 1875
1880 return ret; 1876 if (sc->nr_reclaimed)
1877 return sc->nr_reclaimed;
1878
1879 /* top priority shrink_zones still had more to do? don't OOM, then */
1880 if (scanning_global_lru(sc) && !all_unreclaimable)
1881 return 1;
1882
1883 return 0;
1881} 1884}
1882 1885
1883unsigned long try_to_free_pages(struct zonelist *zonelist, int order, 1886unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 55be90826f5f..529842677817 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -708,7 +708,8 @@ static int vlan_dev_init(struct net_device *dev)
708 netif_carrier_off(dev); 708 netif_carrier_off(dev);
709 709
710 /* IFF_BROADCAST|IFF_MULTICAST; ??? */ 710 /* IFF_BROADCAST|IFF_MULTICAST; ??? */
711 dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI); 711 dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
712 IFF_MASTER | IFF_SLAVE);
712 dev->iflink = real_dev->ifindex; 713 dev->iflink = real_dev->ifindex;
713 dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | 714 dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
714 (1<<__LINK_STATE_DORMANT))) | 715 (1<<__LINK_STATE_DORMANT))) |
diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c
index cb4325a3dc83..965c5baace40 100644
--- a/net/caif/cfserl.c
+++ b/net/caif/cfserl.c
@@ -59,16 +59,18 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
59 u8 stx = CFSERL_STX; 59 u8 stx = CFSERL_STX;
60 int ret; 60 int ret;
61 u16 expectlen = 0; 61 u16 expectlen = 0;
62
62 caif_assert(newpkt != NULL); 63 caif_assert(newpkt != NULL);
63 spin_lock(&layr->sync); 64 spin_lock(&layr->sync);
64 65
65 if (layr->incomplete_frm != NULL) { 66 if (layr->incomplete_frm != NULL) {
66
67 layr->incomplete_frm = 67 layr->incomplete_frm =
68 cfpkt_append(layr->incomplete_frm, newpkt, expectlen); 68 cfpkt_append(layr->incomplete_frm, newpkt, expectlen);
69 pkt = layr->incomplete_frm; 69 pkt = layr->incomplete_frm;
70 if (pkt == NULL) 70 if (pkt == NULL) {
71 spin_unlock(&layr->sync);
71 return -ENOMEM; 72 return -ENOMEM;
73 }
72 } else { 74 } else {
73 pkt = newpkt; 75 pkt = newpkt;
74 } 76 }
diff --git a/net/core/dev.c b/net/core/dev.c
index 1845b08c624e..d03470f5260a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2795,7 +2795,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
2795 struct net_device *orig_dev; 2795 struct net_device *orig_dev;
2796 struct net_device *master; 2796 struct net_device *master;
2797 struct net_device *null_or_orig; 2797 struct net_device *null_or_orig;
2798 struct net_device *null_or_bond; 2798 struct net_device *orig_or_bond;
2799 int ret = NET_RX_DROP; 2799 int ret = NET_RX_DROP;
2800 __be16 type; 2800 __be16 type;
2801 2801
@@ -2868,10 +2868,10 @@ ncls:
2868 * device that may have registered for a specific ptype. The 2868 * device that may have registered for a specific ptype. The
2869 * handler may have to adjust skb->dev and orig_dev. 2869 * handler may have to adjust skb->dev and orig_dev.
2870 */ 2870 */
2871 null_or_bond = NULL; 2871 orig_or_bond = orig_dev;
2872 if ((skb->dev->priv_flags & IFF_802_1Q_VLAN) && 2872 if ((skb->dev->priv_flags & IFF_802_1Q_VLAN) &&
2873 (vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING)) { 2873 (vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING)) {
2874 null_or_bond = vlan_dev_real_dev(skb->dev); 2874 orig_or_bond = vlan_dev_real_dev(skb->dev);
2875 } 2875 }
2876 2876
2877 type = skb->protocol; 2877 type = skb->protocol;
@@ -2879,7 +2879,7 @@ ncls:
2879 &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { 2879 &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
2880 if (ptype->type == type && (ptype->dev == null_or_orig || 2880 if (ptype->type == type && (ptype->dev == null_or_orig ||
2881 ptype->dev == skb->dev || ptype->dev == orig_dev || 2881 ptype->dev == skb->dev || ptype->dev == orig_dev ||
2882 ptype->dev == null_or_bond)) { 2882 ptype->dev == orig_or_bond)) {
2883 if (pt_prev) 2883 if (pt_prev)
2884 ret = deliver_skb(skb, pt_prev, orig_dev); 2884 ret = deliver_skb(skb, pt_prev, orig_dev);
2885 pt_prev = ptype; 2885 pt_prev = ptype;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f8abf68e3988..9f07e749d7b1 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -482,22 +482,22 @@ EXPORT_SYMBOL(consume_skb);
482 * reference count dropping and cleans up the skbuff as if it 482 * reference count dropping and cleans up the skbuff as if it
483 * just came from __alloc_skb(). 483 * just came from __alloc_skb().
484 */ 484 */
485int skb_recycle_check(struct sk_buff *skb, int skb_size) 485bool skb_recycle_check(struct sk_buff *skb, int skb_size)
486{ 486{
487 struct skb_shared_info *shinfo; 487 struct skb_shared_info *shinfo;
488 488
489 if (irqs_disabled()) 489 if (irqs_disabled())
490 return 0; 490 return false;
491 491
492 if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE) 492 if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
493 return 0; 493 return false;
494 494
495 skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD); 495 skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD);
496 if (skb_end_pointer(skb) - skb->head < skb_size) 496 if (skb_end_pointer(skb) - skb->head < skb_size)
497 return 0; 497 return false;
498 498
499 if (skb_shared(skb) || skb_cloned(skb)) 499 if (skb_shared(skb) || skb_cloned(skb))
500 return 0; 500 return false;
501 501
502 skb_release_head_state(skb); 502 skb_release_head_state(skb);
503 503
@@ -509,7 +509,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size)
509 skb->data = skb->head + NET_SKB_PAD; 509 skb->data = skb->head + NET_SKB_PAD;
510 skb_reset_tail_pointer(skb); 510 skb_reset_tail_pointer(skb);
511 511
512 return 1; 512 return true;
513} 513}
514EXPORT_SYMBOL(skb_recycle_check); 514EXPORT_SYMBOL(skb_recycle_check);
515 515
@@ -2965,6 +2965,34 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
2965} 2965}
2966EXPORT_SYMBOL_GPL(skb_cow_data); 2966EXPORT_SYMBOL_GPL(skb_cow_data);
2967 2967
2968static void sock_rmem_free(struct sk_buff *skb)
2969{
2970 struct sock *sk = skb->sk;
2971
2972 atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
2973}
2974
2975/*
2976 * Note: We dont mem charge error packets (no sk_forward_alloc changes)
2977 */
2978int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
2979{
2980 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
2981 (unsigned)sk->sk_rcvbuf)
2982 return -ENOMEM;
2983
2984 skb_orphan(skb);
2985 skb->sk = sk;
2986 skb->destructor = sock_rmem_free;
2987 atomic_add(skb->truesize, &sk->sk_rmem_alloc);
2988
2989 skb_queue_tail(&sk->sk_error_queue, skb);
2990 if (!sock_flag(sk, SOCK_DEAD))
2991 sk->sk_data_ready(sk, skb->len);
2992 return 0;
2993}
2994EXPORT_SYMBOL(sock_queue_err_skb);
2995
2968void skb_tstamp_tx(struct sk_buff *orig_skb, 2996void skb_tstamp_tx(struct sk_buff *orig_skb,
2969 struct skb_shared_hwtstamps *hwtstamps) 2997 struct skb_shared_hwtstamps *hwtstamps)
2970{ 2998{
@@ -2996,7 +3024,9 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
2996 memset(serr, 0, sizeof(*serr)); 3024 memset(serr, 0, sizeof(*serr));
2997 serr->ee.ee_errno = ENOMSG; 3025 serr->ee.ee_errno = ENOMSG;
2998 serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; 3026 serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
3027
2999 err = sock_queue_err_skb(sk, skb); 3028 err = sock_queue_err_skb(sk, skb);
3029
3000 if (err) 3030 if (err)
3001 kfree_skb(skb); 3031 kfree_skb(skb);
3002} 3032}
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 8e3a1fd938ab..7c3a7d191249 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -303,7 +303,7 @@ config ARPD
303 If unsure, say N. 303 If unsure, say N.
304 304
305config SYN_COOKIES 305config SYN_COOKIES
306 bool "IP: TCP syncookie support (disabled per default)" 306 bool "IP: TCP syncookie support"
307 ---help--- 307 ---help---
308 Normal TCP/IP networking is open to an attack known as "SYN 308 Normal TCP/IP networking is open to an attack known as "SYN
309 flooding". This denial-of-service attack prevents legitimate remote 309 flooding". This denial-of-service attack prevents legitimate remote
@@ -328,13 +328,13 @@ config SYN_COOKIES
328 server is really overloaded. If this happens frequently better turn 328 server is really overloaded. If this happens frequently better turn
329 them off. 329 them off.
330 330
331 If you say Y here, note that SYN cookies aren't enabled by default; 331 If you say Y here, you can disable SYN cookies at run time by
332 you can enable them by saying Y to "/proc file system support" and 332 saying Y to "/proc file system support" and
333 "Sysctl support" below and executing the command 333 "Sysctl support" below and executing the command
334 334
335 echo 1 >/proc/sys/net/ipv4/tcp_syncookies 335 echo 0 > /proc/sys/net/ipv4/tcp_syncookies
336 336
337 at boot time after the /proc file system has been mounted. 337 after the /proc file system has been mounted.
338 338
339 If unsure, say N. 339 If unsure, say N.
340 340
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 63958f3394a5..4b6c5ca610fc 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -336,7 +336,7 @@ ipt_do_table(struct sk_buff *skb,
336 cpu = smp_processor_id(); 336 cpu = smp_processor_id();
337 table_base = private->entries[cpu]; 337 table_base = private->entries[cpu];
338 jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; 338 jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
339 stackptr = &private->stackptr[cpu]; 339 stackptr = per_cpu_ptr(private->stackptr, cpu);
340 origptr = *stackptr; 340 origptr = *stackptr;
341 341
342 e = get_entry(table_base, private->hook_entry[hook]); 342 e = get_entry(table_base, private->hook_entry[hook]);
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 5c24db4a3c91..9f6b22206c52 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -347,7 +347,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
347 { .sport = th->dest, 347 { .sport = th->dest,
348 .dport = th->source } } }; 348 .dport = th->source } } };
349 security_req_classify_flow(req, &fl); 349 security_req_classify_flow(req, &fl);
350 if (ip_route_output_key(&init_net, &rt, &fl)) { 350 if (ip_route_output_key(sock_net(sk), &rt, &fl)) {
351 reqsk_free(req); 351 reqsk_free(req);
352 goto out; 352 goto out;
353 } 353 }
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c
index c209e054a634..377bc9349371 100644
--- a/net/ipv4/tcp_hybla.c
+++ b/net/ipv4/tcp_hybla.c
@@ -126,8 +126,8 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
126 * calculate 2^fract in a <<7 value. 126 * calculate 2^fract in a <<7 value.
127 */ 127 */
128 is_slowstart = 1; 128 is_slowstart = 1;
129 increment = ((1 << ca->rho) * hybla_fraction(rho_fractions)) 129 increment = ((1 << min(ca->rho, 16U)) *
130 - 128; 130 hybla_fraction(rho_fractions)) - 128;
131 } else { 131 } else {
132 /* 132 /*
133 * congestion avoidance 133 * congestion avoidance
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3e6dafcb1071..548d575e6cc6 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2639,7 +2639,7 @@ static void DBGUNDO(struct sock *sk, const char *msg)
2639 if (sk->sk_family == AF_INET) { 2639 if (sk->sk_family == AF_INET) {
2640 printk(KERN_DEBUG "Undo %s %pI4/%u c%u l%u ss%u/%u p%u\n", 2640 printk(KERN_DEBUG "Undo %s %pI4/%u c%u l%u ss%u/%u p%u\n",
2641 msg, 2641 msg,
2642 &inet->daddr, ntohs(inet->dport), 2642 &inet->inet_daddr, ntohs(inet->inet_dport),
2643 tp->snd_cwnd, tcp_left_out(tp), 2643 tp->snd_cwnd, tcp_left_out(tp),
2644 tp->snd_ssthresh, tp->prior_ssthresh, 2644 tp->snd_ssthresh, tp->prior_ssthresh,
2645 tp->packets_out); 2645 tp->packets_out);
@@ -2649,7 +2649,7 @@ static void DBGUNDO(struct sock *sk, const char *msg)
2649 struct ipv6_pinfo *np = inet6_sk(sk); 2649 struct ipv6_pinfo *np = inet6_sk(sk);
2650 printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", 2650 printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n",
2651 msg, 2651 msg,
2652 &np->daddr, ntohs(inet->dport), 2652 &np->daddr, ntohs(inet->inet_dport),
2653 tp->snd_cwnd, tcp_left_out(tp), 2653 tp->snd_cwnd, tcp_left_out(tp),
2654 tp->snd_ssthresh, tp->prior_ssthresh, 2654 tp->snd_ssthresh, tp->prior_ssthresh,
2655 tp->packets_out); 2655 tp->packets_out);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 202cf09c4cd4..fe193e53af44 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1555,6 +1555,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1555#endif 1555#endif
1556 1556
1557 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ 1557 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
1558 sock_rps_save_rxhash(sk, skb->rxhash);
1558 TCP_CHECK_TIMER(sk); 1559 TCP_CHECK_TIMER(sk);
1559 if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { 1560 if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
1560 rsk = sk; 1561 rsk = sk;
@@ -1579,7 +1580,9 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1579 } 1580 }
1580 return 0; 1581 return 0;
1581 } 1582 }
1582 } 1583 } else
1584 sock_rps_save_rxhash(sk, skb->rxhash);
1585
1583 1586
1584 TCP_CHECK_TIMER(sk); 1587 TCP_CHECK_TIMER(sk);
1585 if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) { 1588 if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) {
@@ -1672,8 +1675,6 @@ process:
1672 1675
1673 skb->dev = NULL; 1676 skb->dev = NULL;
1674 1677
1675 sock_rps_save_rxhash(sk, skb->rxhash);
1676
1677 bh_lock_sock_nested(sk); 1678 bh_lock_sock_nested(sk);
1678 ret = 0; 1679 ret = 0;
1679 if (!sock_owned_by_user(sk)) { 1680 if (!sock_owned_by_user(sk)) {
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 58585748bdac..eec4ff456e33 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -633,9 +633,9 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
633 if (!inet->recverr) { 633 if (!inet->recverr) {
634 if (!harderr || sk->sk_state != TCP_ESTABLISHED) 634 if (!harderr || sk->sk_state != TCP_ESTABLISHED)
635 goto out; 635 goto out;
636 } else { 636 } else
637 ip_icmp_error(sk, skb, err, uh->dest, info, (u8 *)(uh+1)); 637 ip_icmp_error(sk, skb, err, uh->dest, info, (u8 *)(uh+1));
638 } 638
639 sk->sk_err = err; 639 sk->sk_err = err;
640 sk->sk_error_report(sk); 640 sk->sk_error_report(sk);
641out: 641out:
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 6f517bd83692..9d2d68f0e605 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -363,7 +363,7 @@ ip6t_do_table(struct sk_buff *skb,
363 cpu = smp_processor_id(); 363 cpu = smp_processor_id();
364 table_base = private->entries[cpu]; 364 table_base = private->entries[cpu];
365 jumpstack = (struct ip6t_entry **)private->jumpstack[cpu]; 365 jumpstack = (struct ip6t_entry **)private->jumpstack[cpu];
366 stackptr = &private->stackptr[cpu]; 366 stackptr = per_cpu_ptr(private->stackptr, cpu);
367 origptr = *stackptr; 367 origptr = *stackptr;
368 368
369 e = get_entry(table_base, private->hook_entry[hook]); 369 e = get_entry(table_base, private->hook_entry[hook]);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 294cbe8b0725..252d76199c41 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -814,7 +814,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
814{ 814{
815 int flags = 0; 815 int flags = 0;
816 816
817 if (fl->oif || rt6_need_strict(&fl->fl6_dst)) 817 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl->fl6_dst))
818 flags |= RT6_LOOKUP_F_IFACE; 818 flags |= RT6_LOOKUP_F_IFACE;
819 819
820 if (!ipv6_addr_any(&fl->fl6_src)) 820 if (!ipv6_addr_any(&fl->fl6_src))
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index c163d0a149f4..98258b7341e3 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -332,14 +332,16 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
332 IEEE80211_QUEUE_STOP_REASON_AGGREGATION); 332 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
333 333
334 spin_unlock(&local->ampdu_lock); 334 spin_unlock(&local->ampdu_lock);
335 spin_unlock_bh(&sta->lock);
336 335
337 /* send an addBA request */ 336 /* prepare tid data */
338 sta->ampdu_mlme.dialog_token_allocator++; 337 sta->ampdu_mlme.dialog_token_allocator++;
339 sta->ampdu_mlme.tid_tx[tid]->dialog_token = 338 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
340 sta->ampdu_mlme.dialog_token_allocator; 339 sta->ampdu_mlme.dialog_token_allocator;
341 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; 340 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
342 341
342 spin_unlock_bh(&sta->lock);
343
344 /* send AddBA request */
343 ieee80211_send_addba_request(sdata, pubsta->addr, tid, 345 ieee80211_send_addba_request(sdata, pubsta->addr, tid,
344 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 346 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
345 sta->ampdu_mlme.tid_tx[tid]->ssn, 347 sta->ampdu_mlme.tid_tx[tid]->ssn,
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 5d218c530a4e..32be11e4c4d9 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -5,7 +5,7 @@
5#include <linux/nl80211.h> 5#include <linux/nl80211.h>
6#include "ieee80211_i.h" 6#include "ieee80211_i.h"
7 7
8enum ieee80211_chan_mode 8static enum ieee80211_chan_mode
9__ieee80211_get_channel_mode(struct ieee80211_local *local, 9__ieee80211_get_channel_mode(struct ieee80211_local *local,
10 struct ieee80211_sub_if_data *ignore) 10 struct ieee80211_sub_if_data *ignore)
11{ 11{
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6e2a7bcd8cb8..5e0b65406c44 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1818,17 +1818,26 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1818 return RX_CONTINUE; 1818 return RX_CONTINUE;
1819 1819
1820 if (ieee80211_is_back_req(bar->frame_control)) { 1820 if (ieee80211_is_back_req(bar->frame_control)) {
1821 struct {
1822 __le16 control, start_seq_num;
1823 } __packed bar_data;
1824
1821 if (!rx->sta) 1825 if (!rx->sta)
1822 return RX_DROP_MONITOR; 1826 return RX_DROP_MONITOR;
1827
1828 if (skb_copy_bits(skb, offsetof(struct ieee80211_bar, control),
1829 &bar_data, sizeof(bar_data)))
1830 return RX_DROP_MONITOR;
1831
1823 spin_lock(&rx->sta->lock); 1832 spin_lock(&rx->sta->lock);
1824 tid = le16_to_cpu(bar->control) >> 12; 1833 tid = le16_to_cpu(bar_data.control) >> 12;
1825 if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) { 1834 if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) {
1826 spin_unlock(&rx->sta->lock); 1835 spin_unlock(&rx->sta->lock);
1827 return RX_DROP_MONITOR; 1836 return RX_DROP_MONITOR;
1828 } 1837 }
1829 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; 1838 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
1830 1839
1831 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; 1840 start_seq_num = le16_to_cpu(bar_data.start_seq_num) >> 4;
1832 1841
1833 /* reset session timer */ 1842 /* reset session timer */
1834 if (tid_agg_rx->timeout) 1843 if (tid_agg_rx->timeout)
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 445de702b8b7..e34622fa0003 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -699,10 +699,8 @@ void xt_free_table_info(struct xt_table_info *info)
699 vfree(info->jumpstack); 699 vfree(info->jumpstack);
700 else 700 else
701 kfree(info->jumpstack); 701 kfree(info->jumpstack);
702 if (sizeof(unsigned int) * nr_cpu_ids > PAGE_SIZE) 702
703 vfree(info->stackptr); 703 free_percpu(info->stackptr);
704 else
705 kfree(info->stackptr);
706 704
707 kfree(info); 705 kfree(info);
708} 706}
@@ -753,14 +751,9 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)
753 unsigned int size; 751 unsigned int size;
754 int cpu; 752 int cpu;
755 753
756 size = sizeof(unsigned int) * nr_cpu_ids; 754 i->stackptr = alloc_percpu(unsigned int);
757 if (size > PAGE_SIZE)
758 i->stackptr = vmalloc(size);
759 else
760 i->stackptr = kmalloc(size, GFP_KERNEL);
761 if (i->stackptr == NULL) 755 if (i->stackptr == NULL)
762 return -ENOMEM; 756 return -ENOMEM;
763 memset(i->stackptr, 0, size);
764 757
765 size = sizeof(void **) * nr_cpu_ids; 758 size = sizeof(void **) * nr_cpu_ids;
766 if (size > PAGE_SIZE) 759 if (size > PAGE_SIZE)
@@ -844,10 +837,6 @@ struct xt_table *xt_register_table(struct net *net,
844 struct xt_table_info *private; 837 struct xt_table_info *private;
845 struct xt_table *t, *table; 838 struct xt_table *t, *table;
846 839
847 ret = xt_jumpstack_alloc(newinfo);
848 if (ret < 0)
849 return ERR_PTR(ret);
850
851 /* Don't add one object to multiple lists. */ 840 /* Don't add one object to multiple lists. */
852 table = kmemdup(input_table, sizeof(struct xt_table), GFP_KERNEL); 841 table = kmemdup(input_table, sizeof(struct xt_table), GFP_KERNEL);
853 if (!table) { 842 if (!table) {
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 7b048a35ca58..94d72e85a475 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -1045,12 +1045,12 @@ static void pep_sock_unhash(struct sock *sk)
1045 lock_sock(sk); 1045 lock_sock(sk);
1046 if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) { 1046 if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) {
1047 skparent = pn->listener; 1047 skparent = pn->listener;
1048 sk_del_node_init(sk);
1049 release_sock(sk); 1048 release_sock(sk);
1050 1049
1051 sk = skparent;
1052 pn = pep_sk(skparent); 1050 pn = pep_sk(skparent);
1053 lock_sock(sk); 1051 lock_sock(skparent);
1052 sk_del_node_init(sk);
1053 sk = skparent;
1054 } 1054 }
1055 /* Unhash a listening sock only when it is closed 1055 /* Unhash a listening sock only when it is closed
1056 * and all of its active connected pipes are closed. */ 1056 * and all of its active connected pipes are closed. */
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index 10ed0d55f759..f68832798db2 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -475,6 +475,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
475 err = rds_ib_setup_qp(conn); 475 err = rds_ib_setup_qp(conn);
476 if (err) { 476 if (err) {
477 rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err); 477 rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err);
478 mutex_unlock(&conn->c_cm_lock);
478 goto out; 479 goto out;
479 } 480 }
480 481
diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c
index a9d951b4fbae..b5dd6ac39be8 100644
--- a/net/rds/iw_cm.c
+++ b/net/rds/iw_cm.c
@@ -452,6 +452,7 @@ int rds_iw_cm_handle_connect(struct rdma_cm_id *cm_id,
452 err = rds_iw_setup_qp(conn); 452 err = rds_iw_setup_qp(conn);
453 if (err) { 453 if (err) {
454 rds_iw_conn_error(conn, "rds_iw_setup_qp failed (%d)\n", err); 454 rds_iw_conn_error(conn, "rds_iw_setup_qp failed (%d)\n", err);
455 mutex_unlock(&conn->c_cm_lock);
455 goto out; 456 goto out;
456 } 457 }
457 458
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index d885ba311564..570949417f38 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -159,6 +159,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
159 iph->daddr = new_addr; 159 iph->daddr = new_addr;
160 160
161 csum_replace4(&iph->check, addr, new_addr); 161 csum_replace4(&iph->check, addr, new_addr);
162 } else if ((iph->frag_off & htons(IP_OFFSET)) ||
163 iph->protocol != IPPROTO_ICMP) {
164 goto out;
162 } 165 }
163 166
164 ihl = iph->ihl * 4; 167 ihl = iph->ihl * 4;
@@ -247,6 +250,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
247 break; 250 break;
248 } 251 }
249 252
253out:
250 return action; 254 return action;
251 255
252drop: 256drop:
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index fdbd0b7bd840..50e3d945e1f4 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -125,7 +125,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
125{ 125{
126 struct tcf_pedit *p = a->priv; 126 struct tcf_pedit *p = a->priv;
127 int i, munged = 0; 127 int i, munged = 0;
128 u8 *pptr; 128 unsigned int off;
129 129
130 if (!(skb->tc_verd & TC_OK2MUNGE)) { 130 if (!(skb->tc_verd & TC_OK2MUNGE)) {
131 /* should we set skb->cloned? */ 131 /* should we set skb->cloned? */
@@ -134,7 +134,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
134 } 134 }
135 } 135 }
136 136
137 pptr = skb_network_header(skb); 137 off = skb_network_offset(skb);
138 138
139 spin_lock(&p->tcf_lock); 139 spin_lock(&p->tcf_lock);
140 140
@@ -144,17 +144,17 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
144 struct tc_pedit_key *tkey = p->tcfp_keys; 144 struct tc_pedit_key *tkey = p->tcfp_keys;
145 145
146 for (i = p->tcfp_nkeys; i > 0; i--, tkey++) { 146 for (i = p->tcfp_nkeys; i > 0; i--, tkey++) {
147 u32 *ptr; 147 u32 *ptr, _data;
148 int offset = tkey->off; 148 int offset = tkey->off;
149 149
150 if (tkey->offmask) { 150 if (tkey->offmask) {
151 if (skb->len > tkey->at) { 151 char *d, _d;
152 char *j = pptr + tkey->at; 152
153 offset += ((*j & tkey->offmask) >> 153 d = skb_header_pointer(skb, off + tkey->at, 1,
154 tkey->shift); 154 &_d);
155 } else { 155 if (!d)
156 goto bad; 156 goto bad;
157 } 157 offset += (*d & tkey->offmask) >> tkey->shift;
158 } 158 }
159 159
160 if (offset % 4) { 160 if (offset % 4) {
@@ -169,9 +169,13 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
169 goto bad; 169 goto bad;
170 } 170 }
171 171
172 ptr = (u32 *)(pptr+offset); 172 ptr = skb_header_pointer(skb, off + offset, 4, &_data);
173 if (!ptr)
174 goto bad;
173 /* just do it, baby */ 175 /* just do it, baby */
174 *ptr = ((*ptr & tkey->mask) ^ tkey->val); 176 *ptr = ((*ptr & tkey->mask) ^ tkey->val);
177 if (ptr == &_data)
178 skb_store_bits(skb, off + offset, ptr, 4);
175 munged++; 179 munged++;
176 } 180 }
177 181
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 96275422c619..4f522143811e 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -98,11 +98,11 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re
98{ 98{
99 struct { 99 struct {
100 struct tc_u_knode *knode; 100 struct tc_u_knode *knode;
101 u8 *ptr; 101 unsigned int off;
102 } stack[TC_U32_MAXDEPTH]; 102 } stack[TC_U32_MAXDEPTH];
103 103
104 struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root; 104 struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root;
105 u8 *ptr = skb_network_header(skb); 105 unsigned int off = skb_network_offset(skb);
106 struct tc_u_knode *n; 106 struct tc_u_knode *n;
107 int sdepth = 0; 107 int sdepth = 0;
108 int off2 = 0; 108 int off2 = 0;
@@ -134,8 +134,14 @@ next_knode:
134#endif 134#endif
135 135
136 for (i = n->sel.nkeys; i>0; i--, key++) { 136 for (i = n->sel.nkeys; i>0; i--, key++) {
137 137 unsigned int toff;
138 if ((*(__be32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) { 138 __be32 *data, _data;
139
140 toff = off + key->off + (off2 & key->offmask);
141 data = skb_header_pointer(skb, toff, 4, &_data);
142 if (!data)
143 goto out;
144 if ((*data ^ key->val) & key->mask) {
139 n = n->next; 145 n = n->next;
140 goto next_knode; 146 goto next_knode;
141 } 147 }
@@ -174,29 +180,45 @@ check_terminal:
174 if (sdepth >= TC_U32_MAXDEPTH) 180 if (sdepth >= TC_U32_MAXDEPTH)
175 goto deadloop; 181 goto deadloop;
176 stack[sdepth].knode = n; 182 stack[sdepth].knode = n;
177 stack[sdepth].ptr = ptr; 183 stack[sdepth].off = off;
178 sdepth++; 184 sdepth++;
179 185
180 ht = n->ht_down; 186 ht = n->ht_down;
181 sel = 0; 187 sel = 0;
182 if (ht->divisor) 188 if (ht->divisor) {
183 sel = ht->divisor&u32_hash_fold(*(__be32*)(ptr+n->sel.hoff), &n->sel,n->fshift); 189 __be32 *data, _data;
184 190
191 data = skb_header_pointer(skb, off + n->sel.hoff, 4,
192 &_data);
193 if (!data)
194 goto out;
195 sel = ht->divisor & u32_hash_fold(*data, &n->sel,
196 n->fshift);
197 }
185 if (!(n->sel.flags&(TC_U32_VAROFFSET|TC_U32_OFFSET|TC_U32_EAT))) 198 if (!(n->sel.flags&(TC_U32_VAROFFSET|TC_U32_OFFSET|TC_U32_EAT)))
186 goto next_ht; 199 goto next_ht;
187 200
188 if (n->sel.flags&(TC_U32_OFFSET|TC_U32_VAROFFSET)) { 201 if (n->sel.flags&(TC_U32_OFFSET|TC_U32_VAROFFSET)) {
189 off2 = n->sel.off + 3; 202 off2 = n->sel.off + 3;
190 if (n->sel.flags&TC_U32_VAROFFSET) 203 if (n->sel.flags & TC_U32_VAROFFSET) {
191 off2 += ntohs(n->sel.offmask & *(__be16*)(ptr+n->sel.offoff)) >>n->sel.offshift; 204 __be16 *data, _data;
205
206 data = skb_header_pointer(skb,
207 off + n->sel.offoff,
208 2, &_data);
209 if (!data)
210 goto out;
211 off2 += ntohs(n->sel.offmask & *data) >>
212 n->sel.offshift;
213 }
192 off2 &= ~3; 214 off2 &= ~3;
193 } 215 }
194 if (n->sel.flags&TC_U32_EAT) { 216 if (n->sel.flags&TC_U32_EAT) {
195 ptr += off2; 217 off += off2;
196 off2 = 0; 218 off2 = 0;
197 } 219 }
198 220
199 if (ptr < skb_tail_pointer(skb)) 221 if (off < skb->len)
200 goto next_ht; 222 goto next_ht;
201 } 223 }
202 224
@@ -204,9 +226,10 @@ check_terminal:
204 if (sdepth--) { 226 if (sdepth--) {
205 n = stack[sdepth].knode; 227 n = stack[sdepth].knode;
206 ht = n->ht_up; 228 ht = n->ht_up;
207 ptr = stack[sdepth].ptr; 229 off = stack[sdepth].off;
208 goto check_terminal; 230 goto check_terminal;
209 } 231 }
232out:
210 return -1; 233 return -1;
211 234
212deadloop: 235deadloop:
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 6a329158bdfa..a3cca0a94346 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -95,13 +95,13 @@ resume:
95 goto error_nolock; 95 goto error_nolock;
96 } 96 }
97 97
98 dst = dst_pop(dst); 98 dst = skb_dst_pop(skb);
99 if (!dst) { 99 if (!dst) {
100 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR); 100 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
101 err = -EHOSTUNREACH; 101 err = -EHOSTUNREACH;
102 goto error_nolock; 102 goto error_nolock;
103 } 103 }
104 skb_dst_set(skb, dst); 104 skb_dst_set_noref(skb, dst);
105 x = dst->xfrm; 105 x = dst->xfrm;
106 } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); 106 } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
107 107
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d965a2bad8d3..4bf27d901333 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2153,6 +2153,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
2153 return 0; 2153 return 0;
2154 } 2154 }
2155 2155
2156 skb_dst_force(skb);
2156 dst = skb_dst(skb); 2157 dst = skb_dst(skb);
2157 2158
2158 res = xfrm_lookup(net, &dst, &fl, NULL, 0) == 0; 2159 res = xfrm_lookup(net, &dst, &fl, NULL, 0) == 0;
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 0b94d2fa3a88..e4deb73e9a84 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -82,7 +82,7 @@ ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
82lib-target := $(obj)/lib.a 82lib-target := $(obj)/lib.a
83endif 83endif
84 84
85ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),) 85ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(subdir-m) $(lib-target)),)
86builtin-target := $(obj)/built-in.o 86builtin-target := $(obj)/built-in.o
87endif 87endif
88 88
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index cbcd654215e6..54fd1b700131 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -241,7 +241,7 @@ cmd_lzma = (cat $(filter-out FORCE,$^) | \
241 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ 241 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
242 (rm -f $@ ; false) 242 (rm -f $@ ; false)
243 243
244quiet_cmd_lzo = LZO $@ 244quiet_cmd_lzo = LZO $@
245cmd_lzo = (cat $(filter-out FORCE,$^) | \ 245cmd_lzo = (cat $(filter-out FORCE,$^) | \
246 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ 246 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
247 (rm -f $@ ; false) 247 (rm -f $@ ; false)
diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl
index 676ddc07d6fa..97b2c6143fe4 100755
--- a/scripts/checkincludes.pl
+++ b/scripts/checkincludes.pl
@@ -11,6 +11,8 @@
11# you do have real dups and do not have them under #ifdef's. You 11# you do have real dups and do not have them under #ifdef's. You
12# could also just review the results. 12# could also just review the results.
13 13
14use strict;
15
14sub usage { 16sub usage {
15 print "Usage: checkincludes.pl [-r]\n"; 17 print "Usage: checkincludes.pl [-r]\n";
16 print "By default we just warn of duplicates\n"; 18 print "By default we just warn of duplicates\n";
@@ -35,23 +37,24 @@ if ($#ARGV >= 1) {
35 } 37 }
36} 38}
37 39
38foreach $file (@ARGV) { 40foreach my $file (@ARGV) {
39 open(FILE, $file) or die "Cannot open $file: $!.\n"; 41 open(my $f, '<', $file)
42 or die "Cannot open $file: $!.\n";
40 43
41 my %includedfiles = (); 44 my %includedfiles = ();
42 my @file_lines = (); 45 my @file_lines = ();
43 46
44 while (<FILE>) { 47 while (<$f>) {
45 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 48 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
46 ++$includedfiles{$1}; 49 ++$includedfiles{$1};
47 } 50 }
48 push(@file_lines, $_); 51 push(@file_lines, $_);
49 } 52 }
50 53
51 close(FILE); 54 close($f);
52 55
53 if (!$remove) { 56 if (!$remove) {
54 foreach $filename (keys %includedfiles) { 57 foreach my $filename (keys %includedfiles) {
55 if ($includedfiles{$filename} > 1) { 58 if ($includedfiles{$filename} > 1) {
56 print "$file: $filename is included more than once.\n"; 59 print "$file: $filename is included more than once.\n";
57 } 60 }
@@ -59,27 +62,28 @@ foreach $file (@ARGV) {
59 next; 62 next;
60 } 63 }
61 64
62 open(FILE,">$file") || die("Cannot write to $file: $!"); 65 open($f, '>', $file)
66 or die("Cannot write to $file: $!");
63 67
64 my $dups = 0; 68 my $dups = 0;
65 foreach (@file_lines) { 69 foreach (@file_lines) {
66 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 70 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
67 foreach $filename (keys %includedfiles) { 71 foreach my $filename (keys %includedfiles) {
68 if ($1 eq $filename) { 72 if ($1 eq $filename) {
69 if ($includedfiles{$filename} > 1) { 73 if ($includedfiles{$filename} > 1) {
70 $includedfiles{$filename}--; 74 $includedfiles{$filename}--;
71 $dups++; 75 $dups++;
72 } else { 76 } else {
73 print FILE $_; 77 print {$f} $_;
74 } 78 }
75 } 79 }
76 } 80 }
77 } else { 81 } else {
78 print FILE $_; 82 print {$f} $_;
79 } 83 }
80 } 84 }
81 if ($dups > 0) { 85 if ($dups > 0) {
82 print "$file: removed $dups duplicate includes\n"; 86 print "$file: removed $dups duplicate includes\n";
83 } 87 }
84 close(FILE); 88 close($f);
85} 89}
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index 14ee68e991dd..1afff6658a7d 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -21,6 +21,8 @@
21# 21#
22# TODO : Port to all architectures (one regex per arch) 22# TODO : Port to all architectures (one regex per arch)
23 23
24use strict;
25
24# check for arch 26# check for arch
25# 27#
26# $re is used for two matches: 28# $re is used for two matches:
@@ -104,19 +106,11 @@ my (@stack, $re, $dre, $x, $xs);
104 } 106 }
105} 107}
106 108
107sub bysize($) {
108 my ($asize, $bsize);
109 ($asize = $a) =~ s/.*: *(.*)$/$1/;
110 ($bsize = $b) =~ s/.*: *(.*)$/$1/;
111 $bsize <=> $asize
112}
113
114# 109#
115# main() 110# main()
116# 111#
117my $funcre = qr/^$x* <(.*)>:$/; 112my $funcre = qr/^$x* <(.*)>:$/;
118my $func; 113my ($func, $file, $lastslash);
119my $file, $lastslash;
120 114
121while (my $line = <STDIN>) { 115while (my $line = <STDIN>) {
122 if ($line =~ m/$funcre/) { 116 if ($line =~ m/$funcre/) {
@@ -173,4 +167,6 @@ while (my $line = <STDIN>) {
173 } 167 }
174} 168}
175 169
176print sort bysize @stack; 170# Sort output by size (last field)
171print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
172
diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl
index ec7d21161bdc..b444e89a0095 100755
--- a/scripts/checkversion.pl
+++ b/scripts/checkversion.pl
@@ -5,23 +5,22 @@
5# including <linux/version.h> that don't need it. 5# including <linux/version.h> that don't need it.
6# Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net> 6# Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net>
7 7
8use strict;
9
8$| = 1; 10$| = 1;
9 11
10my $debugging = 0; 12my $debugging;
11 13
12foreach $file (@ARGV) 14foreach my $file (@ARGV) {
13{
14 # Open this file. 15 # Open this file.
15 open(FILE, $file) || die "Can't open $file: $!\n"; 16 open( my $f, '<', $file )
17 or die "Can't open $file: $!\n";
16 18
17 # Initialize variables. 19 # Initialize variables.
18 my $fInComment = 0; 20 my ($fInComment, $fInString, $fUseVersion);
19 my $fInString = 0;
20 my $fUseVersion = 0;
21 my $iLinuxVersion = 0; 21 my $iLinuxVersion = 0;
22 22
23 LINE: while ( <FILE> ) 23 while (<$f>) {
24 {
25 # Strip comments. 24 # Strip comments.
26 $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); 25 $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
27 m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); 26 m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
@@ -43,8 +42,8 @@ foreach $file (@ARGV)
43 # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE 42 # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE
44 if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) { 43 if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) {
45 $fUseVersion = 1; 44 $fUseVersion = 1;
46 last LINE if $iLinuxVersion; 45 last if $iLinuxVersion;
47 } 46 }
48 } 47 }
49 48
50 # Report used version IDs without include? 49 # Report used version IDs without include?
@@ -67,5 +66,5 @@ foreach $file (@ARGV)
67 } 66 }
68 } 67 }
69 68
70 close(FILE); 69 close($f);
71} 70}
diff --git a/scripts/decodecode b/scripts/decodecode
index 4b00647814bc..8b30cc36744f 100755
--- a/scripts/decodecode
+++ b/scripts/decodecode
@@ -7,7 +7,7 @@
7# AFLAGS=--32 decodecode < 386.oops 7# AFLAGS=--32 decodecode < 386.oops
8 8
9cleanup() { 9cleanup() {
10 rm -f $T $T.s $T.o $T.oo $T.aa $T.aaa 10 rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
11 exit 1 11 exit 1
12} 12}
13 13
@@ -39,6 +39,29 @@ fi
39echo $code 39echo $code
40code=`echo $code | sed -e 's/.*Code: //'` 40code=`echo $code | sed -e 's/.*Code: //'`
41 41
42width=`expr index "$code" ' '`
43width=$[($width-1)/2]
44case $width in
451) type=byte ;;
462) type=2byte ;;
474) type=4byte ;;
48esac
49
50disas() {
51 ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null
52
53 if [ "$ARCH" == "arm" ]; then
54 if [ $width == 2 ]; then
55 OBJDUMPFLAGS="-M force-thumb"
56 fi
57
58 ${CROSS_COMPILE}strip $1.o
59 fi
60
61 ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
62 grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis
63}
64
42marker=`expr index "$code" "\<"` 65marker=`expr index "$code" "\<"`
43if [ $marker -eq 0 ]; then 66if [ $marker -eq 0 ]; then
44 marker=`expr index "$code" "\("` 67 marker=`expr index "$code" "\("`
@@ -49,26 +72,25 @@ if [ $marker -ne 0 ]; then
49 echo All code >> $T.oo 72 echo All code >> $T.oo
50 echo ======== >> $T.oo 73 echo ======== >> $T.oo
51 beforemark=`echo "$code"` 74 beforemark=`echo "$code"`
52 echo -n " .byte 0x" > $T.s 75 echo -n " .$type 0x" > $T.s
53 echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's/<//g' | sed -e 's/>//g' >> $T.s 76 echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
54 as $AFLAGS -o $T.o $T.s &> /dev/null 77 disas $T
55 objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo 78 cat $T.dis >> $T.oo
56 cat $T.ooo >> $T.oo 79 rm -f $T.o $T.s $T.dis
57 rm -f $T.o $T.s $T.ooo
58 80
59# and fix code at-and-after marker 81# and fix code at-and-after marker
60 code=`echo "$code" | cut -c$((${marker} + 1))-` 82 code=`echo "$code" | cut -c$((${marker} + 1))-`
61fi 83fi
62echo Code starting with the faulting instruction > $T.aa 84echo Code starting with the faulting instruction > $T.aa
63echo =========================================== >> $T.aa 85echo =========================================== >> $T.aa
64code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'` 86code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
65echo -n " .byte 0x" > $T.s 87echo -n " .$type 0x" > $T.s
66echo $code >> $T.s 88echo $code >> $T.s
67as $AFLAGS -o $T.o $T.s &> /dev/null 89disas $T
68objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa 90cat $T.dis >> $T.aa
69cat $T.aaa >> $T.aa
70 91
71faultline=`cat $T.aaa | head -1 | cut -d":" -f2` 92faultline=`cat $T.dis | head -1 | cut -d":" -f2`
93faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
72 94
73cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g" 95cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g"
74echo 96echo
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
index 705b5ba7c152..04dce7c15f83 100644
--- a/scripts/export_report.pl
+++ b/scripts/export_report.pl
@@ -49,10 +49,10 @@ sub usage {
49} 49}
50 50
51sub collectcfiles { 51sub collectcfiles {
52 my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`; 52 my @file
53 @file = grep {s/\.ko/.mod.c/} @file; 53 = `cat .tmp_versions/*.mod | grep '.*\.ko\$' | sed s/\.ko$/.mod.c/`;
54 chomp @file; 54 chomp @file;
55 return @file; 55 return @file;
56} 56}
57 57
58my (%SYMBOL, %MODULE, %opt, @allcfiles); 58my (%SYMBOL, %MODULE, %opt, @allcfiles);
@@ -71,37 +71,40 @@ if (not defined $opt{'k'}) {
71 $opt{'k'} = "Module.symvers"; 71 $opt{'k'} = "Module.symvers";
72} 72}
73 73
74unless (open(MODULE_SYMVERS, $opt{'k'})) { 74open (my $module_symvers, '<', $opt{'k'})
75 die "Sorry, cannot open $opt{'k'}: $!\n"; 75 or die "Sorry, cannot open $opt{'k'}: $!\n";
76}
77 76
78if (defined $opt{'o'}) { 77if (defined $opt{'o'}) {
79 unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) { 78 open (my $out, '>', $opt{'o'})
80 die "Sorry, cannot open $opt{'o'} $!\n"; 79 or die "Sorry, cannot open $opt{'o'} $!\n";
81 } 80
82 select OUTPUT_HANDLE; 81 select $out;
83} 82}
83
84# 84#
85# collect all the symbols and their attributes from the 85# collect all the symbols and their attributes from the
86# Module.symvers file 86# Module.symvers file
87# 87#
88while ( <MODULE_SYMVERS> ) { 88while ( <$module_symvers> ) {
89 chomp; 89 chomp;
90 my (undef, $symbol, $module, $gpl) = split; 90 my (undef, $symbol, $module, $gpl) = split;
91 $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; 91 $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl];
92} 92}
93close(MODULE_SYMVERS); 93close($module_symvers);
94 94
95# 95#
96# collect the usage count of each symbol. 96# collect the usage count of each symbol.
97# 97#
98foreach my $thismod (@allcfiles) { 98foreach my $thismod (@allcfiles) {
99 unless (open(MODULE_MODULE, $thismod)) { 99 my $module;
100 print "Sorry, cannot open $thismod: $!\n"; 100
101 unless (open ($module, '<', $thismod)) {
102 warn "Sorry, cannot open $thismod: $!\n";
101 next; 103 next;
102 } 104 }
105
103 my $state=0; 106 my $state=0;
104 while ( <MODULE_MODULE> ) { 107 while ( <$module> ) {
105 chomp; 108 chomp;
106 if ($state == 0) { 109 if ($state == 0) {
107 $state = 1 if ($_ =~ /static const struct modversion_info/); 110 $state = 1 if ($_ =~ /static const struct modversion_info/);
@@ -124,7 +127,7 @@ foreach my $thismod (@allcfiles) {
124 if ($state != 2) { 127 if ($state != 2) {
125 print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n"; 128 print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
126 } 129 }
127 close(MODULE_MODULE); 130 close($module);
128} 131}
129 132
130print "\tThis file reports the exported symbols usage patterns by in-tree\n", 133print "\tThis file reports the exported symbols usage patterns by in-tree\n",
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index a932ae52f921..5958fffb2114 100644
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -202,6 +202,7 @@ input_file() {
202 print_mtime "$1" >> ${output} 202 print_mtime "$1" >> ${output}
203 cat "$1" >> ${output} 203 cat "$1" >> ${output}
204 else 204 else
205 echo "$1 \\"
205 cat "$1" | while read type dir file perm ; do 206 cat "$1" | while read type dir file perm ; do
206 if [ "$type" == "file" ]; then 207 if [ "$type" == "file" ]; then
207 echo "$file \\"; 208 echo "$file \\";
@@ -231,7 +232,7 @@ arg="$1"
231case "$arg" in 232case "$arg" in
232 "-l") # files included in initramfs - used by kbuild 233 "-l") # files included in initramfs - used by kbuild
233 dep_list="list_" 234 dep_list="list_"
234 echo "deps_initramfs := \\" 235 echo "deps_initramfs := $0 \\"
235 shift 236 shift
236 ;; 237 ;;
237 "-o") # generate compressed cpio image named $1 238 "-o") # generate compressed cpio image named $1
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index af6b8363a2d5..f99115ebe925 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -758,8 +758,10 @@ int main(int argc, char **argv)
758 /* setlinebuf(debugfile); */ 758 /* setlinebuf(debugfile); */
759 } 759 }
760 760
761 if (flag_reference) 761 if (flag_reference) {
762 read_reference(ref_file); 762 read_reference(ref_file);
763 fclose(ref_file);
764 }
763 765
764 yyparse(); 766 yyparse();
765 767
diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl
index b7f6c560e24d..8dd019bc5a73 100755
--- a/scripts/headerdep.pl
+++ b/scripts/headerdep.pl
@@ -80,8 +80,7 @@ sub search {
80 my $path = "$i/$filename"; 80 my $path = "$i/$filename";
81 return $path if -f $path; 81 return $path if -f $path;
82 } 82 }
83 83 return;
84 return undef;
85} 84}
86 85
87sub parse_all { 86sub parse_all {
diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl
index db1dd7a549f2..50d6cfd1fa77 100644
--- a/scripts/headers_check.pl
+++ b/scripts/headers_check.pl
@@ -28,11 +28,12 @@ my $lineno = 0;
28my $filename; 28my $filename;
29 29
30foreach my $file (@files) { 30foreach my $file (@files) {
31 local *FH;
32 $filename = $file; 31 $filename = $file;
33 open(FH, "<$filename") or die "$filename: $!\n"; 32
33 open(my $fh, '<', $filename)
34 or die "$filename: $!\n";
34 $lineno = 0; 35 $lineno = 0;
35 while ($line = <FH>) { 36 while ($line = <$fh>) {
36 $lineno++; 37 $lineno++;
37 &check_include(); 38 &check_include();
38 &check_asm_types(); 39 &check_asm_types();
@@ -40,7 +41,7 @@ foreach my $file (@files) {
40 &check_declarations(); 41 &check_declarations();
41 # Dropped for now. Too much noise &check_config(); 42 # Dropped for now. Too much noise &check_config();
42 } 43 }
43 close FH; 44 close $fh;
44} 45}
45exit $ret; 46exit $ret;
46 47
@@ -78,7 +79,7 @@ sub check_config
78} 79}
79 80
80my $linux_asm_types; 81my $linux_asm_types;
81sub check_asm_types() 82sub check_asm_types
82{ 83{
83 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { 84 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
84 return; 85 return;
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl
index b89ca2c58fdb..4ca3be3b2e50 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -23,13 +23,13 @@ my ($readdir, $installdir, $arch, @files) = @ARGV;
23my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__"; 23my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
24 24
25foreach my $file (@files) { 25foreach my $file (@files) {
26 local *INFILE;
27 local *OUTFILE;
28 my $tmpfile = "$installdir/$file.tmp"; 26 my $tmpfile = "$installdir/$file.tmp";
29 open(INFILE, "<$readdir/$file") 27
30 or die "$readdir/$file: $!\n"; 28 open(my $in, '<', "$readdir/$file")
31 open(OUTFILE, ">$tmpfile") or die "$tmpfile: $!\n"; 29 or die "$readdir/$file: $!\n";
32 while (my $line = <INFILE>) { 30 open(my $out, '>', $tmpfile)
31 or die "$tmpfile: $!\n";
32 while (my $line = <$in>) {
33 $line =~ s/([\s(])__user\s/$1/g; 33 $line =~ s/([\s(])__user\s/$1/g;
34 $line =~ s/([\s(])__force\s/$1/g; 34 $line =~ s/([\s(])__force\s/$1/g;
35 $line =~ s/([\s(])__iomem\s/$1/g; 35 $line =~ s/([\s(])__iomem\s/$1/g;
@@ -39,10 +39,11 @@ foreach my $file (@files) {
39 $line =~ s/(^|\s)(inline)\b/$1__$2__/g; 39 $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
40 $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g; 40 $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
41 $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g; 41 $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
42 printf OUTFILE "%s", $line; 42 printf {$out} "%s", $line;
43 } 43 }
44 close OUTFILE; 44 close $out;
45 close INFILE; 45 close $in;
46
46 system $unifdef . " $tmpfile > $installdir/$file"; 47 system $unifdef . " $tmpfile > $installdir/$file";
47 unlink $tmpfile; 48 unlink $tmpfile;
48} 49}
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 86c3896a1e01..e3902fb39afd 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -108,8 +108,10 @@ static int read_symbol(FILE *in, struct sym_entry *s)
108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); 108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
109 if (rc != 3) { 109 if (rc != 3) {
110 if (rc != EOF) { 110 if (rc != EOF) {
111 /* skip line */ 111 /* skip line. sym is used as dummy to
112 fgets(str, 500, in); 112 * shut of "warn_unused_result" warning.
113 */
114 sym = fgets(str, 500, in);
113 } 115 }
114 return -1; 116 return -1;
115 } 117 }
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 186c46604d06..7ea649da1940 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -23,6 +23,9 @@ menuconfig: $(obj)/mconf
23config: $(obj)/conf 23config: $(obj)/conf
24 $< $(Kconfig) 24 $< $(Kconfig)
25 25
26nconfig: $(obj)/nconf
27 $< $(Kconfig)
28
26oldconfig: $(obj)/conf 29oldconfig: $(obj)/conf
27 $< -o $(Kconfig) 30 $< -o $(Kconfig)
28 31
@@ -120,6 +123,7 @@ endif
120# Help text used by make help 123# Help text used by make help
121help: 124help:
122 @echo ' config - Update current config utilising a line-oriented program' 125 @echo ' config - Update current config utilising a line-oriented program'
126 @echo ' nconfig - Update current config utilising a ncurses menu based program'
123 @echo ' menuconfig - Update current config utilising a menu based program' 127 @echo ' menuconfig - Update current config utilising a menu based program'
124 @echo ' xconfig - Update current config utilising a QT based front-end' 128 @echo ' xconfig - Update current config utilising a QT based front-end'
125 @echo ' gconfig - Update current config utilising a GTK based front-end' 129 @echo ' gconfig - Update current config utilising a GTK based front-end'
@@ -147,6 +151,8 @@ HOST_EXTRACFLAGS += -DLOCALE
147# =========================================================================== 151# ===========================================================================
148# Shared Makefile for the various kconfig executables: 152# Shared Makefile for the various kconfig executables:
149# conf: Used for defconfig, oldconfig and related targets 153# conf: Used for defconfig, oldconfig and related targets
154# nconf: Used for the nconfig target.
155# Utilizes ncurses
150# mconf: Used for the menuconfig target 156# mconf: Used for the menuconfig target
151# Utilizes the lxdialog package 157# Utilizes the lxdialog package
152# qconf: Used for the xconfig target 158# qconf: Used for the xconfig target
@@ -159,11 +165,16 @@ lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
159lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o 165lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
160 166
161conf-objs := conf.o zconf.tab.o 167conf-objs := conf.o zconf.tab.o
162mconf-objs := mconf.o zconf.tab.o $(lxdialog) 168mconf-objs := mconf.o zconf.tab.o $(lxdialog)
169nconf-objs := nconf.o zconf.tab.o nconf.gui.o
163kxgettext-objs := kxgettext.o zconf.tab.o 170kxgettext-objs := kxgettext.o zconf.tab.o
164 171
165hostprogs-y := conf qconf gconf kxgettext 172hostprogs-y := conf qconf gconf kxgettext
166 173
174ifeq ($(MAKECMDGOALS),nconfig)
175 hostprogs-y += nconf
176endif
177
167ifeq ($(MAKECMDGOALS),menuconfig) 178ifeq ($(MAKECMDGOALS),menuconfig)
168 hostprogs-y += mconf 179 hostprogs-y += mconf
169endif 180endif
@@ -187,7 +198,7 @@ endif
187 198
188clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ 199clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
189 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h 200 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
190clean-files += mconf qconf gconf 201clean-files += mconf qconf gconf nconf
191clean-files += config.pot linux.pot 202clean-files += config.pot linux.pot
192 203
193# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) 204# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
@@ -208,10 +219,11 @@ HOSTCFLAGS_zconf.tab.o := -I$(src)
208HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl 219HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl
209HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK 220HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK
210 221
211HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` 222HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl
212HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ 223HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
213 -D LKC_DIRECT_LINK 224 -D LKC_DIRECT_LINK
214 225
226HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses
215$(obj)/qconf.o: $(obj)/.tmp_qtcheck 227$(obj)/qconf.o: $(obj)/.tmp_qtcheck
216 228
217ifeq ($(qconf-target),1) 229ifeq ($(qconf-target),1)
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index edd3f39a080a..d83f2322893a 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1097,9 +1097,32 @@ void expr_fprint(struct expr *e, FILE *out)
1097 1097
1098static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) 1098static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1099{ 1099{
1100 str_append((struct gstr*)data, str); 1100 struct gstr *gs = (struct gstr*)data;
1101 const char *sym_str = NULL;
1102
1103 if (sym)
1104 sym_str = sym_get_string_value(sym);
1105
1106 if (gs->max_width) {
1107 unsigned extra_length = strlen(str);
1108 const char *last_cr = strrchr(gs->s, '\n');
1109 unsigned last_line_length;
1110
1111 if (sym_str)
1112 extra_length += 4 + strlen(sym_str);
1113
1114 if (!last_cr)
1115 last_cr = gs->s;
1116
1117 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1118
1119 if ((last_line_length + extra_length) > gs->max_width)
1120 str_append(gs, "\\\n");
1121 }
1122
1123 str_append(gs, str);
1101 if (sym) 1124 if (sym)
1102 str_printf((struct gstr*)data, " [=%s]", sym_get_string_value(sym)); 1125 str_printf(gs, " [=%s]", sym_str);
1103} 1126}
1104 1127
1105void expr_gstr_print(struct expr *e, struct gstr *gs) 1128void expr_gstr_print(struct expr *e, struct gstr *gs)
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 6408fefae083..891cd9ce9ba2 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -86,7 +86,7 @@ struct symbol {
86 struct expr_value rev_dep; 86 struct expr_value rev_dep;
87}; 87};
88 88
89#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) 89#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
90 90
91#define SYMBOL_CONST 0x0001 /* symbol is const */ 91#define SYMBOL_CONST 0x0001 /* symbol is const */
92#define SYMBOL_CHECK 0x0008 /* used during dependency checking */ 92#define SYMBOL_CHECK 0x0008 /* used during dependency checking */
@@ -108,8 +108,7 @@ struct symbol {
108#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ 108#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */
109 109
110#define SYMBOL_MAXLENGTH 256 110#define SYMBOL_MAXLENGTH 256
111#define SYMBOL_HASHSIZE 257 111#define SYMBOL_HASHSIZE 9973
112#define SYMBOL_HASHMASK 0xff
113 112
114/* A property represent the config options that can be associated 113/* A property represent the config options that can be associated
115 * with a config "symbol". 114 * with a config "symbol".
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 65464366fe38..bef10411837f 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -30,13 +30,16 @@ enum {
30 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW 30 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
31}; 31};
32 32
33enum {
34 OPT_NORMAL, OPT_ALL, OPT_PROMPT
35};
36
33static gint view_mode = FULL_VIEW; 37static gint view_mode = FULL_VIEW;
34static gboolean show_name = TRUE; 38static gboolean show_name = TRUE;
35static gboolean show_range = TRUE; 39static gboolean show_range = TRUE;
36static gboolean show_value = TRUE; 40static gboolean show_value = TRUE;
37static gboolean show_all = FALSE;
38static gboolean show_debug = FALSE;
39static gboolean resizeable = FALSE; 41static gboolean resizeable = FALSE;
42static int opt_mode = OPT_NORMAL;
40 43
41GtkWidget *main_wnd = NULL; 44GtkWidget *main_wnd = NULL;
42GtkWidget *tree1_w = NULL; // left frame 45GtkWidget *tree1_w = NULL; // left frame
@@ -76,36 +79,7 @@ static void conf_changed(void);
76 79
77/* Helping/Debugging Functions */ 80/* Helping/Debugging Functions */
78 81
79 82const char *dbg_sym_flags(int val)
80const char *dbg_print_stype(int val)
81{
82 static char buf[256];
83
84 bzero(buf, 256);
85
86 if (val == S_UNKNOWN)
87 strcpy(buf, "unknown");
88 if (val == S_BOOLEAN)
89 strcpy(buf, "boolean");
90 if (val == S_TRISTATE)
91 strcpy(buf, "tristate");
92 if (val == S_INT)
93 strcpy(buf, "int");
94 if (val == S_HEX)
95 strcpy(buf, "hex");
96 if (val == S_STRING)
97 strcpy(buf, "string");
98 if (val == S_OTHER)
99 strcpy(buf, "other");
100
101#ifdef DEBUG
102 printf("%s", buf);
103#endif
104
105 return buf;
106}
107
108const char *dbg_print_flags(int val)
109{ 83{
110 static char buf[256]; 84 static char buf[256];
111 85
@@ -131,40 +105,10 @@ const char *dbg_print_flags(int val)
131 strcat(buf, "auto/"); 105 strcat(buf, "auto/");
132 106
133 buf[strlen(buf) - 1] = '\0'; 107 buf[strlen(buf) - 1] = '\0';
134#ifdef DEBUG
135 printf("%s", buf);
136#endif
137
138 return buf;
139}
140
141const char *dbg_print_ptype(int val)
142{
143 static char buf[256];
144
145 bzero(buf, 256);
146
147 if (val == P_UNKNOWN)
148 strcpy(buf, "unknown");
149 if (val == P_PROMPT)
150 strcpy(buf, "prompt");
151 if (val == P_COMMENT)
152 strcpy(buf, "comment");
153 if (val == P_MENU)
154 strcpy(buf, "menu");
155 if (val == P_DEFAULT)
156 strcpy(buf, "default");
157 if (val == P_CHOICE)
158 strcpy(buf, "choice");
159
160#ifdef DEBUG
161 printf("%s", buf);
162#endif
163 108
164 return buf; 109 return buf;
165} 110}
166 111
167
168void replace_button_icon(GladeXML * xml, GdkDrawable * window, 112void replace_button_icon(GladeXML * xml, GdkDrawable * window,
169 GtkStyle * style, gchar * btn_name, gchar ** xpm) 113 GtkStyle * style, gchar * btn_name, gchar ** xpm)
170{ 114{
@@ -697,20 +641,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
697 641
698 642
699void 643void
700on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) 644on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
701{ 645{
702 show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; 646 opt_mode = OPT_NORMAL;
647 gtk_tree_store_clear(tree2);
648 display_tree(&rootmenu); /* instead of update_tree to speed-up */
649}
650
703 651
652void
653on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
654{
655 opt_mode = OPT_ALL;
704 gtk_tree_store_clear(tree2); 656 gtk_tree_store_clear(tree2);
705 display_tree(&rootmenu); // instead of update_tree to speed-up 657 display_tree(&rootmenu); /* instead of update_tree to speed-up */
706} 658}
707 659
708 660
709void 661void
710on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) 662on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
711{ 663{
712 show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; 664 opt_mode = OPT_PROMPT;
713 update_tree(&rootmenu, NULL); 665 gtk_tree_store_clear(tree2);
666 display_tree(&rootmenu); /* instead of update_tree to speed-up */
714} 667}
715 668
716 669
@@ -1163,7 +1116,10 @@ static gchar **fill_row(struct menu *menu)
1163 g_strdup_printf("%s %s", _(menu_get_prompt(menu)), 1116 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1164 sym && sym_has_value(sym) ? "(NEW)" : ""); 1117 sym && sym_has_value(sym) ? "(NEW)" : "");
1165 1118
1166 if (show_all && !menu_is_visible(menu)) 1119 if (opt_mode == OPT_ALL && !menu_is_visible(menu))
1120 row[COL_COLOR] = g_strdup("DarkGray");
1121 else if (opt_mode == OPT_PROMPT &&
1122 menu_has_prompt(menu) && !menu_is_visible(menu))
1167 row[COL_COLOR] = g_strdup("DarkGray"); 1123 row[COL_COLOR] = g_strdup("DarkGray");
1168 else 1124 else
1169 row[COL_COLOR] = g_strdup("Black"); 1125 row[COL_COLOR] = g_strdup("Black");
@@ -1386,16 +1342,19 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
1386 menu2 ? menu_get_prompt(menu2) : "nil"); 1342 menu2 ? menu_get_prompt(menu2) : "nil");
1387#endif 1343#endif
1388 1344
1389 if (!menu_is_visible(child1) && !show_all) { // remove node 1345 if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1346 (opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) {
1347
1348 /* remove node */
1390 if (gtktree_iter_find_node(dst, menu1) != NULL) { 1349 if (gtktree_iter_find_node(dst, menu1) != NULL) {
1391 memcpy(&tmp, child2, sizeof(GtkTreeIter)); 1350 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1392 valid = gtk_tree_model_iter_next(model2, 1351 valid = gtk_tree_model_iter_next(model2,
1393 child2); 1352 child2);
1394 gtk_tree_store_remove(tree2, &tmp); 1353 gtk_tree_store_remove(tree2, &tmp);
1395 if (!valid) 1354 if (!valid)
1396 return; // next parent 1355 return; /* next parent */
1397 else 1356 else
1398 goto reparse; // next child 1357 goto reparse; /* next child */
1399 } else 1358 } else
1400 continue; 1359 continue;
1401 } 1360 }
@@ -1464,17 +1423,19 @@ static void display_tree(struct menu *menu)
1464 && (tree == tree2)) 1423 && (tree == tree2))
1465 continue; 1424 continue;
1466 1425
1467 if (menu_is_visible(child) || show_all) 1426 if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
1427 (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1428 (opt_mode == OPT_ALL))
1468 place_node(child, fill_row(child)); 1429 place_node(child, fill_row(child));
1469#ifdef DEBUG 1430#ifdef DEBUG
1470 printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); 1431 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1471 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); 1432 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
1472 dbg_print_ptype(ptype); 1433 printf("%s", prop_get_type_name(ptype));
1473 printf(" | "); 1434 printf(" | ");
1474 if (sym) { 1435 if (sym) {
1475 dbg_print_stype(sym->type); 1436 printf("%s", sym_type_name(sym->type));
1476 printf(" | "); 1437 printf(" | ");
1477 dbg_print_flags(sym->flags); 1438 printf("%s", dbg_sym_flags(sym->flags));
1478 printf("\n"); 1439 printf("\n");
1479 } else 1440 } else
1480 printf("\n"); 1441 printf("\n");
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
index b1c86c19292c..d52b0a75d824 100644
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.glade
@@ -190,26 +190,40 @@
190 </child> 190 </child>
191 191
192 <child> 192 <child>
193 <widget class="GtkCheckMenuItem" id="show_all_options1"> 193 <widget class="GtkRadioMenuItem" id="set_option_mode1">
194 <property name="visible">True</property>
195 <property name="tooltip" translatable="yes">Show normal options</property>
196 <property name="label" translatable="yes">Show normal options</property>
197 <property name="use_underline">True</property>
198 <property name="active">True</property>
199 <signal name="activate" handler="on_set_option_mode1_activate"/>
200 </widget>
201 </child>
202
203 <child>
204 <widget class="GtkRadioMenuItem" id="set_option_mode2">
194 <property name="visible">True</property> 205 <property name="visible">True</property>
195 <property name="tooltip" translatable="yes">Show all options</property> 206 <property name="tooltip" translatable="yes">Show all options</property>
196 <property name="label" translatable="yes">Show all _options</property> 207 <property name="label" translatable="yes">Show all _options</property>
197 <property name="use_underline">True</property> 208 <property name="use_underline">True</property>
198 <property name="active">False</property> 209 <property name="active">False</property>
199 <signal name="activate" handler="on_show_all_options1_activate"/> 210 <property name="group">set_option_mode1</property>
211 <signal name="activate" handler="on_set_option_mode2_activate"/>
200 </widget> 212 </widget>
201 </child> 213 </child>
202 214
203 <child> 215 <child>
204 <widget class="GtkCheckMenuItem" id="show_debug_info1"> 216 <widget class="GtkRadioMenuItem" id="set_option_mode3">
205 <property name="visible">True</property> 217 <property name="visible">True</property>
206 <property name="tooltip" translatable="yes">Show masked options</property> 218 <property name="tooltip" translatable="yes">Show all options with prompts</property>
207 <property name="label" translatable="yes">Show _debug info</property> 219 <property name="label" translatable="yes">Show all prompt options</property>
208 <property name="use_underline">True</property> 220 <property name="use_underline">True</property>
209 <property name="active">False</property> 221 <property name="active">False</property>
210 <signal name="activate" handler="on_show_debug_info1_activate"/> 222 <property name="group">set_option_mode1</property>
223 <signal name="activate" handler="on_set_option_mode3_activate"/>
211 </widget> 224 </widget>
212 </child> 225 </child>
226
213 </widget> 227 </widget>
214 </child> 228 </child>
215 </widget> 229 </widget>
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index f379b0bf8c9e..ce6549cdaccf 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -84,7 +84,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode);
84void kconfig_load(void); 84void kconfig_load(void);
85 85
86/* menu.c */ 86/* menu.c */
87void menu_init(void); 87void _menu_init(void);
88void menu_warn(struct menu *menu, const char *fmt, ...); 88void menu_warn(struct menu *menu, const char *fmt, ...);
89struct menu *menu_add_menu(void); 89struct menu *menu_add_menu(void);
90void menu_end_menu(void); 90void menu_end_menu(void);
@@ -106,6 +106,11 @@ int file_write_dep(const char *name);
106struct gstr { 106struct gstr {
107 size_t len; 107 size_t len;
108 char *s; 108 char *s;
109 /*
110 * when max_width is not zero long lines in string s (if any) get
111 * wrapped not to exceed the max_width value
112 */
113 int max_width;
109}; 114};
110struct gstr str_new(void); 115struct gstr str_new(void);
111struct gstr str_assign(const char *s); 116struct gstr str_assign(const char *s);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index ffeb532b2cff..7cadcad8233b 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -11,13 +11,15 @@ P(conf_set_changed_callback, void,(void (*fn)(void)));
11/* menu.c */ 11/* menu.c */
12P(rootmenu,struct menu,); 12P(rootmenu,struct menu,);
13 13
14P(menu_is_visible,bool,(struct menu *menu)); 14P(menu_is_visible, bool, (struct menu *menu));
15P(menu_has_prompt, bool, (struct menu *menu));
15P(menu_get_prompt,const char *,(struct menu *menu)); 16P(menu_get_prompt,const char *,(struct menu *menu));
16P(menu_get_root_menu,struct menu *,(struct menu *menu)); 17P(menu_get_root_menu,struct menu *,(struct menu *menu));
17P(menu_get_parent_menu,struct menu *,(struct menu *menu)); 18P(menu_get_parent_menu,struct menu *,(struct menu *menu));
18P(menu_has_help,bool,(struct menu *menu)); 19P(menu_has_help,bool,(struct menu *menu));
19P(menu_get_help,const char *,(struct menu *menu)); 20P(menu_get_help,const char *,(struct menu *menu));
20P(get_symbol_str,void,(struct gstr *r, struct symbol *sym)); 21P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
22P(get_relations_str, struct gstr, (struct symbol **sym_arr));
21P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); 23P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
22 24
23/* symbol.c */ 25/* symbol.c */
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 616c60138183..dd8e587c50e2 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -180,7 +180,7 @@ do_resize:
180 case KEY_LEFT: 180 case KEY_LEFT:
181 switch (button) { 181 switch (button) {
182 case -1: 182 case -1:
183 button = 1; /* Indicates "Cancel" button is selected */ 183 button = 1; /* Indicates "Help" button is selected */
184 print_buttons(dialog, height, width, 1); 184 print_buttons(dialog, height, width, 1);
185 break; 185 break;
186 case 0: 186 case 0:
@@ -204,7 +204,7 @@ do_resize:
204 print_buttons(dialog, height, width, 0); 204 print_buttons(dialog, height, width, 0);
205 break; 205 break;
206 case 0: 206 case 0:
207 button = 1; /* Indicates "Cancel" button is selected */ 207 button = 1; /* Indicates "Help" button is selected */
208 print_buttons(dialog, height, width, 1); 208 print_buttons(dialog, height, width, 1);
209 break; 209 break;
210 case 1: 210 case 1:
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index fa9d633f293c..1d604738fa13 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -383,6 +383,10 @@ do_resize:
383 case 'n': 383 case 'n':
384 case 'm': 384 case 'm':
385 case '/': 385 case '/':
386 case 'h':
387 case '?':
388 case 'z':
389 case '\n':
386 /* save scroll info */ 390 /* save scroll info */
387 *s_scroll = scroll; 391 *s_scroll = scroll;
388 delwin(menu); 392 delwin(menu);
@@ -390,8 +394,10 @@ do_resize:
390 item_set(scroll + choice); 394 item_set(scroll + choice);
391 item_set_selected(1); 395 item_set_selected(1);
392 switch (key) { 396 switch (key) {
397 case 'h':
398 case '?':
399 return 2;
393 case 's': 400 case 's':
394 return 3;
395 case 'y': 401 case 'y':
396 return 3; 402 return 3;
397 case 'n': 403 case 'n':
@@ -402,18 +408,12 @@ do_resize:
402 return 6; 408 return 6;
403 case '/': 409 case '/':
404 return 7; 410 return 7;
411 case 'z':
412 return 8;
413 case '\n':
414 return button;
405 } 415 }
406 return 0; 416 return 0;
407 case 'h':
408 case '?':
409 button = 2;
410 case '\n':
411 *s_scroll = scroll;
412 delwin(menu);
413 delwin(dialog);
414 item_set(scroll + choice);
415 item_set_selected(1);
416 return button;
417 case 'e': 417 case 'e':
418 case 'x': 418 case 'x':
419 key = KEY_ESC; 419 key = KEY_ESC;
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 8413cf38ed27..2c83d3234d30 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -67,13 +67,15 @@ static const char mconf_readme[] = N_(
67" there is a delayed response which you may find annoying.\n" 67" there is a delayed response which you may find annoying.\n"
68"\n" 68"\n"
69" Also, the <TAB> and cursor keys will cycle between <Select>,\n" 69" Also, the <TAB> and cursor keys will cycle between <Select>,\n"
70" <Exit> and <Help>\n" 70" <Exit> and <Help>.\n"
71"\n" 71"\n"
72"o To get help with an item, use the cursor keys to highlight <Help>\n" 72"o To get help with an item, use the cursor keys to highlight <Help>\n"
73" and Press <ENTER>.\n" 73" and press <ENTER>.\n"
74"\n" 74"\n"
75" Shortcut: Press <H> or <?>.\n" 75" Shortcut: Press <H> or <?>.\n"
76"\n" 76"\n"
77"o To show hidden options, press <Z>.\n"
78"\n"
77"\n" 79"\n"
78"Radiolists (Choice lists)\n" 80"Radiolists (Choice lists)\n"
79"-----------\n" 81"-----------\n"
@@ -272,6 +274,7 @@ static int indent;
272static struct menu *current_menu; 274static struct menu *current_menu;
273static int child_count; 275static int child_count;
274static int single_menu_mode; 276static int single_menu_mode;
277static int show_all_options;
275 278
276static void conf(struct menu *menu); 279static void conf(struct menu *menu);
277static void conf_choice(struct menu *menu); 280static void conf_choice(struct menu *menu);
@@ -282,19 +285,6 @@ static void show_textbox(const char *title, const char *text, int r, int c);
282static void show_helptext(const char *title, const char *text); 285static void show_helptext(const char *title, const char *text);
283static void show_help(struct menu *menu); 286static void show_help(struct menu *menu);
284 287
285static struct gstr get_relations_str(struct symbol **sym_arr)
286{
287 struct symbol *sym;
288 struct gstr res = str_new();
289 int i;
290
291 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
292 get_symbol_str(&res, sym);
293 if (!i)
294 str_append(&res, _("No matches found.\n"));
295 return res;
296}
297
298static char filename[PATH_MAX+1]; 288static char filename[PATH_MAX+1];
299static void set_config_filename(const char *config_filename) 289static void set_config_filename(const char *config_filename)
300{ 290{
@@ -359,8 +349,16 @@ static void build_conf(struct menu *menu)
359 int type, tmp, doint = 2; 349 int type, tmp, doint = 2;
360 tristate val; 350 tristate val;
361 char ch; 351 char ch;
362 352 bool visible;
363 if (!menu_is_visible(menu)) 353
354 /*
355 * note: menu_is_visible() has side effect that it will
356 * recalc the value of the symbol.
357 */
358 visible = menu_is_visible(menu);
359 if (show_all_options && !menu_has_prompt(menu))
360 return;
361 else if (!show_all_options && !visible)
364 return; 362 return;
365 363
366 sym = menu->sym; 364 sym = menu->sym;
@@ -619,6 +617,9 @@ static void conf(struct menu *menu)
619 case 7: 617 case 7:
620 search_conf(); 618 search_conf();
621 break; 619 break;
620 case 8:
621 show_all_options = !show_all_options;
622 break;
622 } 623 }
623 } 624 }
624} 625}
@@ -638,6 +639,7 @@ static void show_help(struct menu *menu)
638{ 639{
639 struct gstr help = str_new(); 640 struct gstr help = str_new();
640 641
642 help.max_width = getmaxx(stdscr) - 10;
641 menu_get_ext_help(menu, &help); 643 menu_get_ext_help(menu, &help);
642 644
643 show_helptext(_(menu_get_prompt(menu)), str_get(&help)); 645 show_helptext(_(menu_get_prompt(menu)), str_get(&help));
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 059a2465c574..203632cc30bd 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -38,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...)
38 va_end(ap); 38 va_end(ap);
39} 39}
40 40
41void menu_init(void) 41void _menu_init(void)
42{ 42{
43 current_entry = current_menu = &rootmenu; 43 current_entry = current_menu = &rootmenu;
44 last_entry_ptr = &rootmenu.list; 44 last_entry_ptr = &rootmenu.list;
@@ -197,7 +197,7 @@ static void sym_check_prop(struct symbol *sym)
197 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && 197 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
198 prop->expr->type != E_SYMBOL) 198 prop->expr->type != E_SYMBOL)
199 prop_warn(prop, 199 prop_warn(prop,
200 "default for config symbol '%'" 200 "default for config symbol '%s'"
201 " must be a single symbol", sym->name); 201 " must be a single symbol", sym->name);
202 break; 202 break;
203 case P_SELECT: 203 case P_SELECT:
@@ -390,6 +390,13 @@ void menu_finalize(struct menu *parent)
390 } 390 }
391} 391}
392 392
393bool menu_has_prompt(struct menu *menu)
394{
395 if (!menu->prompt)
396 return false;
397 return true;
398}
399
393bool menu_is_visible(struct menu *menu) 400bool menu_is_visible(struct menu *menu)
394{ 401{
395 struct menu *child; 402 struct menu *child;
@@ -398,6 +405,7 @@ bool menu_is_visible(struct menu *menu)
398 405
399 if (!menu->prompt) 406 if (!menu->prompt)
400 return false; 407 return false;
408
401 sym = menu->sym; 409 sym = menu->sym;
402 if (sym) { 410 if (sym) {
403 sym_calc_value(sym); 411 sym_calc_value(sym);
@@ -407,12 +415,14 @@ bool menu_is_visible(struct menu *menu)
407 415
408 if (visible != no) 416 if (visible != no)
409 return true; 417 return true;
418
410 if (!sym || sym_get_tristate_value(menu->sym) == no) 419 if (!sym || sym_get_tristate_value(menu->sym) == no)
411 return false; 420 return false;
412 421
413 for (child = menu->list; child; child = child->next) 422 for (child = menu->list; child; child = child->next)
414 if (menu_is_visible(child)) 423 if (menu_is_visible(child))
415 return true; 424 return true;
425
416 return false; 426 return false;
417} 427}
418 428
@@ -515,6 +525,20 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
515 str_append(r, "\n\n"); 525 str_append(r, "\n\n");
516} 526}
517 527
528struct gstr get_relations_str(struct symbol **sym_arr)
529{
530 struct symbol *sym;
531 struct gstr res = str_new();
532 int i;
533
534 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
535 get_symbol_str(&res, sym);
536 if (!i)
537 str_append(&res, _("No matches found.\n"));
538 return res;
539}
540
541
518void menu_get_ext_help(struct menu *menu, struct gstr *help) 542void menu_get_ext_help(struct menu *menu, struct gstr *help)
519{ 543{
520 struct symbol *sym = menu->sym; 544 struct symbol *sym = menu->sym;
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
new file mode 100644
index 000000000000..762caf80ce37
--- /dev/null
+++ b/scripts/kconfig/nconf.c
@@ -0,0 +1,1568 @@
1/*
2 * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Derived from menuconfig.
6 *
7 */
8#define LKC_DIRECT_LINK
9#include "lkc.h"
10#include "nconf.h"
11
12static const char nconf_readme[] = N_(
13"Overview\n"
14"--------\n"
15"Some kernel features may be built directly into the kernel.\n"
16"Some may be made into loadable runtime modules. Some features\n"
17"may be completely removed altogether. There are also certain\n"
18"kernel parameters which are not really features, but must be\n"
19"entered in as decimal or hexadecimal numbers or possibly text.\n"
20"\n"
21"Menu items beginning with following braces represent features that\n"
22" [ ] can be built in or removed\n"
23" < > can be built in, modularized or removed\n"
24" { } can be built in or modularized (selected by other feature)\n"
25" - - are selected by other feature,\n"
26" XXX cannot be selected. use Symbol Info to find out why,\n"
27"while *, M or whitespace inside braces means to build in, build as\n"
28"a module or to exclude the feature respectively.\n"
29"\n"
30"To change any of these features, highlight it with the cursor\n"
31"keys and press <Y> to build it in, <M> to make it a module or\n"
32"<N> to removed it. You may also press the <Space Bar> to cycle\n"
33"through the available options (ie. Y->N->M->Y).\n"
34"\n"
35"Some additional keyboard hints:\n"
36"\n"
37"Menus\n"
38"----------\n"
39"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
40" you wish to change use <Enter> or <Space>. Goto submenu by \n"
41" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
42" Submenus are designated by \"--->\".\n"
43"\n"
44" Shortcut: Press the option's highlighted letter (hotkey).\n"
45" Pressing a hotkey more than once will sequence\n"
46" through all visible items which use that hotkey.\n"
47"\n"
48" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
49" unseen options into view.\n"
50"\n"
51"o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
52"\n"
53"o To get help with an item, press <F1>\n"
54" Shortcut: Press <h> or <?>.\n"
55"\n"
56"\n"
57"Radiolists (Choice lists)\n"
58"-----------\n"
59"o Use the cursor keys to select the option you wish to set and press\n"
60" <S> or the <SPACE BAR>.\n"
61"\n"
62" Shortcut: Press the first letter of the option you wish to set then\n"
63" press <S> or <SPACE BAR>.\n"
64"\n"
65"o To see available help for the item, press <F1>\n"
66" Shortcut: Press <H> or <?>.\n"
67"\n"
68"\n"
69"Data Entry\n"
70"-----------\n"
71"o Enter the requested information and press <ENTER>\n"
72" If you are entering hexadecimal values, it is not necessary to\n"
73" add the '0x' prefix to the entry.\n"
74"\n"
75"o For help, press <F1>.\n"
76"\n"
77"\n"
78"Text Box (Help Window)\n"
79"--------\n"
80"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
81" keys h,j,k,l function here as do <SPACE BAR> for those\n"
82" who are familiar with less and lynx.\n"
83"\n"
84"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
85"\n"
86"\n"
87"Alternate Configuration Files\n"
88"-----------------------------\n"
89"nconfig supports the use of alternate configuration files for\n"
90"those who, for various reasons, find it necessary to switch\n"
91"between different kernel configurations.\n"
92"\n"
93"At the end of the main menu you will find two options. One is\n"
94"for saving the current configuration to a file of your choosing.\n"
95"The other option is for loading a previously saved alternate\n"
96"configuration.\n"
97"\n"
98"Even if you don't use alternate configuration files, but you\n"
99"find during a nconfig session that you have completely messed\n"
100"up your settings, you may use the \"Load Alternate...\" option to\n"
101"restore your previously saved settings from \".config\" without\n"
102"restarting nconfig.\n"
103"\n"
104"Other information\n"
105"-----------------\n"
106"If you use nconfig in an XTERM window make sure you have your\n"
107"$TERM variable set to point to a xterm definition which supports color.\n"
108"Otherwise, nconfig will look rather bad. nconfig will not\n"
109"display correctly in a RXVT window because rxvt displays only one\n"
110"intensity of color, bright.\n"
111"\n"
112"nconfig will display larger menus on screens or xterms which are\n"
113"set to display more than the standard 25 row by 80 column geometry.\n"
114"In order for this to work, the \"stty size\" command must be able to\n"
115"display the screen's current row and column geometry. I STRONGLY\n"
116"RECOMMEND that you make sure you do NOT have the shell variables\n"
117"LINES and COLUMNS exported into your environment. Some distributions\n"
118"export those variables via /etc/profile. Some ncurses programs can\n"
119"become confused when those variables (LINES & COLUMNS) don't reflect\n"
120"the true screen size.\n"
121"\n"
122"Optional personality available\n"
123"------------------------------\n"
124"If you prefer to have all of the kernel options listed in a single\n"
125"menu, rather than the default multimenu hierarchy, run the nconfig\n"
126"with NCONFIG_MODE environment variable set to single_menu. Example:\n"
127"\n"
128"make NCONFIG_MODE=single_menu nconfig\n"
129"\n"
130"<Enter> will then unroll the appropriate category, or enfold it if it\n"
131"is already unrolled.\n"
132"\n"
133"Note that this mode can eventually be a little more CPU expensive\n"
134"(especially with a larger number of unrolled categories) than the\n"
135"default mode.\n"
136"\n"),
137menu_no_f_instructions[] = N_(
138" You do not have function keys support. Please follow the\n"
139" following instructions:\n"
140" Arrow keys navigate the menu.\n"
141" <Enter> or <right-arrow> selects submenus --->.\n"
142" Capital Letters are hotkeys.\n"
143" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
144" Pressing SpaceBar toggles between the above options\n"
145" Press <Esc> or <left-arrow> to go back one menu, \n"
146" <?> or <h> for Help, </> for Search.\n"
147" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
148" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
149" <Esc> always leaves the current window\n"),
150menu_instructions[] = N_(
151" Arrow keys navigate the menu.\n"
152" <Enter> or <right-arrow> selects submenus --->.\n"
153" Capital Letters are hotkeys.\n"
154" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
155" Pressing SpaceBar toggles between the above options\n"
156" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n"
157" <?>, <F1> or <h> for Help, </> for Search.\n"
158" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
159" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
160" <Esc> always leaves the current window\n"),
161radiolist_instructions[] = N_(
162" Use the arrow keys to navigate this window or\n"
163" press the hotkey of the item you wish to select\n"
164" followed by the <SPACE BAR>.\n"
165" Press <?>, <F1> or <h> for additional information about this option.\n"),
166inputbox_instructions_int[] = N_(
167"Please enter a decimal value.\n"
168"Fractions will not be accepted.\n"
169"Press <RETURN> to accept, <ESC> to cancel."),
170inputbox_instructions_hex[] = N_(
171"Please enter a hexadecimal value.\n"
172"Press <RETURN> to accept, <ESC> to cancel."),
173inputbox_instructions_string[] = N_(
174"Please enter a string value.\n"
175"Press <RETURN> to accept, <ESC> to cancel."),
176setmod_text[] = N_(
177"This feature depends on another which\n"
178"has been configured as a module.\n"
179"As a result, this feature will be built as a module."),
180nohelp_text[] = N_(
181"There is no help available for this kernel option.\n"),
182load_config_text[] = N_(
183"Enter the name of the configuration file you wish to load.\n"
184"Accept the name shown to restore the configuration you\n"
185"last retrieved. Leave blank to abort."),
186load_config_help[] = N_(
187"\n"
188"For various reasons, one may wish to keep several different kernel\n"
189"configurations available on a single machine.\n"
190"\n"
191"If you have saved a previous configuration in a file other than the\n"
192"kernel's default, entering the name of the file here will allow you\n"
193"to modify that configuration.\n"
194"\n"
195"If you are uncertain, then you have probably never used alternate\n"
196"configuration files. You should therefor leave this blank to abort.\n"),
197save_config_text[] = N_(
198"Enter a filename to which this configuration should be saved\n"
199"as an alternate. Leave blank to abort."),
200save_config_help[] = N_(
201"\n"
202"For various reasons, one may wish to keep different kernel\n"
203"configurations available on a single machine.\n"
204"\n"
205"Entering a file name here will allow you to later retrieve, modify\n"
206"and use the current configuration as an alternate to whatever\n"
207"configuration options you have selected at that time.\n"
208"\n"
209"If you are uncertain what all this means then you should probably\n"
210"leave this blank.\n"),
211search_help[] = N_(
212"\n"
213"Search for CONFIG_ symbols and display their relations.\n"
214"Regular expressions are allowed.\n"
215"Example: search for \"^FOO\"\n"
216"Result:\n"
217"-----------------------------------------------------------------\n"
218"Symbol: FOO [ = m]\n"
219"Prompt: Foo bus is used to drive the bar HW\n"
220"Defined at drivers/pci/Kconfig:47\n"
221"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
222"Location:\n"
223" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
224" -> PCI support (PCI [ = y])\n"
225" -> PCI access mode (<choice> [ = y])\n"
226"Selects: LIBCRC32\n"
227"Selected by: BAR\n"
228"-----------------------------------------------------------------\n"
229"o The line 'Prompt:' shows the text used in the menu structure for\n"
230" this CONFIG_ symbol\n"
231"o The 'Defined at' line tell at what file / line number the symbol\n"
232" is defined\n"
233"o The 'Depends on:' line tell what symbols needs to be defined for\n"
234" this symbol to be visible in the menu (selectable)\n"
235"o The 'Location:' lines tell where in the menu structure this symbol\n"
236" is located\n"
237" A location followed by a [ = y] indicate that this is a selectable\n"
238" menu item - and current value is displayed inside brackets.\n"
239"o The 'Selects:' line tell what symbol will be automatically\n"
240" selected if this symbol is selected (y or m)\n"
241"o The 'Selected by' line tell what symbol has selected this symbol\n"
242"\n"
243"Only relevant lines are shown.\n"
244"\n\n"
245"Search examples:\n"
246"Examples: USB = > find all CONFIG_ symbols containing USB\n"
247" ^USB => find all CONFIG_ symbols starting with USB\n"
248" USB$ => find all CONFIG_ symbols ending with USB\n"
249"\n");
250
251struct mitem {
252 char str[256];
253 char tag;
254 void *usrptr;
255 int is_hot;
256 int is_visible;
257};
258
259#define MAX_MENU_ITEMS 4096
260static int show_all_items;
261static int indent;
262static struct menu *current_menu;
263static int child_count;
264static int single_menu_mode;
265/* the window in which all information appears */
266static WINDOW *main_window;
267/* the largest size of the menu window */
268static int mwin_max_lines;
269static int mwin_max_cols;
270/* the window in which we show option buttons */
271static MENU *curses_menu;
272static ITEM *curses_menu_items[MAX_MENU_ITEMS];
273static struct mitem k_menu_items[MAX_MENU_ITEMS];
274static int items_num;
275static int global_exit;
276/* the currently selected button */
277const char *current_instructions = menu_instructions;
278/* this array is used to implement hot keys. it is updated in item_make and
279 * resetted in clean_items. It would be better to use a hash, but lets keep it
280 * simple... */
281#define MAX_SAME_KEY MAX_MENU_ITEMS
282struct {
283 int count;
284 int ptrs[MAX_MENU_ITEMS];
285} hotkeys[1<<(sizeof(char)*8)];
286
287static void conf(struct menu *menu);
288static void conf_choice(struct menu *menu);
289static void conf_string(struct menu *menu);
290static void conf_load(void);
291static void conf_save(void);
292static void show_help(struct menu *menu);
293static int do_exit(void);
294static void setup_windows(void);
295
296typedef void (*function_key_handler_t)(int *key, struct menu *menu);
297static void handle_f1(int *key, struct menu *current_item);
298static void handle_f2(int *key, struct menu *current_item);
299static void handle_f3(int *key, struct menu *current_item);
300static void handle_f4(int *key, struct menu *current_item);
301static void handle_f5(int *key, struct menu *current_item);
302static void handle_f6(int *key, struct menu *current_item);
303static void handle_f7(int *key, struct menu *current_item);
304static void handle_f8(int *key, struct menu *current_item);
305
306struct function_keys {
307 const char *key_str;
308 const char *func;
309 function_key key;
310 function_key_handler_t handler;
311};
312
313static const int function_keys_num = 8;
314struct function_keys function_keys[] = {
315 {
316 .key_str = "F1",
317 .func = "Help",
318 .key = F_HELP,
319 .handler = handle_f1,
320 },
321 {
322 .key_str = "F2",
323 .func = "Symbol Info",
324 .key = F_SYMBOL,
325 .handler = handle_f2,
326 },
327 {
328 .key_str = "F3",
329 .func = "Instructions",
330 .key = F_INSTS,
331 .handler = handle_f3,
332 },
333 {
334 .key_str = "F4",
335 .func = "Config",
336 .key = F_CONF,
337 .handler = handle_f4,
338 },
339 {
340 .key_str = "F5",
341 .func = "Back",
342 .key = F_BACK,
343 .handler = handle_f5,
344 },
345 {
346 .key_str = "F6",
347 .func = "Save",
348 .key = F_SAVE,
349 .handler = handle_f6,
350 },
351 {
352 .key_str = "F7",
353 .func = "Load",
354 .key = F_LOAD,
355 .handler = handle_f7,
356 },
357 {
358 .key_str = "F8",
359 .func = "Exit",
360 .key = F_EXIT,
361 .handler = handle_f8,
362 },
363};
364
365static void print_function_line(void)
366{
367 int i;
368 int offset = 1;
369 const int skip = 1;
370
371 for (i = 0; i < function_keys_num; i++) {
372 wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
373 mvwprintw(main_window, LINES-3, offset,
374 "%s",
375 function_keys[i].key_str);
376 wattrset(main_window, attributes[FUNCTION_TEXT]);
377 offset += strlen(function_keys[i].key_str);
378 mvwprintw(main_window, LINES-3,
379 offset, "%s",
380 function_keys[i].func);
381 offset += strlen(function_keys[i].func) + skip;
382 }
383 wattrset(main_window, attributes[NORMAL]);
384}
385
386/* help */
387static void handle_f1(int *key, struct menu *current_item)
388{
389 show_scroll_win(main_window,
390 _("README"), _(nconf_readme));
391 return;
392}
393
394/* symbole help */
395static void handle_f2(int *key, struct menu *current_item)
396{
397 show_help(current_item);
398 return;
399}
400
401/* instructions */
402static void handle_f3(int *key, struct menu *current_item)
403{
404 show_scroll_win(main_window,
405 _("Instructions"),
406 _(current_instructions));
407 return;
408}
409
410/* config */
411static void handle_f4(int *key, struct menu *current_item)
412{
413 int res = btn_dialog(main_window,
414 _("Show all symbols?"),
415 2,
416 " <Show All> ",
417 "<Don't show all>");
418 if (res == 0)
419 show_all_items = 1;
420 else if (res == 1)
421 show_all_items = 0;
422
423 return;
424}
425
426/* back */
427static void handle_f5(int *key, struct menu *current_item)
428{
429 *key = KEY_LEFT;
430 return;
431}
432
433/* save */
434static void handle_f6(int *key, struct menu *current_item)
435{
436 conf_save();
437 return;
438}
439
440/* load */
441static void handle_f7(int *key, struct menu *current_item)
442{
443 conf_load();
444 return;
445}
446
447/* exit */
448static void handle_f8(int *key, struct menu *current_item)
449{
450 do_exit();
451 return;
452}
453
454/* return != 0 to indicate the key was handles */
455static int process_special_keys(int *key, struct menu *menu)
456{
457 int i;
458
459 if (*key == KEY_RESIZE) {
460 setup_windows();
461 return 1;
462 }
463
464 for (i = 0; i < function_keys_num; i++) {
465 if (*key == KEY_F(function_keys[i].key) ||
466 *key == '0' + function_keys[i].key){
467 function_keys[i].handler(key, menu);
468 return 1;
469 }
470 }
471
472 return 0;
473}
474
475static void clean_items(void)
476{
477 int i;
478 for (i = 0; curses_menu_items[i]; i++)
479 free_item(curses_menu_items[i]);
480 bzero(curses_menu_items, sizeof(curses_menu_items));
481 bzero(k_menu_items, sizeof(k_menu_items));
482 bzero(hotkeys, sizeof(hotkeys));
483 items_num = 0;
484}
485
486/* return the index of the next hot item, or -1 if no such item exists */
487static int get_next_hot(int c)
488{
489 static int hot_index;
490 static int hot_char;
491
492 if (c < 0 || c > 255 || hotkeys[c].count <= 0)
493 return -1;
494
495 if (hot_char == c) {
496 hot_index = (hot_index+1)%hotkeys[c].count;
497 return hotkeys[c].ptrs[hot_index];
498 } else {
499 hot_char = c;
500 hot_index = 0;
501 return hotkeys[c].ptrs[0];
502 }
503}
504
505/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */
506static int canbhot(char c)
507{
508 c = tolower(c);
509 return isalnum(c) && c != 'y' && c != 'm' && c != 'h' &&
510 c != 'n' && c != '?';
511}
512
513/* check if str already contains a hot key. */
514static int is_hot(int index)
515{
516 return k_menu_items[index].is_hot;
517}
518
519/* find the first possible hot key, and mark it.
520 * index is the index of the item in the menu
521 * return 0 on success*/
522static int make_hot(char *dest, int len, const char *org, int index)
523{
524 int position = -1;
525 int i;
526 int tmp;
527 int c;
528 int org_len = strlen(org);
529
530 if (org == NULL || is_hot(index))
531 return 1;
532
533 /* make sure not to make hot keys out of markers.
534 * find where to start looking for a hot key
535 */
536 i = 0;
537 /* skip white space */
538 while (i < org_len && org[i] == ' ')
539 i++;
540 if (i == org_len)
541 return -1;
542 /* if encountering '(' or '<' or '[', find the match and look from there
543 **/
544 if (org[i] == '[' || org[i] == '<' || org[i] == '(') {
545 i++;
546 for (; i < org_len; i++)
547 if (org[i] == ']' || org[i] == '>' || org[i] == ')')
548 break;
549 }
550 if (i == org_len)
551 return -1;
552 for (; i < org_len; i++) {
553 if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') {
554 position = i;
555 break;
556 }
557 }
558 if (position == -1)
559 return 1;
560
561 /* ok, char at org[position] should be a hot key to this item */
562 c = tolower(org[position]);
563 tmp = hotkeys[c].count;
564 hotkeys[c].ptrs[tmp] = index;
565 hotkeys[c].count++;
566 /*
567 snprintf(dest, len, "%.*s(%c)%s", position, org, org[position],
568 &org[position+1]);
569 */
570 /* make org[position] uppercase, and all leading letter small case */
571 strncpy(dest, org, len);
572 for (i = 0; i < position; i++)
573 dest[i] = tolower(dest[i]);
574 dest[position] = toupper(dest[position]);
575 k_menu_items[index].is_hot = 1;
576 return 0;
577}
578
579/* Make a new item. Add a hotkey mark in the first possible letter.
580 * As ncurses does not allow any attributes inside menue item, we mark the
581 * hot key as the first capitalized letter in the string */
582static void item_make(struct menu *menu, char tag, const char *fmt, ...)
583{
584 va_list ap;
585 char tmp_str[256];
586
587 if (items_num > MAX_MENU_ITEMS-1)
588 return;
589
590 bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
591 k_menu_items[items_num].tag = tag;
592 k_menu_items[items_num].usrptr = menu;
593 if (menu != NULL)
594 k_menu_items[items_num].is_visible =
595 menu_is_visible(menu);
596 else
597 k_menu_items[items_num].is_visible = 1;
598
599 va_start(ap, fmt);
600 vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap);
601 if (!k_menu_items[items_num].is_visible)
602 memcpy(tmp_str, "XXX", 3);
603 va_end(ap);
604 if (make_hot(
605 k_menu_items[items_num].str,
606 sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0)
607 strncpy(k_menu_items[items_num].str,
608 tmp_str,
609 sizeof(k_menu_items[items_num].str));
610
611 curses_menu_items[items_num] = new_item(
612 k_menu_items[items_num].str,
613 k_menu_items[items_num].str);
614 set_item_userptr(curses_menu_items[items_num],
615 &k_menu_items[items_num]);
616 /*
617 if (!k_menu_items[items_num].is_visible)
618 item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
619 */
620
621 items_num++;
622 curses_menu_items[items_num] = NULL;
623}
624
625/* very hackish. adds a string to the last item added */
626static void item_add_str(const char *fmt, ...)
627{
628 va_list ap;
629 int index = items_num-1;
630 char new_str[256];
631 char tmp_str[256];
632
633 if (index < 0)
634 return;
635
636 va_start(ap, fmt);
637 vsnprintf(new_str, sizeof(new_str), fmt, ap);
638 va_end(ap);
639 snprintf(tmp_str, sizeof(tmp_str), "%s%s",
640 k_menu_items[index].str, new_str);
641 if (make_hot(k_menu_items[index].str,
642 sizeof(k_menu_items[index].str), tmp_str, index) != 0)
643 strncpy(k_menu_items[index].str,
644 tmp_str,
645 sizeof(k_menu_items[index].str));
646
647 free_item(curses_menu_items[index]);
648 curses_menu_items[index] = new_item(
649 k_menu_items[index].str,
650 k_menu_items[index].str);
651 set_item_userptr(curses_menu_items[index],
652 &k_menu_items[index]);
653}
654
655/* get the tag of the currently selected item */
656static char item_tag(void)
657{
658 ITEM *cur;
659 struct mitem *mcur;
660
661 cur = current_item(curses_menu);
662 if (cur == NULL)
663 return 0;
664 mcur = (struct mitem *) item_userptr(cur);
665 return mcur->tag;
666}
667
668static int curses_item_index(void)
669{
670 return item_index(current_item(curses_menu));
671}
672
673static void *item_data(void)
674{
675 ITEM *cur;
676 struct mitem *mcur;
677
678 cur = current_item(curses_menu);
679 mcur = (struct mitem *) item_userptr(cur);
680 return mcur->usrptr;
681
682}
683
684static int item_is_tag(char tag)
685{
686 return item_tag() == tag;
687}
688
689static char filename[PATH_MAX+1];
690static char menu_backtitle[PATH_MAX+128];
691static const char *set_config_filename(const char *config_filename)
692{
693 int size;
694 struct symbol *sym;
695
696 sym = sym_lookup("KERNELVERSION", 0);
697 sym_calc_value(sym);
698 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
699 _("%s - Linux Kernel v%s Configuration"),
700 config_filename, sym_get_string_value(sym));
701 if (size >= sizeof(menu_backtitle))
702 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
703
704 size = snprintf(filename, sizeof(filename), "%s", config_filename);
705 if (size >= sizeof(filename))
706 filename[sizeof(filename)-1] = '\0';
707 return menu_backtitle;
708}
709
710/* command = 0 is supress, 1 is restore */
711static void supress_stdout(int command)
712{
713 static FILE *org_stdout;
714 static FILE *org_stderr;
715
716 if (command == 0) {
717 org_stdout = stdout;
718 org_stderr = stderr;
719 stdout = fopen("/dev/null", "a");
720 stderr = fopen("/dev/null", "a");
721 } else {
722 fclose(stdout);
723 fclose(stderr);
724 stdout = org_stdout;
725 stderr = org_stderr;
726 }
727}
728
729/* return = 0 means we are successful.
730 * -1 means go on doing what you were doing
731 */
732static int do_exit(void)
733{
734 int res;
735 if (!conf_get_changed()) {
736 global_exit = 1;
737 return 0;
738 }
739 res = btn_dialog(main_window,
740 _("Do you wish to save your "
741 "new kernel configuration?\n"
742 "<ESC> to cancel and resume nconfig."),
743 2,
744 " <save> ",
745 "<don't save>");
746 if (res == KEY_EXIT) {
747 global_exit = 0;
748 return -1;
749 }
750
751 /* if we got here, the user really wants to exit */
752 switch (res) {
753 case 0:
754 supress_stdout(0);
755 res = conf_write(filename);
756 supress_stdout(1);
757 if (res)
758 btn_dialog(
759 main_window,
760 _("Error during writing of the kernel "
761 "configuration.\n"
762 "Your kernel configuration "
763 "changes were NOT saved."),
764 1,
765 "<OK>");
766 else {
767 char buf[1024];
768 snprintf(buf, 1024,
769 _("Configuration written to %s\n"
770 "End of Linux kernel configuration.\n"
771 "Execute 'make' to build the kernel or try"
772 " 'make help'."), filename);
773 btn_dialog(
774 main_window,
775 buf,
776 1,
777 "<OK>");
778 }
779 break;
780 default:
781 btn_dialog(
782 main_window,
783 _("Your kernel configuration changes were NOT saved."),
784 1,
785 "<OK>");
786 break;
787 }
788 global_exit = 1;
789 return 0;
790}
791
792
793static void search_conf(void)
794{
795 struct symbol **sym_arr;
796 struct gstr res;
797 char dialog_input_result[100];
798 char *dialog_input;
799 int dres;
800again:
801 dres = dialog_inputbox(main_window,
802 _("Search Configuration Parameter"),
803 _("Enter CONFIG_ (sub)string to search for "
804 "(with or without \"CONFIG\")"),
805 "", dialog_input_result, 99);
806 switch (dres) {
807 case 0:
808 break;
809 case 1:
810 show_scroll_win(main_window,
811 _("Search Configuration"), search_help);
812 goto again;
813 default:
814 return;
815 }
816
817 /* strip CONFIG_ if necessary */
818 dialog_input = dialog_input_result;
819 if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
820 dialog_input += 7;
821
822 sym_arr = sym_re_search(dialog_input);
823 res = get_relations_str(sym_arr);
824 free(sym_arr);
825 show_scroll_win(main_window,
826 _("Search Results"), str_get(&res));
827 str_free(&res);
828}
829
830
831static void build_conf(struct menu *menu)
832{
833 struct symbol *sym;
834 struct property *prop;
835 struct menu *child;
836 int type, tmp, doint = 2;
837 tristate val;
838 char ch;
839
840 if (!menu || (!show_all_items && !menu_is_visible(menu)))
841 return;
842
843 sym = menu->sym;
844 prop = menu->prompt;
845 if (!sym) {
846 if (prop && menu != current_menu) {
847 const char *prompt = menu_get_prompt(menu);
848 enum prop_type ptype;
849 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
850 switch (ptype) {
851 case P_MENU:
852 child_count++;
853 prompt = _(prompt);
854 if (single_menu_mode) {
855 item_make(menu, 'm',
856 "%s%*c%s",
857 menu->data ? "-->" : "++>",
858 indent + 1, ' ', prompt);
859 } else
860 item_make(menu, 'm',
861 " %*c%s --->",
862 indent + 1,
863 ' ', prompt);
864
865 if (single_menu_mode && menu->data)
866 goto conf_childs;
867 return;
868 case P_COMMENT:
869 if (prompt) {
870 child_count++;
871 item_make(menu, ':',
872 " %*c*** %s ***",
873 indent + 1, ' ',
874 _(prompt));
875 }
876 break;
877 default:
878 if (prompt) {
879 child_count++;
880 item_make(menu, ':', "---%*c%s",
881 indent + 1, ' ',
882 _(prompt));
883 }
884 }
885 } else
886 doint = 0;
887 goto conf_childs;
888 }
889
890 type = sym_get_type(sym);
891 if (sym_is_choice(sym)) {
892 struct symbol *def_sym = sym_get_choice_value(sym);
893 struct menu *def_menu = NULL;
894
895 child_count++;
896 for (child = menu->list; child; child = child->next) {
897 if (menu_is_visible(child) && child->sym == def_sym)
898 def_menu = child;
899 }
900
901 val = sym_get_tristate_value(sym);
902 if (sym_is_changable(sym)) {
903 switch (type) {
904 case S_BOOLEAN:
905 item_make(menu, 't', "[%c]",
906 val == no ? ' ' : '*');
907 break;
908 case S_TRISTATE:
909 switch (val) {
910 case yes:
911 ch = '*';
912 break;
913 case mod:
914 ch = 'M';
915 break;
916 default:
917 ch = ' ';
918 break;
919 }
920 item_make(menu, 't', "<%c>", ch);
921 break;
922 }
923 } else {
924 item_make(menu, def_menu ? 't' : ':', " ");
925 }
926
927 item_add_str("%*c%s", indent + 1,
928 ' ', _(menu_get_prompt(menu)));
929 if (val == yes) {
930 if (def_menu) {
931 item_add_str(" (%s)",
932 _(menu_get_prompt(def_menu)));
933 item_add_str(" --->");
934 if (def_menu->list) {
935 indent += 2;
936 build_conf(def_menu);
937 indent -= 2;
938 }
939 }
940 return;
941 }
942 } else {
943 if (menu == current_menu) {
944 item_make(menu, ':',
945 "---%*c%s", indent + 1,
946 ' ', _(menu_get_prompt(menu)));
947 goto conf_childs;
948 }
949 child_count++;
950 val = sym_get_tristate_value(sym);
951 if (sym_is_choice_value(sym) && val == yes) {
952 item_make(menu, ':', " ");
953 } else {
954 switch (type) {
955 case S_BOOLEAN:
956 if (sym_is_changable(sym))
957 item_make(menu, 't', "[%c]",
958 val == no ? ' ' : '*');
959 else
960 item_make(menu, 't', "-%c-",
961 val == no ? ' ' : '*');
962 break;
963 case S_TRISTATE:
964 switch (val) {
965 case yes:
966 ch = '*';
967 break;
968 case mod:
969 ch = 'M';
970 break;
971 default:
972 ch = ' ';
973 break;
974 }
975 if (sym_is_changable(sym)) {
976 if (sym->rev_dep.tri == mod)
977 item_make(menu,
978 't', "{%c}", ch);
979 else
980 item_make(menu,
981 't', "<%c>", ch);
982 } else
983 item_make(menu, 't', "-%c-", ch);
984 break;
985 default:
986 tmp = 2 + strlen(sym_get_string_value(sym));
987 item_make(menu, 's', " (%s)",
988 sym_get_string_value(sym));
989 tmp = indent - tmp + 4;
990 if (tmp < 0)
991 tmp = 0;
992 item_add_str("%*c%s%s", tmp, ' ',
993 _(menu_get_prompt(menu)),
994 (sym_has_value(sym) ||
995 !sym_is_changable(sym)) ? "" :
996 _(" (NEW)"));
997 goto conf_childs;
998 }
999 }
1000 item_add_str("%*c%s%s", indent + 1, ' ',
1001 _(menu_get_prompt(menu)),
1002 (sym_has_value(sym) || !sym_is_changable(sym)) ?
1003 "" : _(" (NEW)"));
1004 if (menu->prompt && menu->prompt->type == P_MENU) {
1005 item_add_str(" --->");
1006 return;
1007 }
1008 }
1009
1010conf_childs:
1011 indent += doint;
1012 for (child = menu->list; child; child = child->next)
1013 build_conf(child);
1014 indent -= doint;
1015}
1016
1017static void reset_menu(void)
1018{
1019 unpost_menu(curses_menu);
1020 clean_items();
1021}
1022
1023/* adjust the menu to show this item.
1024 * prefer not to scroll the menu if possible*/
1025static void center_item(int selected_index, int *last_top_row)
1026{
1027 int toprow;
1028 int maxy, maxx;
1029
1030 scale_menu(curses_menu, &maxy, &maxx);
1031 set_top_row(curses_menu, *last_top_row);
1032 toprow = top_row(curses_menu);
1033 if (selected_index >= toprow && selected_index < toprow+maxy) {
1034 /* we can only move the selected item. no need to scroll */
1035 set_current_item(curses_menu,
1036 curses_menu_items[selected_index]);
1037 } else {
1038 toprow = max(selected_index-maxy/2, 0);
1039 if (toprow >= item_count(curses_menu)-maxy)
1040 toprow = item_count(curses_menu)-mwin_max_lines;
1041 set_top_row(curses_menu, toprow);
1042 set_current_item(curses_menu,
1043 curses_menu_items[selected_index]);
1044 }
1045 *last_top_row = toprow;
1046 post_menu(curses_menu);
1047 refresh_all_windows(main_window);
1048}
1049
1050/* this function assumes reset_menu has been called before */
1051static void show_menu(const char *prompt, const char *instructions,
1052 int selected_index, int *last_top_row)
1053{
1054 int maxx, maxy;
1055 WINDOW *menu_window;
1056
1057 current_instructions = instructions;
1058
1059 clear();
1060 wattrset(main_window, attributes[NORMAL]);
1061 print_in_middle(stdscr, 1, 0, COLS,
1062 menu_backtitle,
1063 attributes[MAIN_HEADING]);
1064
1065 wattrset(main_window, attributes[MAIN_MENU_BOX]);
1066 box(main_window, 0, 0);
1067 wattrset(main_window, attributes[MAIN_MENU_HEADING]);
1068 mvwprintw(main_window, 0, 3, " %s ", prompt);
1069 wattrset(main_window, attributes[NORMAL]);
1070
1071 set_menu_items(curses_menu, curses_menu_items);
1072
1073 /* position the menu at the middle of the screen */
1074 scale_menu(curses_menu, &maxy, &maxx);
1075 maxx = min(maxx, mwin_max_cols-2);
1076 maxy = mwin_max_lines-2;
1077 menu_window = derwin(main_window,
1078 maxy,
1079 maxx,
1080 2,
1081 (mwin_max_cols-maxx)/2);
1082 keypad(menu_window, TRUE);
1083 set_menu_win(curses_menu, menu_window);
1084 set_menu_sub(curses_menu, menu_window);
1085
1086 /* must reassert this after changing items, otherwise returns to a
1087 * default of 16
1088 */
1089 set_menu_format(curses_menu, maxy, 1);
1090 center_item(selected_index, last_top_row);
1091 set_menu_format(curses_menu, maxy, 1);
1092
1093 print_function_line();
1094
1095 /* Post the menu */
1096 post_menu(curses_menu);
1097 refresh_all_windows(main_window);
1098}
1099
1100
1101static void conf(struct menu *menu)
1102{
1103 char pattern[256];
1104 struct menu *submenu = 0;
1105 const char *prompt = menu_get_prompt(menu);
1106 struct symbol *sym;
1107 struct menu *active_menu = NULL;
1108 int res;
1109 int current_index = 0;
1110 int last_top_row = 0;
1111
1112 bzero(pattern, sizeof(pattern));
1113
1114 while (!global_exit) {
1115 reset_menu();
1116 current_menu = menu;
1117 build_conf(menu);
1118 if (!child_count)
1119 break;
1120
1121 show_menu(prompt ? _(prompt) : _("Main Menu"),
1122 _(menu_instructions),
1123 current_index, &last_top_row);
1124 keypad((menu_win(curses_menu)), TRUE);
1125 while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
1126 if (process_special_keys(&res,
1127 (struct menu *) item_data()))
1128 break;
1129 switch (res) {
1130 case KEY_DOWN:
1131 menu_driver(curses_menu, REQ_DOWN_ITEM);
1132 break;
1133 case KEY_UP:
1134 menu_driver(curses_menu, REQ_UP_ITEM);
1135 break;
1136 case KEY_NPAGE:
1137 menu_driver(curses_menu, REQ_SCR_DPAGE);
1138 break;
1139 case KEY_PPAGE:
1140 menu_driver(curses_menu, REQ_SCR_UPAGE);
1141 break;
1142 case KEY_HOME:
1143 menu_driver(curses_menu, REQ_FIRST_ITEM);
1144 break;
1145 case KEY_END:
1146 menu_driver(curses_menu, REQ_LAST_ITEM);
1147 break;
1148 case 'h':
1149 case '?':
1150 show_help((struct menu *) item_data());
1151 break;
1152 }
1153 if (res == 10 || res == 27 ||
1154 res == 32 || res == 'n' || res == 'y' ||
1155 res == KEY_LEFT || res == KEY_RIGHT ||
1156 res == 'm' || res == '/')
1157 break;
1158 else if (canbhot(res)) {
1159 /* check for hot keys: */
1160 int tmp = get_next_hot(res);
1161 if (tmp != -1)
1162 center_item(tmp, &last_top_row);
1163 }
1164 refresh_all_windows(main_window);
1165 }
1166
1167 refresh_all_windows(main_window);
1168 /* if ESC or left*/
1169 if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1170 break;
1171
1172 /* remember location in the menu */
1173 last_top_row = top_row(curses_menu);
1174 current_index = curses_item_index();
1175
1176 if (!item_tag())
1177 continue;
1178
1179 submenu = (struct menu *) item_data();
1180 active_menu = (struct menu *)item_data();
1181 if (!submenu || !menu_is_visible(submenu))
1182 continue;
1183 if (submenu)
1184 sym = submenu->sym;
1185 else
1186 sym = NULL;
1187
1188 switch (res) {
1189 case ' ':
1190 if (item_is_tag('t'))
1191 sym_toggle_tristate_value(sym);
1192 else if (item_is_tag('m'))
1193 conf(submenu);
1194 break;
1195 case KEY_RIGHT:
1196 case 10: /* ENTER WAS PRESSED */
1197 switch (item_tag()) {
1198 case 'm':
1199 if (single_menu_mode)
1200 submenu->data =
1201 (void *) (long) !submenu->data;
1202 else
1203 conf(submenu);
1204 break;
1205 case 't':
1206 if (sym_is_choice(sym) &&
1207 sym_get_tristate_value(sym) == yes)
1208 conf_choice(submenu);
1209 else if (submenu->prompt &&
1210 submenu->prompt->type == P_MENU)
1211 conf(submenu);
1212 else if (res == 10)
1213 sym_toggle_tristate_value(sym);
1214 break;
1215 case 's':
1216 conf_string(submenu);
1217 break;
1218 }
1219 break;
1220 case 'y':
1221 if (item_is_tag('t')) {
1222 if (sym_set_tristate_value(sym, yes))
1223 break;
1224 if (sym_set_tristate_value(sym, mod))
1225 btn_dialog(main_window, setmod_text, 0);
1226 }
1227 break;
1228 case 'n':
1229 if (item_is_tag('t'))
1230 sym_set_tristate_value(sym, no);
1231 break;
1232 case 'm':
1233 if (item_is_tag('t'))
1234 sym_set_tristate_value(sym, mod);
1235 break;
1236 case '/':
1237 search_conf();
1238 break;
1239 }
1240 }
1241}
1242
1243static void show_help(struct menu *menu)
1244{
1245 struct gstr help = str_new();
1246
1247 if (menu && menu->sym && menu_has_help(menu)) {
1248 if (menu->sym->name) {
1249 str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name);
1250 str_append(&help, _(menu_get_help(menu)));
1251 str_append(&help, "\n");
1252 get_symbol_str(&help, menu->sym);
1253 }
1254 } else {
1255 str_append(&help, nohelp_text);
1256 }
1257 show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
1258 str_free(&help);
1259}
1260
1261static void conf_choice(struct menu *menu)
1262{
1263 const char *prompt = _(menu_get_prompt(menu));
1264 struct menu *child = 0;
1265 struct symbol *active;
1266 int selected_index = 0;
1267 int last_top_row = 0;
1268 int res, i = 0;
1269
1270 active = sym_get_choice_value(menu->sym);
1271 /* this is mostly duplicated from the conf() function. */
1272 while (!global_exit) {
1273 reset_menu();
1274
1275 for (i = 0, child = menu->list; child; child = child->next) {
1276 if (!show_all_items && !menu_is_visible(child))
1277 continue;
1278
1279 if (child->sym == sym_get_choice_value(menu->sym))
1280 item_make(child, ':', "<X> %s",
1281 _(menu_get_prompt(child)));
1282 else
1283 item_make(child, ':', " %s",
1284 _(menu_get_prompt(child)));
1285 if (child->sym == active){
1286 last_top_row = top_row(curses_menu);
1287 selected_index = i;
1288 }
1289 i++;
1290 }
1291 show_menu(prompt ? _(prompt) : _("Choice Menu"),
1292 _(radiolist_instructions),
1293 selected_index,
1294 &last_top_row);
1295 while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
1296 if (process_special_keys(
1297 &res,
1298 (struct menu *) item_data()))
1299 break;
1300 switch (res) {
1301 case KEY_DOWN:
1302 menu_driver(curses_menu, REQ_DOWN_ITEM);
1303 break;
1304 case KEY_UP:
1305 menu_driver(curses_menu, REQ_UP_ITEM);
1306 break;
1307 case KEY_NPAGE:
1308 menu_driver(curses_menu, REQ_SCR_DPAGE);
1309 break;
1310 case KEY_PPAGE:
1311 menu_driver(curses_menu, REQ_SCR_UPAGE);
1312 break;
1313 case KEY_HOME:
1314 menu_driver(curses_menu, REQ_FIRST_ITEM);
1315 break;
1316 case KEY_END:
1317 menu_driver(curses_menu, REQ_LAST_ITEM);
1318 break;
1319 case 'h':
1320 case '?':
1321 show_help((struct menu *) item_data());
1322 break;
1323 }
1324 if (res == 10 || res == 27 || res == ' ' ||
1325 res == KEY_LEFT)
1326 break;
1327 else if (canbhot(res)) {
1328 /* check for hot keys: */
1329 int tmp = get_next_hot(res);
1330 if (tmp != -1)
1331 center_item(tmp, &last_top_row);
1332 }
1333 refresh_all_windows(main_window);
1334 }
1335 /* if ESC or left */
1336 if (res == 27 || res == KEY_LEFT)
1337 break;
1338
1339 child = item_data();
1340 if (!child || !menu_is_visible(child))
1341 continue;
1342 switch (res) {
1343 case ' ':
1344 case 10:
1345 case KEY_RIGHT:
1346 sym_set_tristate_value(child->sym, yes);
1347 return;
1348 case 'h':
1349 case '?':
1350 show_help(child);
1351 active = child->sym;
1352 break;
1353 case KEY_EXIT:
1354 return;
1355 }
1356 }
1357}
1358
1359static void conf_string(struct menu *menu)
1360{
1361 const char *prompt = menu_get_prompt(menu);
1362 char dialog_input_result[256];
1363
1364 while (1) {
1365 int res;
1366 const char *heading;
1367
1368 switch (sym_get_type(menu->sym)) {
1369 case S_INT:
1370 heading = _(inputbox_instructions_int);
1371 break;
1372 case S_HEX:
1373 heading = _(inputbox_instructions_hex);
1374 break;
1375 case S_STRING:
1376 heading = _(inputbox_instructions_string);
1377 break;
1378 default:
1379 heading = _("Internal nconf error!");
1380 }
1381 res = dialog_inputbox(main_window,
1382 prompt ? _(prompt) : _("Main Menu"),
1383 heading,
1384 sym_get_string_value(menu->sym),
1385 dialog_input_result,
1386 sizeof(dialog_input_result));
1387 switch (res) {
1388 case 0:
1389 if (sym_set_string_value(menu->sym,
1390 dialog_input_result))
1391 return;
1392 btn_dialog(main_window,
1393 _("You have made an invalid entry."), 0);
1394 break;
1395 case 1:
1396 show_help(menu);
1397 break;
1398 case KEY_EXIT:
1399 return;
1400 }
1401 }
1402}
1403
1404static void conf_load(void)
1405{
1406 char dialog_input_result[256];
1407 while (1) {
1408 int res;
1409 res = dialog_inputbox(main_window,
1410 NULL, load_config_text,
1411 filename,
1412 dialog_input_result,
1413 sizeof(dialog_input_result));
1414 switch (res) {
1415 case 0:
1416 if (!dialog_input_result[0])
1417 return;
1418 if (!conf_read(dialog_input_result)) {
1419 set_config_filename(dialog_input_result);
1420 sym_set_change_count(1);
1421 return;
1422 }
1423 btn_dialog(main_window, _("File does not exist!"), 0);
1424 break;
1425 case 1:
1426 show_scroll_win(main_window,
1427 _("Load Alternate Configuration"),
1428 load_config_help);
1429 break;
1430 case KEY_EXIT:
1431 return;
1432 }
1433 }
1434}
1435
1436static void conf_save(void)
1437{
1438 char dialog_input_result[256];
1439 while (1) {
1440 int res;
1441 res = dialog_inputbox(main_window,
1442 NULL, save_config_text,
1443 filename,
1444 dialog_input_result,
1445 sizeof(dialog_input_result));
1446 switch (res) {
1447 case 0:
1448 if (!dialog_input_result[0])
1449 return;
1450 supress_stdout(0);
1451 res = conf_write(dialog_input_result);
1452 supress_stdout(1);
1453 if (!res) {
1454 char buf[1024];
1455 sprintf(buf, "%s %s",
1456 _("configuration file saved to: "),
1457 dialog_input_result);
1458 btn_dialog(main_window,
1459 buf, 1, "<OK>");
1460 set_config_filename(dialog_input_result);
1461 return;
1462 }
1463 btn_dialog(main_window, _("Can't create file! "
1464 "Probably a nonexistent directory."),
1465 1, "<OK>");
1466 break;
1467 case 1:
1468 show_scroll_win(main_window,
1469 _("Save Alternate Configuration"),
1470 save_config_help);
1471 break;
1472 case KEY_EXIT:
1473 return;
1474 }
1475 }
1476}
1477
1478void setup_windows(void)
1479{
1480 if (main_window != NULL)
1481 delwin(main_window);
1482
1483 /* set up the menu and menu window */
1484 main_window = newwin(LINES-2, COLS-2, 2, 1);
1485 keypad(main_window, TRUE);
1486 mwin_max_lines = LINES-6;
1487 mwin_max_cols = COLS-6;
1488
1489 /* panels order is from bottom to top */
1490 new_panel(main_window);
1491}
1492
1493int main(int ac, char **av)
1494{
1495 char *mode;
1496
1497 setlocale(LC_ALL, "");
1498 bindtextdomain(PACKAGE, LOCALEDIR);
1499 textdomain(PACKAGE);
1500
1501 conf_parse(av[1]);
1502 conf_read(NULL);
1503
1504 mode = getenv("NCONFIG_MODE");
1505 if (mode) {
1506 if (!strcasecmp(mode, "single_menu"))
1507 single_menu_mode = 1;
1508 }
1509
1510 /* Initialize curses */
1511 initscr();
1512 /* set color theme */
1513 set_colors();
1514
1515 cbreak();
1516 noecho();
1517 keypad(stdscr, TRUE);
1518 curs_set(0);
1519
1520 if (COLS < 75 || LINES < 20) {
1521 endwin();
1522 printf("Your terminal should have at "
1523 "least 20 lines and 75 columns\n");
1524 return 1;
1525 }
1526
1527 notimeout(stdscr, FALSE);
1528 ESCDELAY = 1;
1529
1530 /* set btns menu */
1531 curses_menu = new_menu(curses_menu_items);
1532 menu_opts_off(curses_menu, O_SHOWDESC);
1533 menu_opts_off(curses_menu, O_SHOWMATCH);
1534 menu_opts_on(curses_menu, O_ONEVALUE);
1535 menu_opts_on(curses_menu, O_NONCYCLIC);
1536 set_menu_mark(curses_menu, " ");
1537 set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1538 set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
1539 set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
1540
1541 set_config_filename(conf_get_configname());
1542 setup_windows();
1543
1544 /* check for KEY_FUNC(1) */
1545 if (has_key(KEY_F(1)) == FALSE) {
1546 show_scroll_win(main_window,
1547 _("Instructions"),
1548 _(menu_no_f_instructions));
1549 }
1550
1551
1552
1553 /* do the work */
1554 while (!global_exit) {
1555 conf(&rootmenu);
1556 if (!global_exit && do_exit() == 0)
1557 break;
1558 }
1559 /* ok, we are done */
1560 unpost_menu(curses_menu);
1561 free_menu(curses_menu);
1562 delwin(main_window);
1563 clear();
1564 refresh();
1565 endwin();
1566 return 0;
1567}
1568
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
new file mode 100644
index 000000000000..115edb437fb1
--- /dev/null
+++ b/scripts/kconfig/nconf.gui.c
@@ -0,0 +1,617 @@
1/*
2 * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Derived from menuconfig.
6 *
7 */
8#include "nconf.h"
9
10/* a list of all the different widgets we use */
11attributes_t attributes[ATTR_MAX+1] = {0};
12
13/* available colors:
14 COLOR_BLACK 0
15 COLOR_RED 1
16 COLOR_GREEN 2
17 COLOR_YELLOW 3
18 COLOR_BLUE 4
19 COLOR_MAGENTA 5
20 COLOR_CYAN 6
21 COLOR_WHITE 7
22 */
23static void set_normal_colors(void)
24{
25 init_pair(NORMAL, -1, -1);
26 init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
27
28 /* FORE is for the selected item */
29 init_pair(MAIN_MENU_FORE, -1, -1);
30 /* BACK for all the rest */
31 init_pair(MAIN_MENU_BACK, -1, -1);
32 init_pair(MAIN_MENU_GREY, -1, -1);
33 init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
34 init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
35
36 init_pair(SCROLLWIN_TEXT, -1, -1);
37 init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
38 init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
39
40 init_pair(DIALOG_TEXT, -1, -1);
41 init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
42 init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
43 init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
44
45 init_pair(INPUT_BOX, COLOR_YELLOW, -1);
46 init_pair(INPUT_HEADING, COLOR_GREEN, -1);
47 init_pair(INPUT_TEXT, -1, -1);
48 init_pair(INPUT_FIELD, -1, -1);
49
50 init_pair(FUNCTION_HIGHLIGHT, -1, -1);
51 init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
52}
53
54/* available attributes:
55 A_NORMAL Normal display (no highlight)
56 A_STANDOUT Best highlighting mode of the terminal.
57 A_UNDERLINE Underlining
58 A_REVERSE Reverse video
59 A_BLINK Blinking
60 A_DIM Half bright
61 A_BOLD Extra bright or bold
62 A_PROTECT Protected mode
63 A_INVIS Invisible or blank mode
64 A_ALTCHARSET Alternate character set
65 A_CHARTEXT Bit-mask to extract a character
66 COLOR_PAIR(n) Color-pair number n
67 */
68static void normal_color_theme(void)
69{
70 /* automatically add color... */
71#define mkattr(name, attr) do { \
72attributes[name] = attr | COLOR_PAIR(name); } while (0)
73 mkattr(NORMAL, NORMAL);
74 mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
75
76 mkattr(MAIN_MENU_FORE, A_REVERSE);
77 mkattr(MAIN_MENU_BACK, A_NORMAL);
78 mkattr(MAIN_MENU_GREY, A_NORMAL);
79 mkattr(MAIN_MENU_HEADING, A_BOLD);
80 mkattr(MAIN_MENU_BOX, A_NORMAL);
81
82 mkattr(SCROLLWIN_TEXT, A_NORMAL);
83 mkattr(SCROLLWIN_HEADING, A_BOLD);
84 mkattr(SCROLLWIN_BOX, A_BOLD);
85
86 mkattr(DIALOG_TEXT, A_BOLD);
87 mkattr(DIALOG_BOX, A_BOLD);
88 mkattr(DIALOG_MENU_FORE, A_STANDOUT);
89 mkattr(DIALOG_MENU_BACK, A_NORMAL);
90
91 mkattr(INPUT_BOX, A_NORMAL);
92 mkattr(INPUT_HEADING, A_BOLD);
93 mkattr(INPUT_TEXT, A_NORMAL);
94 mkattr(INPUT_FIELD, A_UNDERLINE);
95
96 mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
97 mkattr(FUNCTION_TEXT, A_REVERSE);
98}
99
100static void no_colors_theme(void)
101{
102 /* automatically add highlight, no color */
103#define mkattrn(name, attr) { attributes[name] = attr; }
104
105 mkattrn(NORMAL, NORMAL);
106 mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
107
108 mkattrn(MAIN_MENU_FORE, A_STANDOUT);
109 mkattrn(MAIN_MENU_BACK, A_NORMAL);
110 mkattrn(MAIN_MENU_GREY, A_NORMAL);
111 mkattrn(MAIN_MENU_HEADING, A_BOLD);
112 mkattrn(MAIN_MENU_BOX, A_NORMAL);
113
114 mkattrn(SCROLLWIN_TEXT, A_NORMAL);
115 mkattrn(SCROLLWIN_HEADING, A_BOLD);
116 mkattrn(SCROLLWIN_BOX, A_BOLD);
117
118 mkattrn(DIALOG_TEXT, A_NORMAL);
119 mkattrn(DIALOG_BOX, A_BOLD);
120 mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
121 mkattrn(DIALOG_MENU_BACK, A_NORMAL);
122
123 mkattrn(INPUT_BOX, A_BOLD);
124 mkattrn(INPUT_HEADING, A_BOLD);
125 mkattrn(INPUT_TEXT, A_NORMAL);
126 mkattrn(INPUT_FIELD, A_UNDERLINE);
127
128 mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
129 mkattrn(FUNCTION_TEXT, A_REVERSE);
130}
131
132void set_colors()
133{
134 start_color();
135 use_default_colors();
136 set_normal_colors();
137 if (has_colors()) {
138 normal_color_theme();
139 } else {
140 /* give deafults */
141 no_colors_theme();
142 }
143}
144
145
146/* this changes the windows attributes !!! */
147void print_in_middle(WINDOW *win,
148 int starty,
149 int startx,
150 int width,
151 const char *string,
152 chtype color)
153{ int length, x, y;
154 float temp;
155
156
157 if (win == NULL)
158 win = stdscr;
159 getyx(win, y, x);
160 if (startx != 0)
161 x = startx;
162 if (starty != 0)
163 y = starty;
164 if (width == 0)
165 width = 80;
166
167 length = strlen(string);
168 temp = (width - length) / 2;
169 x = startx + (int)temp;
170 wattrset(win, color);
171 mvwprintw(win, y, x, "%s", string);
172 refresh();
173}
174
175int get_line_no(const char *text)
176{
177 int i;
178 int total = 1;
179
180 if (!text)
181 return 0;
182
183 for (i = 0; text[i] != '\0'; i++)
184 if (text[i] == '\n')
185 total++;
186 return total;
187}
188
189const char *get_line(const char *text, int line_no)
190{
191 int i;
192 int lines = 0;
193
194 if (!text)
195 return 0;
196
197 for (i = 0; text[i] != '\0' && lines < line_no; i++)
198 if (text[i] == '\n')
199 lines++;
200 return text+i;
201}
202
203int get_line_length(const char *line)
204{
205 int res = 0;
206 while (*line != '\0' && *line != '\n') {
207 line++;
208 res++;
209 }
210 return res;
211}
212
213/* print all lines to the window. */
214void fill_window(WINDOW *win, const char *text)
215{
216 int x, y;
217 int total_lines = get_line_no(text);
218 int i;
219
220 getmaxyx(win, y, x);
221 /* do not go over end of line */
222 total_lines = min(total_lines, y);
223 for (i = 0; i < total_lines; i++) {
224 char tmp[x+10];
225 const char *line = get_line(text, i);
226 int len = get_line_length(line);
227 strncpy(tmp, line, min(len, x));
228 tmp[len] = '\0';
229 mvwprintw(win, i, 0, tmp);
230 }
231}
232
233/* get the message, and buttons.
234 * each button must be a char*
235 * return the selected button
236 *
237 * this dialog is used for 2 different things:
238 * 1) show a text box, no buttons.
239 * 2) show a dialog, with horizontal buttons
240 */
241int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
242{
243 va_list ap;
244 char *btn;
245 int btns_width = 0;
246 int msg_lines = 0;
247 int msg_width = 0;
248 int total_width;
249 int win_rows = 0;
250 WINDOW *win;
251 WINDOW *msg_win;
252 WINDOW *menu_win;
253 MENU *menu;
254 ITEM *btns[btn_num+1];
255 int i, x, y;
256 int res = -1;
257
258
259 va_start(ap, btn_num);
260 for (i = 0; i < btn_num; i++) {
261 btn = va_arg(ap, char *);
262 btns[i] = new_item(btn, "");
263 btns_width += strlen(btn)+1;
264 }
265 va_end(ap);
266 btns[btn_num] = NULL;
267
268 /* find the widest line of msg: */
269 msg_lines = get_line_no(msg);
270 for (i = 0; i < msg_lines; i++) {
271 const char *line = get_line(msg, i);
272 int len = get_line_length(line);
273 if (msg_width < len)
274 msg_width = len;
275 }
276
277 total_width = max(msg_width, btns_width);
278 /* place dialog in middle of screen */
279 y = (LINES-(msg_lines+4))/2;
280 x = (COLS-(total_width+4))/2;
281
282
283 /* create the windows */
284 if (btn_num > 0)
285 win_rows = msg_lines+4;
286 else
287 win_rows = msg_lines+2;
288
289 win = newwin(win_rows, total_width+4, y, x);
290 keypad(win, TRUE);
291 menu_win = derwin(win, 1, btns_width, win_rows-2,
292 1+(total_width+2-btns_width)/2);
293 menu = new_menu(btns);
294 msg_win = derwin(win, win_rows-2, msg_width, 1,
295 1+(total_width+2-msg_width)/2);
296
297 set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
298 set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
299
300 wattrset(win, attributes[DIALOG_BOX]);
301 box(win, 0, 0);
302
303 /* print message */
304 wattrset(msg_win, attributes[DIALOG_TEXT]);
305 fill_window(msg_win, msg);
306
307 set_menu_win(menu, win);
308 set_menu_sub(menu, menu_win);
309 set_menu_format(menu, 1, btn_num);
310 menu_opts_off(menu, O_SHOWDESC);
311 menu_opts_off(menu, O_SHOWMATCH);
312 menu_opts_on(menu, O_ONEVALUE);
313 menu_opts_on(menu, O_NONCYCLIC);
314 set_menu_mark(menu, "");
315 post_menu(menu);
316
317
318 touchwin(win);
319 refresh_all_windows(main_window);
320 while ((res = wgetch(win))) {
321 switch (res) {
322 case KEY_LEFT:
323 menu_driver(menu, REQ_LEFT_ITEM);
324 break;
325 case KEY_RIGHT:
326 menu_driver(menu, REQ_RIGHT_ITEM);
327 break;
328 case 10: /* ENTER */
329 case 27: /* ESCAPE */
330 case ' ':
331 case KEY_F(F_BACK):
332 case KEY_F(F_EXIT):
333 break;
334 }
335 touchwin(win);
336 refresh_all_windows(main_window);
337
338 if (res == 10 || res == ' ') {
339 res = item_index(current_item(menu));
340 break;
341 } else if (res == 27 || res == KEY_F(F_BACK) ||
342 res == KEY_F(F_EXIT)) {
343 res = KEY_EXIT;
344 break;
345 }
346 }
347
348 unpost_menu(menu);
349 free_menu(menu);
350 for (i = 0; i < btn_num; i++)
351 free_item(btns[i]);
352
353 delwin(win);
354 return res;
355}
356
357int dialog_inputbox(WINDOW *main_window,
358 const char *title, const char *prompt,
359 const char *init, char *result, int result_len)
360{
361 int prompt_lines = 0;
362 int prompt_width = 0;
363 WINDOW *win;
364 WINDOW *prompt_win;
365 WINDOW *form_win;
366 PANEL *panel;
367 int i, x, y;
368 int res = -1;
369 int cursor_position = strlen(init);
370
371
372 /* find the widest line of msg: */
373 prompt_lines = get_line_no(prompt);
374 for (i = 0; i < prompt_lines; i++) {
375 const char *line = get_line(prompt, i);
376 int len = get_line_length(line);
377 prompt_width = max(prompt_width, len);
378 }
379
380 if (title)
381 prompt_width = max(prompt_width, strlen(title));
382
383 /* place dialog in middle of screen */
384 y = (LINES-(prompt_lines+4))/2;
385 x = (COLS-(prompt_width+4))/2;
386
387 strncpy(result, init, result_len);
388
389 /* create the windows */
390 win = newwin(prompt_lines+6, prompt_width+7, y, x);
391 prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
392 form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
393 keypad(form_win, TRUE);
394
395 wattrset(form_win, attributes[INPUT_FIELD]);
396
397 wattrset(win, attributes[INPUT_BOX]);
398 box(win, 0, 0);
399 wattrset(win, attributes[INPUT_HEADING]);
400 if (title)
401 mvwprintw(win, 0, 3, "%s", title);
402
403 /* print message */
404 wattrset(prompt_win, attributes[INPUT_TEXT]);
405 fill_window(prompt_win, prompt);
406
407 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
408 mvwprintw(form_win, 0, 0, "%s", result);
409
410 /* create panels */
411 panel = new_panel(win);
412
413 /* show the cursor */
414 curs_set(1);
415
416 touchwin(win);
417 refresh_all_windows(main_window);
418 while ((res = wgetch(form_win))) {
419 int len = strlen(result);
420 switch (res) {
421 case 10: /* ENTER */
422 case 27: /* ESCAPE */
423 case KEY_F(F_HELP):
424 case KEY_F(F_EXIT):
425 case KEY_F(F_BACK):
426 break;
427 case 127:
428 case KEY_BACKSPACE:
429 if (cursor_position > 0) {
430 memmove(&result[cursor_position-1],
431 &result[cursor_position],
432 len-cursor_position+1);
433 cursor_position--;
434 }
435 break;
436 case KEY_DC:
437 if (cursor_position >= 0 && cursor_position < len) {
438 memmove(&result[cursor_position],
439 &result[cursor_position+1],
440 len-cursor_position+1);
441 }
442 break;
443 case KEY_UP:
444 case KEY_RIGHT:
445 if (cursor_position < len &&
446 cursor_position < min(result_len, prompt_width))
447 cursor_position++;
448 break;
449 case KEY_DOWN:
450 case KEY_LEFT:
451 if (cursor_position > 0)
452 cursor_position--;
453 break;
454 default:
455 if ((isgraph(res) || isspace(res)) &&
456 len-2 < result_len) {
457 /* insert the char at the proper position */
458 memmove(&result[cursor_position+1],
459 &result[cursor_position],
460 len+1);
461 result[cursor_position] = res;
462 cursor_position++;
463 } else {
464 mvprintw(0, 0, "unknow key: %d\n", res);
465 }
466 break;
467 }
468 wmove(form_win, 0, 0);
469 wclrtoeol(form_win);
470 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
471 mvwprintw(form_win, 0, 0, "%s", result);
472 wmove(form_win, 0, cursor_position);
473 touchwin(win);
474 refresh_all_windows(main_window);
475
476 if (res == 10) {
477 res = 0;
478 break;
479 } else if (res == 27 || res == KEY_F(F_BACK) ||
480 res == KEY_F(F_EXIT)) {
481 res = KEY_EXIT;
482 break;
483 } else if (res == KEY_F(F_HELP)) {
484 res = 1;
485 break;
486 }
487 }
488
489 /* hide the cursor */
490 curs_set(0);
491 del_panel(panel);
492 delwin(prompt_win);
493 delwin(form_win);
494 delwin(win);
495 return res;
496}
497
498/* refresh all windows in the correct order */
499void refresh_all_windows(WINDOW *main_window)
500{
501 update_panels();
502 touchwin(main_window);
503 refresh();
504}
505
506/* layman's scrollable window... */
507void show_scroll_win(WINDOW *main_window,
508 const char *title,
509 const char *text)
510{
511 int res;
512 int total_lines = get_line_no(text);
513 int x, y;
514 int start_x = 0, start_y = 0;
515 int text_lines = 0, text_cols = 0;
516 int total_cols = 0;
517 int win_cols = 0;
518 int win_lines = 0;
519 int i = 0;
520 WINDOW *win;
521 WINDOW *pad;
522 PANEL *panel;
523
524 /* find the widest line of msg: */
525 total_lines = get_line_no(text);
526 for (i = 0; i < total_lines; i++) {
527 const char *line = get_line(text, i);
528 int len = get_line_length(line);
529 total_cols = max(total_cols, len+2);
530 }
531
532 /* create the pad */
533 pad = newpad(total_lines+10, total_cols+10);
534 wattrset(pad, attributes[SCROLLWIN_TEXT]);
535 fill_window(pad, text);
536
537 win_lines = min(total_lines+4, LINES-2);
538 win_cols = min(total_cols+2, COLS-2);
539 text_lines = max(win_lines-4, 0);
540 text_cols = max(win_cols-2, 0);
541
542 /* place window in middle of screen */
543 y = (LINES-win_lines)/2;
544 x = (COLS-win_cols)/2;
545
546 win = newwin(win_lines, win_cols, y, x);
547 keypad(win, TRUE);
548 /* show the help in the help window, and show the help panel */
549 wattrset(win, attributes[SCROLLWIN_BOX]);
550 box(win, 0, 0);
551 wattrset(win, attributes[SCROLLWIN_HEADING]);
552 mvwprintw(win, 0, 3, " %s ", title);
553 panel = new_panel(win);
554
555 /* handle scrolling */
556 do {
557
558 copywin(pad, win, start_y, start_x, 2, 2, text_lines,
559 text_cols, 0);
560 print_in_middle(win,
561 text_lines+2,
562 0,
563 text_cols,
564 "<OK>",
565 attributes[DIALOG_MENU_FORE]);
566 wrefresh(win);
567
568 res = wgetch(win);
569 switch (res) {
570 case KEY_NPAGE:
571 case ' ':
572 start_y += text_lines-2;
573 break;
574 case KEY_PPAGE:
575 start_y -= text_lines+2;
576 break;
577 case KEY_HOME:
578 start_y = 0;
579 break;
580 case KEY_END:
581 start_y = total_lines-text_lines;
582 break;
583 case KEY_DOWN:
584 case 'j':
585 start_y++;
586 break;
587 case KEY_UP:
588 case 'k':
589 start_y--;
590 break;
591 case KEY_LEFT:
592 case 'h':
593 start_x--;
594 break;
595 case KEY_RIGHT:
596 case 'l':
597 start_x++;
598 break;
599 }
600 if (res == 10 || res == 27 || res == 'q'
601 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
602 break;
603 }
604 if (start_y < 0)
605 start_y = 0;
606 if (start_y >= total_lines-text_lines)
607 start_y = total_lines-text_lines;
608 if (start_x < 0)
609 start_x = 0;
610 if (start_x >= total_cols-text_cols)
611 start_x = total_cols-text_cols;
612 } while (res);
613
614 del_panel(panel);
615 delwin(win);
616 refresh_all_windows(main_window);
617}
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h
new file mode 100644
index 000000000000..fb4296666004
--- /dev/null
+++ b/scripts/kconfig/nconf.h
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Derived from menuconfig.
6 *
7 */
8
9#include <ctype.h>
10#include <errno.h>
11#include <fcntl.h>
12#include <limits.h>
13#include <stdarg.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17#include <locale.h>
18#include <curses.h>
19#include <menu.h>
20#include <panel.h>
21#include <form.h>
22
23#include <stdio.h>
24#include <time.h>
25#include <sys/time.h>
26
27#include "ncurses.h"
28
29#define max(a, b) ({\
30 typeof(a) _a = a;\
31 typeof(b) _b = b;\
32 _a > _b ? _a : _b; })
33
34#define min(a, b) ({\
35 typeof(a) _a = a;\
36 typeof(b) _b = b;\
37 _a < _b ? _a : _b; })
38
39typedef enum {
40 NORMAL = 1,
41 MAIN_HEADING,
42 MAIN_MENU_BOX,
43 MAIN_MENU_FORE,
44 MAIN_MENU_BACK,
45 MAIN_MENU_GREY,
46 MAIN_MENU_HEADING,
47 SCROLLWIN_TEXT,
48 SCROLLWIN_HEADING,
49 SCROLLWIN_BOX,
50 DIALOG_TEXT,
51 DIALOG_MENU_FORE,
52 DIALOG_MENU_BACK,
53 DIALOG_BOX,
54 INPUT_BOX,
55 INPUT_HEADING,
56 INPUT_TEXT,
57 INPUT_FIELD,
58 FUNCTION_TEXT,
59 FUNCTION_HIGHLIGHT,
60 ATTR_MAX
61} attributes_t;
62extern attributes_t attributes[];
63
64typedef enum {
65 F_HELP = 1,
66 F_SYMBOL = 2,
67 F_INSTS = 3,
68 F_CONF = 4,
69 F_BACK = 5,
70 F_SAVE = 6,
71 F_LOAD = 7,
72 F_EXIT = 8
73} function_key;
74
75void set_colors(void);
76
77/* this changes the windows attributes !!! */
78void print_in_middle(WINDOW *win,
79 int starty,
80 int startx,
81 int width,
82 const char *string,
83 chtype color);
84int get_line_length(const char *line);
85int get_line_no(const char *text);
86const char *get_line(const char *text, int line_no);
87void fill_window(WINDOW *win, const char *text);
88int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
89int dialog_inputbox(WINDOW *main_window,
90 const char *title, const char *prompt,
91 const char *init, char *result, int result_len);
92void refresh_all_windows(WINDOW *main_window);
93void show_scroll_win(WINDOW *main_window,
94 const char *title,
95 const char *text);
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 6c8fbbb66ebc..2e7a048e0cfc 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -651,12 +651,20 @@ bool sym_is_changable(struct symbol *sym)
651 return sym->visible > sym->rev_dep.tri; 651 return sym->visible > sym->rev_dep.tri;
652} 652}
653 653
654static unsigned strhash(const char *s)
655{
656 /* fnv32 hash */
657 unsigned hash = 2166136261U;
658 for (; *s; s++)
659 hash = (hash ^ *s) * 0x01000193;
660 return hash;
661}
662
654struct symbol *sym_lookup(const char *name, int flags) 663struct symbol *sym_lookup(const char *name, int flags)
655{ 664{
656 struct symbol *symbol; 665 struct symbol *symbol;
657 const char *ptr;
658 char *new_name; 666 char *new_name;
659 int hash = 0; 667 int hash;
660 668
661 if (name) { 669 if (name) {
662 if (name[0] && !name[1]) { 670 if (name[0] && !name[1]) {
@@ -666,12 +674,11 @@ struct symbol *sym_lookup(const char *name, int flags)
666 case 'n': return &symbol_no; 674 case 'n': return &symbol_no;
667 } 675 }
668 } 676 }
669 for (ptr = name; *ptr; ptr++) 677 hash = strhash(name) % SYMBOL_HASHSIZE;
670 hash += *ptr;
671 hash &= 0xff;
672 678
673 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 679 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
674 if (!strcmp(symbol->name, name) && 680 if (symbol->name &&
681 !strcmp(symbol->name, name) &&
675 (flags ? symbol->flags & flags 682 (flags ? symbol->flags & flags
676 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) 683 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
677 return symbol; 684 return symbol;
@@ -679,7 +686,7 @@ struct symbol *sym_lookup(const char *name, int flags)
679 new_name = strdup(name); 686 new_name = strdup(name);
680 } else { 687 } else {
681 new_name = NULL; 688 new_name = NULL;
682 hash = 256; 689 hash = 0;
683 } 690 }
684 691
685 symbol = malloc(sizeof(*symbol)); 692 symbol = malloc(sizeof(*symbol));
@@ -697,7 +704,6 @@ struct symbol *sym_lookup(const char *name, int flags)
697struct symbol *sym_find(const char *name) 704struct symbol *sym_find(const char *name)
698{ 705{
699 struct symbol *symbol = NULL; 706 struct symbol *symbol = NULL;
700 const char *ptr;
701 int hash = 0; 707 int hash = 0;
702 708
703 if (!name) 709 if (!name)
@@ -710,12 +716,11 @@ struct symbol *sym_find(const char *name)
710 case 'n': return &symbol_no; 716 case 'n': return &symbol_no;
711 } 717 }
712 } 718 }
713 for (ptr = name; *ptr; ptr++) 719 hash = strhash(name) % SYMBOL_HASHSIZE;
714 hash += *ptr;
715 hash &= 0xff;
716 720
717 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 721 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
718 if (!strcmp(symbol->name, name) && 722 if (symbol->name &&
723 !strcmp(symbol->name, name) &&
719 !(symbol->flags & SYMBOL_CONST)) 724 !(symbol->flags & SYMBOL_CONST))
720 break; 725 break;
721 } 726 }
@@ -750,6 +755,7 @@ struct symbol **sym_re_search(const char *pattern)
750 return NULL; 755 return NULL;
751 } 756 }
752 } 757 }
758 sym_calc_value(sym);
753 sym_arr[cnt++] = sym; 759 sym_arr[cnt++] = sym;
754 } 760 }
755 if (sym_arr) 761 if (sym_arr)
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 25d1ec4ca28a..78b5c04e736b 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -78,6 +78,7 @@ struct gstr str_new(void)
78 struct gstr gs; 78 struct gstr gs;
79 gs.s = malloc(sizeof(char) * 64); 79 gs.s = malloc(sizeof(char) * 64);
80 gs.len = 64; 80 gs.len = 64;
81 gs.max_width = 0;
81 strcpy(gs.s, "\0"); 82 strcpy(gs.s, "\0");
82 return gs; 83 return gs;
83} 84}
@@ -88,6 +89,7 @@ struct gstr str_assign(const char *s)
88 struct gstr gs; 89 struct gstr gs;
89 gs.s = strdup(s); 90 gs.s = strdup(s);
90 gs.len = strlen(s) + 1; 91 gs.len = strlen(s) + 1;
92 gs.max_width = 0;
91 return gs; 93 return gs;
92} 94}
93 95
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 6e9dcd59aa87..32a9eefd842c 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -104,7 +104,7 @@ static void zconf_error(const char *err, ...);
104static void zconferror(const char *err); 104static void zconferror(const char *err);
105static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); 105static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
106 106
107struct symbol *symbol_hash[257]; 107struct symbol *symbol_hash[SYMBOL_HASHSIZE];
108 108
109static struct menu *current_menu, *current_entry; 109static struct menu *current_menu, *current_entry;
110 110
@@ -2220,7 +2220,7 @@ void conf_parse(const char *name)
2220 zconf_initscan(name); 2220 zconf_initscan(name);
2221 2221
2222 sym_init(); 2222 sym_init();
2223 menu_init(); 2223 _menu_init();
2224 modules_sym = sym_lookup(NULL, 0); 2224 modules_sym = sym_lookup(NULL, 0);
2225 modules_sym->type = S_BOOLEAN; 2225 modules_sym->type = S_BOOLEAN;
2226 modules_sym->flags |= SYMBOL_AUTO; 2226 modules_sym->flags |= SYMBOL_AUTO;
@@ -2336,9 +2336,9 @@ static void print_symbol(FILE *out, struct menu *menu)
2336 struct property *prop; 2336 struct property *prop;
2337 2337
2338 if (sym_is_choice(sym)) 2338 if (sym_is_choice(sym))
2339 fprintf(out, "choice\n"); 2339 fprintf(out, "\nchoice\n");
2340 else 2340 else
2341 fprintf(out, "config %s\n", sym->name); 2341 fprintf(out, "\nconfig %s\n", sym->name);
2342 switch (sym->type) { 2342 switch (sym->type) {
2343 case S_BOOLEAN: 2343 case S_BOOLEAN:
2344 fputs(" boolean\n", out); 2344 fputs(" boolean\n", out);
@@ -2384,6 +2384,21 @@ static void print_symbol(FILE *out, struct menu *menu)
2384 case P_CHOICE: 2384 case P_CHOICE:
2385 fputs(" #choice value\n", out); 2385 fputs(" #choice value\n", out);
2386 break; 2386 break;
2387 case P_SELECT:
2388 fputs( " select ", out);
2389 expr_fprint(prop->expr, out);
2390 fputc('\n', out);
2391 break;
2392 case P_RANGE:
2393 fputs( " range ", out);
2394 expr_fprint(prop->expr, out);
2395 fputc('\n', out);
2396 break;
2397 case P_MENU:
2398 fputs( " menu ", out);
2399 print_quoted_string(out, prop->text);
2400 fputc('\n', out);
2401 break;
2387 default: 2402 default:
2388 fprintf(out, " unknown prop %d!\n", prop->type); 2403 fprintf(out, " unknown prop %d!\n", prop->type);
2389 break; 2404 break;
@@ -2395,7 +2410,6 @@ static void print_symbol(FILE *out, struct menu *menu)
2395 menu->help[len] = 0; 2410 menu->help[len] = 0;
2396 fprintf(out, " help\n%s\n", menu->help); 2411 fprintf(out, " help\n%s\n", menu->help);
2397 } 2412 }
2398 fputc('\n', out);
2399} 2413}
2400 2414
2401void zconfdump(FILE *out) 2415void zconfdump(FILE *out)
@@ -2428,7 +2442,6 @@ void zconfdump(FILE *out)
2428 expr_fprint(prop->visible.expr, out); 2442 expr_fprint(prop->visible.expr, out);
2429 fputc('\n', out); 2443 fputc('\n', out);
2430 } 2444 }
2431 fputs("\n", out);
2432 } 2445 }
2433 2446
2434 if (menu->list) 2447 if (menu->list)
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 8c43491f8cc9..23dfd3baa7a1 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -27,7 +27,7 @@ static void zconf_error(const char *err, ...);
27static void zconferror(const char *err); 27static void zconferror(const char *err);
28static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); 28static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
29 29
30struct symbol *symbol_hash[257]; 30struct symbol *symbol_hash[SYMBOL_HASHSIZE];
31 31
32static struct menu *current_menu, *current_entry; 32static struct menu *current_menu, *current_entry;
33 33
@@ -475,7 +475,7 @@ void conf_parse(const char *name)
475 zconf_initscan(name); 475 zconf_initscan(name);
476 476
477 sym_init(); 477 sym_init();
478 menu_init(); 478 _menu_init();
479 modules_sym = sym_lookup(NULL, 0); 479 modules_sym = sym_lookup(NULL, 0);
480 modules_sym->type = S_BOOLEAN; 480 modules_sym->type = S_BOOLEAN;
481 modules_sym->flags |= SYMBOL_AUTO; 481 modules_sym->flags |= SYMBOL_AUTO;
@@ -591,9 +591,9 @@ static void print_symbol(FILE *out, struct menu *menu)
591 struct property *prop; 591 struct property *prop;
592 592
593 if (sym_is_choice(sym)) 593 if (sym_is_choice(sym))
594 fprintf(out, "choice\n"); 594 fprintf(out, "\nchoice\n");
595 else 595 else
596 fprintf(out, "config %s\n", sym->name); 596 fprintf(out, "\nconfig %s\n", sym->name);
597 switch (sym->type) { 597 switch (sym->type) {
598 case S_BOOLEAN: 598 case S_BOOLEAN:
599 fputs(" boolean\n", out); 599 fputs(" boolean\n", out);
@@ -639,6 +639,21 @@ static void print_symbol(FILE *out, struct menu *menu)
639 case P_CHOICE: 639 case P_CHOICE:
640 fputs(" #choice value\n", out); 640 fputs(" #choice value\n", out);
641 break; 641 break;
642 case P_SELECT:
643 fputs( " select ", out);
644 expr_fprint(prop->expr, out);
645 fputc('\n', out);
646 break;
647 case P_RANGE:
648 fputs( " range ", out);
649 expr_fprint(prop->expr, out);
650 fputc('\n', out);
651 break;
652 case P_MENU:
653 fputs( " menu ", out);
654 print_quoted_string(out, prop->text);
655 fputc('\n', out);
656 break;
642 default: 657 default:
643 fprintf(out, " unknown prop %d!\n", prop->type); 658 fprintf(out, " unknown prop %d!\n", prop->type);
644 break; 659 break;
@@ -650,7 +665,6 @@ static void print_symbol(FILE *out, struct menu *menu)
650 menu->help[len] = 0; 665 menu->help[len] = 0;
651 fprintf(out, " help\n%s\n", menu->help); 666 fprintf(out, " help\n%s\n", menu->help);
652 } 667 }
653 fputc('\n', out);
654} 668}
655 669
656void zconfdump(FILE *out) 670void zconfdump(FILE *out)
@@ -683,7 +697,6 @@ void zconfdump(FILE *out)
683 expr_fprint(prop->visible.expr, out); 697 expr_fprint(prop->visible.expr, out);
684 fputc('\n', out); 698 fputc('\n', out);
685 } 699 }
686 fputs("\n", out);
687 } 700 }
688 701
689 if (menu->list) 702 if (menu->list)
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
index e950f9cde019..827896f56501 100644
--- a/scripts/markup_oops.pl
+++ b/scripts/markup_oops.pl
@@ -2,6 +2,7 @@
2 2
3use File::Basename; 3use File::Basename;
4use Math::BigInt; 4use Math::BigInt;
5use Getopt::Long;
5 6
6# Copyright 2008, Intel Corporation 7# Copyright 2008, Intel Corporation
7# 8#
@@ -15,6 +16,16 @@ use Math::BigInt;
15# Arjan van de Ven <arjan@linux.intel.com> 16# Arjan van de Ven <arjan@linux.intel.com>
16 17
17 18
19my $cross_compile = "";
20my $vmlinux_name = "";
21my $modulefile = "";
22
23# Get options
24Getopt::Long::GetOptions(
25 'cross-compile|c=s' => \$cross_compile,
26 'module|m=s' => \$modulefile,
27 'help|h' => \&usage,
28) || usage ();
18my $vmlinux_name = $ARGV[0]; 29my $vmlinux_name = $ARGV[0];
19if (!defined($vmlinux_name)) { 30if (!defined($vmlinux_name)) {
20 my $kerver = `uname -r`; 31 my $kerver = `uname -r`;
@@ -23,9 +34,8 @@ if (!defined($vmlinux_name)) {
23 print "No vmlinux specified, assuming $vmlinux_name\n"; 34 print "No vmlinux specified, assuming $vmlinux_name\n";
24} 35}
25my $filename = $vmlinux_name; 36my $filename = $vmlinux_name;
26# 37
27# Step 1: Parse the oops to find the EIP value 38# Parse the oops to find the EIP value
28#
29 39
30my $target = "0"; 40my $target = "0";
31my $function; 41my $function;
@@ -177,26 +187,26 @@ my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("
177my $decodestop = Math::BigInt->from_hex("0x$target") + 8192; 187my $decodestop = Math::BigInt->from_hex("0x$target") + 8192;
178if ($target eq "0") { 188if ($target eq "0") {
179 print "No oops found!\n"; 189 print "No oops found!\n";
180 print "Usage: \n"; 190 usage();
181 print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
182 exit;
183} 191}
184 192
185# if it's a module, we need to find the .ko file and calculate a load offset 193# if it's a module, we need to find the .ko file and calculate a load offset
186if ($module ne "") { 194if ($module ne "") {
187 my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`; 195 if ($modulefile eq "") {
188 chomp($modulefile); 196 $modulefile = `modinfo -F filename $module`;
197 chomp($modulefile);
198 }
189 $filename = $modulefile; 199 $filename = $modulefile;
190 if ($filename eq "") { 200 if ($filename eq "") {
191 print "Module .ko file for $module not found. Aborting\n"; 201 print "Module .ko file for $module not found. Aborting\n";
192 exit; 202 exit;
193 } 203 }
194 # ok so we found the module, now we need to calculate the vma offset 204 # ok so we found the module, now we need to calculate the vma offset
195 open(FILE, "objdump -dS $filename |") || die "Cannot start objdump"; 205 open(FILE, $cross_compile."objdump -dS $filename |") || die "Cannot start objdump";
196 while (<FILE>) { 206 while (<FILE>) {
197 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) { 207 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
198 my $fu = $1; 208 my $fu = $1;
199 $vmaoffset = hex($target) - hex($fu) - hex($func_offset); 209 $vmaoffset = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$fu") - Math::BigInt->from_hex("0x$func_offset");
200 } 210 }
201 } 211 }
202 close(FILE); 212 close(FILE);
@@ -204,7 +214,7 @@ if ($module ne "") {
204 214
205my $counter = 0; 215my $counter = 0;
206my $state = 0; 216my $state = 0;
207my $center = 0; 217my $center = -1;
208my @lines; 218my @lines;
209my @reglines; 219my @reglines;
210 220
@@ -212,7 +222,7 @@ sub InRange {
212 my ($address, $target) = @_; 222 my ($address, $target) = @_;
213 my $ad = "0x".$address; 223 my $ad = "0x".$address;
214 my $ta = "0x".$target; 224 my $ta = "0x".$target;
215 my $delta = hex($ad) - hex($ta); 225 my $delta = Math::BigInt->from_hex($ad) - Math::BigInt->from_hex($ta);
216 226
217 if (($delta > -4096) && ($delta < 4096)) { 227 if (($delta > -4096) && ($delta < 4096)) {
218 return 1; 228 return 1;
@@ -225,7 +235,7 @@ sub InRange {
225# first, parse the input into the lines array, but to keep size down, 235# first, parse the input into the lines array, but to keep size down,
226# we only do this for 4Kb around the sweet spot 236# we only do this for 4Kb around the sweet spot
227 237
228open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump"; 238open(FILE, $cross_compile."objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
229 239
230while (<FILE>) { 240while (<FILE>) {
231 my $line = $_; 241 my $line = $_;
@@ -236,7 +246,8 @@ while (<FILE>) {
236 $state = 1; 246 $state = 1;
237 } 247 }
238 } 248 }
239 } else { 249 }
250 if ($state == 1) {
240 if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) { 251 if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
241 my $val = $1; 252 my $val = $1;
242 if (!InRange($val, $target)) { 253 if (!InRange($val, $target)) {
@@ -259,7 +270,7 @@ if ($counter == 0) {
259 exit; 270 exit;
260} 271}
261 272
262if ($center == 0) { 273if ($center == -1) {
263 print "No matching code found \n"; 274 print "No matching code found \n";
264 exit; 275 exit;
265} 276}
@@ -344,3 +355,16 @@ while ($i < $finish) {
344 $i = $i +1; 355 $i = $i +1;
345} 356}
346 357
358sub usage {
359 print <<EOT;
360Usage:
361 dmesg | perl $0 [OPTION] [VMLINUX]
362
363OPTION:
364 -c, --cross-compile CROSS_COMPILE Specify the prefix used for toolchain.
365 -m, --module MODULE_DIRNAME Specify the module filename.
366 -h, --help Help.
367EOT
368 exit;
369}
370
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index 23dbad80cce9..50ad317a4bf9 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -67,9 +67,8 @@ UTS_TRUNCATE="cut -b -$UTS_LEN"
67 echo \#define LINUX_COMPILE_BY \"`whoami`\" 67 echo \#define LINUX_COMPILE_BY \"`whoami`\"
68 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" 68 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
69 69
70 if [ -x /bin/dnsdomainname ]; then 70 domain=`dnsdomainname 2> /dev/null`
71 domain=`dnsdomainname 2> /dev/null` 71 if [ -z "$domain" ]; then
72 elif [ -x /bin/domainname ]; then
73 domain=`domainname 2> /dev/null` 72 domain=`domainname 2> /dev/null`
74 fi 73 fi
75 74
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 20923613467c..3318692e4e76 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -781,10 +781,13 @@ static void check_section(const char *modname, struct elf_info *elf,
781#define ALL_EXIT_TEXT_SECTIONS \ 781#define ALL_EXIT_TEXT_SECTIONS \
782 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" 782 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
783 783
784#define ALL_INIT_SECTIONS INIT_SECTIONS, DEV_INIT_SECTIONS, \ 784#define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
785 CPU_INIT_SECTIONS, MEM_INIT_SECTIONS 785 MEM_INIT_SECTIONS
786#define ALL_EXIT_SECTIONS EXIT_SECTIONS, DEV_EXIT_SECTIONS, \ 786#define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
787 CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS 787 MEM_EXIT_SECTIONS
788
789#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
790#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
788 791
789#define DATA_SECTIONS ".data$", ".data.rel$" 792#define DATA_SECTIONS ".data$", ".data.rel$"
790#define TEXT_SECTIONS ".text$" 793#define TEXT_SECTIONS ".text$"
@@ -814,33 +817,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
814 817
815 818
816/* symbols in .data that may refer to init/exit sections */ 819/* symbols in .data that may refer to init/exit sections */
817static const char *symbol_white_list[] = 820#define DEFAULT_SYMBOL_WHITE_LIST \
818{ 821 "*driver", \
819 "*driver", 822 "*_template", /* scsi uses *_template a lot */ \
820 "*_template", /* scsi uses *_template a lot */ 823 "*_timer", /* arm uses ops structures named _timer a lot */ \
821 "*_timer", /* arm uses ops structures named _timer a lot */ 824 "*_sht", /* scsi also used *_sht to some extent */ \
822 "*_sht", /* scsi also used *_sht to some extent */ 825 "*_ops", \
823 "*_ops", 826 "*_probe", \
824 "*_probe", 827 "*_probe_one", \
825 "*_probe_one", 828 "*_console"
826 "*_console",
827 NULL
828};
829 829
830static const char *head_sections[] = { ".head.text*", NULL }; 830static const char *head_sections[] = { ".head.text*", NULL };
831static const char *linker_symbols[] = 831static const char *linker_symbols[] =
832 { "__init_begin", "_sinittext", "_einittext", NULL }; 832 { "__init_begin", "_sinittext", "_einittext", NULL };
833 833
834enum mismatch { 834enum mismatch {
835 NO_MISMATCH, 835 TEXT_TO_ANY_INIT,
836 TEXT_TO_INIT, 836 DATA_TO_ANY_INIT,
837 DATA_TO_INIT, 837 TEXT_TO_ANY_EXIT,
838 TEXT_TO_EXIT, 838 DATA_TO_ANY_EXIT,
839 DATA_TO_EXIT, 839 XXXINIT_TO_SOME_INIT,
840 XXXINIT_TO_INIT, 840 XXXEXIT_TO_SOME_EXIT,
841 XXXEXIT_TO_EXIT, 841 ANY_INIT_TO_ANY_EXIT,
842 INIT_TO_EXIT, 842 ANY_EXIT_TO_ANY_INIT,
843 EXIT_TO_INIT,
844 EXPORT_TO_INIT_EXIT, 843 EXPORT_TO_INIT_EXIT,
845}; 844};
846 845
@@ -848,6 +847,7 @@ struct sectioncheck {
848 const char *fromsec[20]; 847 const char *fromsec[20];
849 const char *tosec[20]; 848 const char *tosec[20];
850 enum mismatch mismatch; 849 enum mismatch mismatch;
850 const char *symbol_white_list[20];
851}; 851};
852 852
853const struct sectioncheck sectioncheck[] = { 853const struct sectioncheck sectioncheck[] = {
@@ -857,80 +857,103 @@ const struct sectioncheck sectioncheck[] = {
857{ 857{
858 .fromsec = { TEXT_SECTIONS, NULL }, 858 .fromsec = { TEXT_SECTIONS, NULL },
859 .tosec = { ALL_INIT_SECTIONS, NULL }, 859 .tosec = { ALL_INIT_SECTIONS, NULL },
860 .mismatch = TEXT_TO_INIT, 860 .mismatch = TEXT_TO_ANY_INIT,
861 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
861}, 862},
862{ 863{
863 .fromsec = { DATA_SECTIONS, NULL }, 864 .fromsec = { DATA_SECTIONS, NULL },
864 .tosec = { ALL_INIT_SECTIONS, NULL }, 865 .tosec = { ALL_XXXINIT_SECTIONS, NULL },
865 .mismatch = DATA_TO_INIT, 866 .mismatch = DATA_TO_ANY_INIT,
867 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
868},
869{
870 .fromsec = { DATA_SECTIONS, NULL },
871 .tosec = { INIT_SECTIONS, NULL },
872 .mismatch = DATA_TO_ANY_INIT,
873 .symbol_white_list = {
874 "*_template", "*_timer", "*_sht", "*_ops",
875 "*_probe", "*_probe_one", "*_console", NULL
876 },
866}, 877},
867{ 878{
868 .fromsec = { TEXT_SECTIONS, NULL }, 879 .fromsec = { TEXT_SECTIONS, NULL },
869 .tosec = { ALL_EXIT_SECTIONS, NULL }, 880 .tosec = { ALL_EXIT_SECTIONS, NULL },
870 .mismatch = TEXT_TO_EXIT, 881 .mismatch = TEXT_TO_ANY_EXIT,
882 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
871}, 883},
872{ 884{
873 .fromsec = { DATA_SECTIONS, NULL }, 885 .fromsec = { DATA_SECTIONS, NULL },
874 .tosec = { ALL_EXIT_SECTIONS, NULL }, 886 .tosec = { ALL_EXIT_SECTIONS, NULL },
875 .mismatch = DATA_TO_EXIT, 887 .mismatch = DATA_TO_ANY_EXIT,
888 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
876}, 889},
877/* Do not reference init code/data from devinit/cpuinit/meminit code/data */ 890/* Do not reference init code/data from devinit/cpuinit/meminit code/data */
878{ 891{
879 .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL }, 892 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
880 .tosec = { INIT_SECTIONS, NULL }, 893 .tosec = { INIT_SECTIONS, NULL },
881 .mismatch = XXXINIT_TO_INIT, 894 .mismatch = XXXINIT_TO_SOME_INIT,
895 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
882}, 896},
883/* Do not reference cpuinit code/data from meminit code/data */ 897/* Do not reference cpuinit code/data from meminit code/data */
884{ 898{
885 .fromsec = { MEM_INIT_SECTIONS, NULL }, 899 .fromsec = { MEM_INIT_SECTIONS, NULL },
886 .tosec = { CPU_INIT_SECTIONS, NULL }, 900 .tosec = { CPU_INIT_SECTIONS, NULL },
887 .mismatch = XXXINIT_TO_INIT, 901 .mismatch = XXXINIT_TO_SOME_INIT,
902 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
888}, 903},
889/* Do not reference meminit code/data from cpuinit code/data */ 904/* Do not reference meminit code/data from cpuinit code/data */
890{ 905{
891 .fromsec = { CPU_INIT_SECTIONS, NULL }, 906 .fromsec = { CPU_INIT_SECTIONS, NULL },
892 .tosec = { MEM_INIT_SECTIONS, NULL }, 907 .tosec = { MEM_INIT_SECTIONS, NULL },
893 .mismatch = XXXINIT_TO_INIT, 908 .mismatch = XXXINIT_TO_SOME_INIT,
909 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
894}, 910},
895/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ 911/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
896{ 912{
897 .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL }, 913 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
898 .tosec = { EXIT_SECTIONS, NULL }, 914 .tosec = { EXIT_SECTIONS, NULL },
899 .mismatch = XXXEXIT_TO_EXIT, 915 .mismatch = XXXEXIT_TO_SOME_EXIT,
916 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
900}, 917},
901/* Do not reference cpuexit code/data from memexit code/data */ 918/* Do not reference cpuexit code/data from memexit code/data */
902{ 919{
903 .fromsec = { MEM_EXIT_SECTIONS, NULL }, 920 .fromsec = { MEM_EXIT_SECTIONS, NULL },
904 .tosec = { CPU_EXIT_SECTIONS, NULL }, 921 .tosec = { CPU_EXIT_SECTIONS, NULL },
905 .mismatch = XXXEXIT_TO_EXIT, 922 .mismatch = XXXEXIT_TO_SOME_EXIT,
923 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
906}, 924},
907/* Do not reference memexit code/data from cpuexit code/data */ 925/* Do not reference memexit code/data from cpuexit code/data */
908{ 926{
909 .fromsec = { CPU_EXIT_SECTIONS, NULL }, 927 .fromsec = { CPU_EXIT_SECTIONS, NULL },
910 .tosec = { MEM_EXIT_SECTIONS, NULL }, 928 .tosec = { MEM_EXIT_SECTIONS, NULL },
911 .mismatch = XXXEXIT_TO_EXIT, 929 .mismatch = XXXEXIT_TO_SOME_EXIT,
930 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
912}, 931},
913/* Do not use exit code/data from init code */ 932/* Do not use exit code/data from init code */
914{ 933{
915 .fromsec = { ALL_INIT_SECTIONS, NULL }, 934 .fromsec = { ALL_INIT_SECTIONS, NULL },
916 .tosec = { ALL_EXIT_SECTIONS, NULL }, 935 .tosec = { ALL_EXIT_SECTIONS, NULL },
917 .mismatch = INIT_TO_EXIT, 936 .mismatch = ANY_INIT_TO_ANY_EXIT,
937 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
918}, 938},
919/* Do not use init code/data from exit code */ 939/* Do not use init code/data from exit code */
920{ 940{
921 .fromsec = { ALL_EXIT_SECTIONS, NULL }, 941 .fromsec = { ALL_EXIT_SECTIONS, NULL },
922 .tosec = { ALL_INIT_SECTIONS, NULL }, 942 .tosec = { ALL_INIT_SECTIONS, NULL },
923 .mismatch = EXIT_TO_INIT, 943 .mismatch = ANY_EXIT_TO_ANY_INIT,
944 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
924}, 945},
925/* Do not export init/exit functions or data */ 946/* Do not export init/exit functions or data */
926{ 947{
927 .fromsec = { "__ksymtab*", NULL }, 948 .fromsec = { "__ksymtab*", NULL },
928 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, 949 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
929 .mismatch = EXPORT_TO_INIT_EXIT 950 .mismatch = EXPORT_TO_INIT_EXIT,
951 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
930} 952}
931}; 953};
932 954
933static int section_mismatch(const char *fromsec, const char *tosec) 955static const struct sectioncheck *section_mismatch(
956 const char *fromsec, const char *tosec)
934{ 957{
935 int i; 958 int i;
936 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); 959 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
@@ -939,10 +962,10 @@ static int section_mismatch(const char *fromsec, const char *tosec)
939 for (i = 0; i < elems; i++) { 962 for (i = 0; i < elems; i++) {
940 if (match(fromsec, check->fromsec) && 963 if (match(fromsec, check->fromsec) &&
941 match(tosec, check->tosec)) 964 match(tosec, check->tosec))
942 return check->mismatch; 965 return check;
943 check++; 966 check++;
944 } 967 }
945 return NO_MISMATCH; 968 return NULL;
946} 969}
947 970
948/** 971/**
@@ -961,7 +984,7 @@ static int section_mismatch(const char *fromsec, const char *tosec)
961 * Pattern 2: 984 * Pattern 2:
962 * Many drivers utilise a *driver container with references to 985 * Many drivers utilise a *driver container with references to
963 * add, remove, probe functions etc. 986 * add, remove, probe functions etc.
964 * These functions may often be marked __init and we do not want to 987 * These functions may often be marked __devinit and we do not want to
965 * warn here. 988 * warn here.
966 * the pattern is identified by: 989 * the pattern is identified by:
967 * tosec = init or exit section 990 * tosec = init or exit section
@@ -982,7 +1005,8 @@ static int section_mismatch(const char *fromsec, const char *tosec)
982 * refsymname = __init_begin, _sinittext, _einittext 1005 * refsymname = __init_begin, _sinittext, _einittext
983 * 1006 *
984 **/ 1007 **/
985static int secref_whitelist(const char *fromsec, const char *fromsym, 1008static int secref_whitelist(const struct sectioncheck *mismatch,
1009 const char *fromsec, const char *fromsym,
986 const char *tosec, const char *tosym) 1010 const char *tosec, const char *tosym)
987{ 1011{
988 /* Check for pattern 1 */ 1012 /* Check for pattern 1 */
@@ -994,7 +1018,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
994 /* Check for pattern 2 */ 1018 /* Check for pattern 2 */
995 if (match(tosec, init_exit_sections) && 1019 if (match(tosec, init_exit_sections) &&
996 match(fromsec, data_sections) && 1020 match(fromsec, data_sections) &&
997 match(fromsym, symbol_white_list)) 1021 match(fromsym, mismatch->symbol_white_list))
998 return 0; 1022 return 0;
999 1023
1000 /* Check for pattern 3 */ 1024 /* Check for pattern 3 */
@@ -1155,7 +1179,8 @@ static int is_function(Elf_Sym *sym)
1155 * Try to find symbols near it so user can find it. 1179 * Try to find symbols near it so user can find it.
1156 * Check whitelist before warning - it may be a false positive. 1180 * Check whitelist before warning - it may be a false positive.
1157 */ 1181 */
1158static void report_sec_mismatch(const char *modname, enum mismatch mismatch, 1182static void report_sec_mismatch(const char *modname,
1183 const struct sectioncheck *mismatch,
1159 const char *fromsec, 1184 const char *fromsec,
1160 unsigned long long fromaddr, 1185 unsigned long long fromaddr,
1161 const char *fromsym, 1186 const char *fromsym,
@@ -1186,8 +1211,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1186 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, 1211 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1187 tosym, to_p); 1212 tosym, to_p);
1188 1213
1189 switch (mismatch) { 1214 switch (mismatch->mismatch) {
1190 case TEXT_TO_INIT: 1215 case TEXT_TO_ANY_INIT:
1191 fprintf(stderr, 1216 fprintf(stderr,
1192 "The function %s%s() references\n" 1217 "The function %s%s() references\n"
1193 "the %s %s%s%s.\n" 1218 "the %s %s%s%s.\n"
@@ -1197,8 +1222,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1197 to, sec2annotation(tosec), tosym, to_p, 1222 to, sec2annotation(tosec), tosym, to_p,
1198 fromsym, sec2annotation(tosec), tosym); 1223 fromsym, sec2annotation(tosec), tosym);
1199 break; 1224 break;
1200 case DATA_TO_INIT: { 1225 case DATA_TO_ANY_INIT: {
1201 const char **s = symbol_white_list; 1226 const char *const *s = mismatch->symbol_white_list;
1202 fprintf(stderr, 1227 fprintf(stderr,
1203 "The variable %s references\n" 1228 "The variable %s references\n"
1204 "the %s %s%s%s\n" 1229 "the %s %s%s%s\n"
@@ -1211,15 +1236,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1211 fprintf(stderr, "\n"); 1236 fprintf(stderr, "\n");
1212 break; 1237 break;
1213 } 1238 }
1214 case TEXT_TO_EXIT: 1239 case TEXT_TO_ANY_EXIT:
1215 fprintf(stderr, 1240 fprintf(stderr,
1216 "The function %s() references a %s in an exit section.\n" 1241 "The function %s() references a %s in an exit section.\n"
1217 "Often the %s %s%s has valid usage outside the exit section\n" 1242 "Often the %s %s%s has valid usage outside the exit section\n"
1218 "and the fix is to remove the %sannotation of %s.\n", 1243 "and the fix is to remove the %sannotation of %s.\n",
1219 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); 1244 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
1220 break; 1245 break;
1221 case DATA_TO_EXIT: { 1246 case DATA_TO_ANY_EXIT: {
1222 const char **s = symbol_white_list; 1247 const char *const *s = mismatch->symbol_white_list;
1223 fprintf(stderr, 1248 fprintf(stderr,
1224 "The variable %s references\n" 1249 "The variable %s references\n"
1225 "the %s %s%s%s\n" 1250 "the %s %s%s%s\n"
@@ -1232,8 +1257,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1232 fprintf(stderr, "\n"); 1257 fprintf(stderr, "\n");
1233 break; 1258 break;
1234 } 1259 }
1235 case XXXINIT_TO_INIT: 1260 case XXXINIT_TO_SOME_INIT:
1236 case XXXEXIT_TO_EXIT: 1261 case XXXEXIT_TO_SOME_EXIT:
1237 fprintf(stderr, 1262 fprintf(stderr,
1238 "The %s %s%s%s references\n" 1263 "The %s %s%s%s references\n"
1239 "a %s %s%s%s.\n" 1264 "a %s %s%s%s.\n"
@@ -1243,7 +1268,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1243 to, sec2annotation(tosec), tosym, to_p, 1268 to, sec2annotation(tosec), tosym, to_p,
1244 tosym, fromsym, tosym); 1269 tosym, fromsym, tosym);
1245 break; 1270 break;
1246 case INIT_TO_EXIT: 1271 case ANY_INIT_TO_ANY_EXIT:
1247 fprintf(stderr, 1272 fprintf(stderr,
1248 "The %s %s%s%s references\n" 1273 "The %s %s%s%s references\n"
1249 "a %s %s%s%s.\n" 1274 "a %s %s%s%s.\n"
@@ -1256,7 +1281,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1256 to, sec2annotation(tosec), tosym, to_p, 1281 to, sec2annotation(tosec), tosym, to_p,
1257 sec2annotation(tosec), tosym, to_p); 1282 sec2annotation(tosec), tosym, to_p);
1258 break; 1283 break;
1259 case EXIT_TO_INIT: 1284 case ANY_EXIT_TO_ANY_INIT:
1260 fprintf(stderr, 1285 fprintf(stderr,
1261 "The %s %s%s%s references\n" 1286 "The %s %s%s%s references\n"
1262 "a %s %s%s%s.\n" 1287 "a %s %s%s%s.\n"
@@ -1275,8 +1300,6 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1275 "Fix this by removing the %sannotation of %s " 1300 "Fix this by removing the %sannotation of %s "
1276 "or drop the export.\n", 1301 "or drop the export.\n",
1277 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); 1302 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
1278 case NO_MISMATCH:
1279 /* To get warnings on missing members */
1280 break; 1303 break;
1281 } 1304 }
1282 fprintf(stderr, "\n"); 1305 fprintf(stderr, "\n");
@@ -1286,11 +1309,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1286 Elf_Rela *r, Elf_Sym *sym, const char *fromsec) 1309 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1287{ 1310{
1288 const char *tosec; 1311 const char *tosec;
1289 enum mismatch mismatch; 1312 const struct sectioncheck *mismatch;
1290 1313
1291 tosec = sec_name(elf, sym->st_shndx); 1314 tosec = sec_name(elf, sym->st_shndx);
1292 mismatch = section_mismatch(fromsec, tosec); 1315 mismatch = section_mismatch(fromsec, tosec);
1293 if (mismatch != NO_MISMATCH) { 1316 if (mismatch) {
1294 Elf_Sym *to; 1317 Elf_Sym *to;
1295 Elf_Sym *from; 1318 Elf_Sym *from;
1296 const char *tosym; 1319 const char *tosym;
@@ -1302,7 +1325,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1302 tosym = sym_name(elf, to); 1325 tosym = sym_name(elf, to);
1303 1326
1304 /* check whitelist - we may ignore it */ 1327 /* check whitelist - we may ignore it */
1305 if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { 1328 if (secref_whitelist(mismatch,
1329 fromsec, fromsym, tosec, tosym)) {
1306 report_sec_mismatch(modname, mismatch, 1330 report_sec_mismatch(modname, mismatch,
1307 fromsec, r->r_offset, fromsym, 1331 fromsec, r->r_offset, fromsym,
1308 is_function(from), tosec, tosym, 1332 is_function(from), tosec, tosym,
diff --git a/scripts/namespace.pl b/scripts/namespace.pl
index c6e88c652c2f..361d0f71184b 100755
--- a/scripts/namespace.pl
+++ b/scripts/namespace.pl
@@ -175,12 +175,11 @@ sub do_nm
175 } 175 }
176 if (! -e "$source.c" && ! -e "$source.S") { 176 if (! -e "$source.c" && ! -e "$source.S") {
177 # No obvious source, exclude the object if it is conglomerate 177 # No obvious source, exclude the object if it is conglomerate
178 if (! open(OBJDUMPDATA, "$objdump $basename|")) { 178 open(my $objdumpdata, "$objdump $basename|")
179 printf STDERR "$objdump $fullname failed $!\n"; 179 or die "$objdump $fullname failed $!\n";
180 return; 180
181 }
182 my $comment; 181 my $comment;
183 while (<OBJDUMPDATA>) { 182 while (<$objdumpdata>) {
184 chomp(); 183 chomp();
185 if (/^In archive/) { 184 if (/^In archive/) {
186 # Archives are always conglomerate 185 # Archives are always conglomerate
@@ -190,18 +189,18 @@ sub do_nm
190 next if (! /^[ 0-9a-f]{5,} /); 189 next if (! /^[ 0-9a-f]{5,} /);
191 $comment .= substr($_, 43); 190 $comment .= substr($_, 43);
192 } 191 }
193 close(OBJDUMPDATA); 192 close($objdumpdata);
193
194 if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) { 194 if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
195 printf STDERR "No source file found for $fullname\n"; 195 printf STDERR "No source file found for $fullname\n";
196 } 196 }
197 return; 197 return;
198 } 198 }
199 if (! open(NMDATA, "$nm $basename|")) { 199 open (my $nmdata, "$nm $basename|")
200 printf STDERR "$nm $fullname failed $!\n"; 200 or die "$nm $fullname failed $!\n";
201 return; 201
202 }
203 my @nmdata; 202 my @nmdata;
204 while (<NMDATA>) { 203 while (<$nmdata>) {
205 chop; 204 chop;
206 ($type, $name) = (split(/ +/, $_, 3))[1..2]; 205 ($type, $name) = (split(/ +/, $_, 3))[1..2];
207 # Expected types 206 # Expected types
@@ -268,7 +267,8 @@ sub do_nm
268 } 267 }
269 } 268 }
270 } 269 }
271 close(NMDATA); 270 close($nmdata);
271
272 if ($#nmdata < 0) { 272 if ($#nmdata < 0) {
273 if ( 273 if (
274 $fullname ne "lib/brlock.o" 274 $fullname ne "lib/brlock.o"
@@ -316,8 +316,7 @@ sub drop_def
316 316
317sub list_multiply_defined 317sub list_multiply_defined
318{ 318{
319 my ($name, $module); 319 foreach my $name (keys(%def)) {
320 foreach $name (keys(%def)) {
321 if ($#{$def{$name}} > 0) { 320 if ($#{$def{$name}} > 0) {
322 # Special case for cond_syscall 321 # Special case for cond_syscall
323 if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && 322 if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
@@ -333,8 +332,9 @@ sub list_multiply_defined
333 &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name); 332 &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
334 next; 333 next;
335 } 334 }
335
336 printf "$name is multiply defined in :-\n"; 336 printf "$name is multiply defined in :-\n";
337 foreach $module (@{$def{$name}}) { 337 foreach my $module (@{$def{$name}}) {
338 printf "\t$module\n"; 338 printf "\t$module\n";
339 } 339 }
340 } 340 }
@@ -343,12 +343,13 @@ sub list_multiply_defined
343 343
344sub resolve_external_references 344sub resolve_external_references
345{ 345{
346 my ($object, $type, $name, $i, $j, $kstrtab, $ksymtab, $export); 346 my ($kstrtab, $ksymtab, $export);
347
347 printf "\n"; 348 printf "\n";
348 foreach $object (keys(%nmdata)) { 349 foreach my $object (keys(%nmdata)) {
349 my $nmdata = $nmdata{$object}; 350 my $nmdata = $nmdata{$object};
350 for ($i = 0; $i <= $#{$nmdata}; ++$i) { 351 for (my $i = 0; $i <= $#{$nmdata}; ++$i) {
351 ($type, $name) = split(' ', $nmdata->[$i], 2); 352 my ($type, $name) = split(' ', $nmdata->[$i], 2);
352 if ($type eq "U" || $type eq "w") { 353 if ($type eq "U" || $type eq "w") {
353 if (exists($def{$name}) || exists($ksymtab{$name})) { 354 if (exists($def{$name}) || exists($ksymtab{$name})) {
354 # add the owning object to the nmdata 355 # add the owning object to the nmdata
@@ -357,7 +358,7 @@ sub resolve_external_references
357 $kstrtab = "R __kstrtab_$name"; 358 $kstrtab = "R __kstrtab_$name";
358 $ksymtab = "R __ksymtab_$name"; 359 $ksymtab = "R __ksymtab_$name";
359 $export = 0; 360 $export = 0;
360 for ($j = 0; $j <= $#{$nmdata}; ++$j) { 361 for (my $j = 0; $j <= $#{$nmdata}; ++$j) {
361 if ($nmdata->[$j] eq $kstrtab || 362 if ($nmdata->[$j] eq $kstrtab ||
362 $nmdata->[$j] eq $ksymtab) { 363 $nmdata->[$j] eq $ksymtab) {
363 $export = 1; 364 $export = 1;
@@ -424,11 +425,11 @@ sub resolve_external_references
424sub list_extra_externals 425sub list_extra_externals
425{ 426{
426 my %noref = (); 427 my %noref = ();
427 my ($name, @module, $module, $export); 428
428 foreach $name (keys(%def)) { 429 foreach my $name (keys(%def)) {
429 if (! exists($ref{$name})) { 430 if (! exists($ref{$name})) {
430 @module = @{$def{$name}}; 431 my @module = @{$def{$name}};
431 foreach $module (@module) { 432 foreach my $module (@module) {
432 if (! exists($noref{$module})) { 433 if (! exists($noref{$module})) {
433 $noref{$module} = []; 434 $noref{$module} = [];
434 } 435 }
@@ -438,16 +439,16 @@ sub list_extra_externals
438 } 439 }
439 if (%noref) { 440 if (%noref) {
440 printf "\nExternally defined symbols with no external references\n"; 441 printf "\nExternally defined symbols with no external references\n";
441 foreach $module (sort(keys(%noref))) { 442 foreach my $module (sort(keys(%noref))) {
442 printf " $module\n"; 443 printf " $module\n";
443 foreach (sort(@{$noref{$module}})) { 444 foreach (sort(@{$noref{$module}})) {
444 if (exists($export{$_})) { 445 my $export;
445 $export = " (export only)"; 446 if (exists($export{$_})) {
446 } 447 $export = " (export only)";
447 else { 448 } else {
448 $export = ""; 449 $export = "";
449 } 450 }
450 printf " $_$export\n"; 451 printf " $_$export\n";
451 } 452 }
452 } 453 }
453 } 454 }
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 8b357b0bd250..07f2fbde2abf 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -18,6 +18,8 @@ create_package() {
18 cp debian/copyright "$pdir/usr/share/doc/$pname/" 18 cp debian/copyright "$pdir/usr/share/doc/$pname/"
19 cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian" 19 cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian"
20 gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian" 20 gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian"
21 sh -c "cd '$pdir'; find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
22 | xargs -r0 md5sum > DEBIAN/md5sums"
21 23
22 # Fix ownership and permissions 24 # Fix ownership and permissions
23 chown -R root:root "$pdir" 25 chown -R root:root "$pdir"
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index fa27f3dac769..15440f55aef6 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -39,7 +39,7 @@ if ! $PREBUILT; then
39echo "Source: kernel-$__KERNELRELEASE.tar.gz" 39echo "Source: kernel-$__KERNELRELEASE.tar.gz"
40fi 40fi
41 41
42echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root" 42echo "BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root"
43echo "Provides: $PROVIDES" 43echo "Provides: $PROVIDES"
44echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :" 44echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
45echo "%define debug_package %{nil}" 45echo "%define debug_package %{nil}"
diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl
index cb4260ebdb91..6943fa7cc95b 100644
--- a/scripts/profile2linkerlist.pl
+++ b/scripts/profile2linkerlist.pl
@@ -7,15 +7,13 @@
7# usage: 7# usage:
8# readprofile | sort -rn | perl profile2linkerlist.pl > functionlist 8# readprofile | sort -rn | perl profile2linkerlist.pl > functionlist
9# 9#
10use strict;
10 11
11while (<>) { 12while (<>) {
12 my $line = $_; 13 my $line = $_;
13 14
14 $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/; 15 $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/;
15 16
16 if ( ($line =~ /unknown/) || ($line =~ /total/)) { 17 print "*(.text.$1)\n"
17 18 unless ($line =~ /unknown/) || ($line =~ /total/);
18 } else {
19 print "*(.text.$1)\n";
20 }
21} 19}
diff --git a/scripts/rt-tester/rt-tester.py b/scripts/rt-tester/rt-tester.py
index 4c79660793cf..44423b4dcb82 100644
--- a/scripts/rt-tester/rt-tester.py
+++ b/scripts/rt-tester/rt-tester.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python 1#!/usr/bin/python
2# 2#
3# rt-mutex tester 3# rt-mutex tester
4# 4#
diff --git a/scripts/show_delta b/scripts/show_delta
index 48a706ab3d0c..17df3051747a 100755
--- a/scripts/show_delta
+++ b/scripts/show_delta
@@ -1,4 +1,4 @@
1#!/usr/bin/env python 1#!/usr/bin/python
2# 2#
3# show_deltas: Read list of printk messages instrumented with 3# show_deltas: Read list of printk messages instrumented with
4# time data, and format with time deltas. 4# time data, and format with time deltas.
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 1a0c44d7c4a7..8509bb512935 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -5,7 +5,7 @@
5# mode may be any of: tags, TAGS, cscope 5# mode may be any of: tags, TAGS, cscope
6# 6#
7# Uses the following environment variables: 7# Uses the following environment variables:
8# ARCH, SUBARCH, srctree, src, obj 8# ARCH, SUBARCH, SRCARCH, srctree, src, obj
9 9
10if [ "$KBUILD_VERBOSE" = "1" ]; then 10if [ "$KBUILD_VERBOSE" = "1" ]; then
11 set -x 11 set -x
@@ -17,28 +17,48 @@ ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \
17 -name .git ) \ 17 -name .git ) \
18 -prune -o" 18 -prune -o"
19 19
20# Do not use full path is we do not use O=.. builds 20# Do not use full path if we do not use O=.. builds
21# Use make O=. {tags|cscope}
22# to force full paths for a non-O= build
21if [ "${KBUILD_SRC}" = "" ]; then 23if [ "${KBUILD_SRC}" = "" ]; then
22 tree= 24 tree=
23else 25else
24 tree=${srctree}/ 26 tree=${srctree}/
25fi 27fi
26 28
29# Find all available archs
30find_all_archs()
31{
32 ALLSOURCE_ARCHS=""
33 for arch in `ls ${tree}arch`; do
34 ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/}
35 done
36}
37
27# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH 38# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
28if [ "${ALLSOURCE_ARCHS}" = "" ]; then 39if [ "${ALLSOURCE_ARCHS}" = "" ]; then
29 ALLSOURCE_ARCHS=${SRCARCH} 40 ALLSOURCE_ARCHS=${SRCARCH}
41elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then
42 find_all_archs
30fi 43fi
31 44
32# find sources in arch/$ARCH 45# find sources in arch/$ARCH
33find_arch_sources() 46find_arch_sources()
34{ 47{
35 find ${tree}arch/$1 $ignore -name "$2" -print; 48 for i in $archincludedir; do
49 prune="$prune -wholename $i -prune -o"
50 done
51 find ${tree}arch/$1 $ignore $prune -name "$2" -print;
36} 52}
37 53
38# find sources in arch/$1/include 54# find sources in arch/$1/include
39find_arch_include_sources() 55find_arch_include_sources()
40{ 56{
41 find ${tree}arch/$1/include $ignore -name "$2" -print; 57 include=$(find ${tree}arch/$1/ -name include -type d);
58 if [ -n "$include" ]; then
59 archincludedir="$archincludedir $include"
60 find $include $ignore -name "$2" -print;
61 fi
42} 62}
43 63
44# find sources in include/ 64# find sources in include/
@@ -63,14 +83,15 @@ find_sources()
63 83
64all_sources() 84all_sources()
65{ 85{
66 for arch in $ALLSOURCE_ARCHS 86 find_arch_include_sources ${SRCARCH} '*.[chS]'
67 do
68 find_sources $arch '*.[chS]'
69 done
70 if [ ! -z "$archinclude" ]; then 87 if [ ! -z "$archinclude" ]; then
71 find_arch_include_sources $archinclude '*.[chS]' 88 find_arch_include_sources $archinclude '*.[chS]'
72 fi 89 fi
73 find_include_sources '*.[chS]' 90 find_include_sources '*.[chS]'
91 for arch in $ALLSOURCE_ARCHS
92 do
93 find_sources $arch '*.[chS]'
94 done
74 find_other_sources '*.[chS]' 95 find_other_sources '*.[chS]'
75} 96}
76 97
@@ -89,13 +110,7 @@ all_defconfigs()
89 110
90docscope() 111docscope()
91{ 112{
92 # always use absolute paths for cscope, as recommended by cscope 113 (echo \-k; echo \-q; all_sources) > cscope.files
93 # upstream
94 case "$tree" in
95 /*) ;;
96 *) tree=$PWD/$tree ;;
97 esac
98 (cd /; echo \-k; echo \-q; all_sources) > cscope.files
99 cscope -b -f cscope.out 114 cscope -b -f cscope.out
100} 115}
101 116
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
index 678933721735..3ff8cc5f487a 100644
--- a/sound/aoa/soundbus/i2sbus/core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -437,9 +437,11 @@ static int i2sbus_shutdown(struct macio_dev* dev)
437} 437}
438 438
439static struct macio_driver i2sbus_drv = { 439static struct macio_driver i2sbus_drv = {
440 .name = "soundbus-i2s", 440 .driver = {
441 .owner = THIS_MODULE, 441 .name = "soundbus-i2s",
442 .match_table = i2sbus_match, 442 .owner = THIS_MODULE,
443 .of_match_table = i2sbus_match,
444 },
443 .probe = i2sbus_probe, 445 .probe = i2sbus_probe,
444 .remove = i2sbus_remove, 446 .remove = i2sbus_remove,
445#ifdef CONFIG_PM 447#ifdef CONFIG_PM
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index 428121a7e705..10c3a871a12d 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -657,7 +657,7 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
657 if (sr & AC97C_SR_CAEVT) { 657 if (sr & AC97C_SR_CAEVT) {
658 struct snd_pcm_runtime *runtime; 658 struct snd_pcm_runtime *runtime;
659 int offset, next_period, block_size; 659 int offset, next_period, block_size;
660 dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", 660 dev_dbg(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
661 casr & AC97C_CSR_OVRUN ? " OVRUN" : "", 661 casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
662 casr & AC97C_CSR_RXRDY ? " RXRDY" : "", 662 casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
663 casr & AC97C_CSR_UNRUN ? " UNRUN" : "", 663 casr & AC97C_CSR_UNRUN ? " UNRUN" : "",
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index f74c7372b3d1..1db586af4f9c 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -2578,6 +2578,9 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2578 if (err) 2578 if (err)
2579 return -err; 2579 return -err;
2580 2580
2581 memset(&prev_ctl, 0, sizeof(prev_ctl));
2582 prev_ctl.control_type = -1;
2583
2581 for (idx = 0; idx < 2000; idx++) { 2584 for (idx = 0; idx < 2000; idx++) {
2582 err = hpi_mixer_get_control_by_index( 2585 err = hpi_mixer_get_control_by_index(
2583 ss, asihpi->h_mixer, 2586 ss, asihpi->h_mixer,
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index dc79564fea30..1df25cf5ce38 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1913,11 +1913,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1913 if (WARN_ONCE(!azx_dev->period_bytes, 1913 if (WARN_ONCE(!azx_dev->period_bytes,
1914 "hda-intel: zero azx_dev->period_bytes")) 1914 "hda-intel: zero azx_dev->period_bytes"))
1915 return -1; /* this shouldn't happen! */ 1915 return -1; /* this shouldn't happen! */
1916 if (wallclk <= azx_dev->period_wallclk && 1916 if (wallclk < (azx_dev->period_wallclk * 5) / 4 &&
1917 pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) 1917 pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
1918 /* NG - it's below the first next period boundary */ 1918 /* NG - it's below the first next period boundary */
1919 return bdl_pos_adj[chip->dev_index] ? 0 : -1; 1919 return bdl_pos_adj[chip->dev_index] ? 0 : -1;
1920 azx_dev->start_wallclk = wallclk; 1920 azx_dev->start_wallclk += wallclk;
1921 return 1; /* OK, it's fine */ 1921 return 1; /* OK, it's fine */
1922} 1922}
1923 1923
@@ -2288,6 +2288,8 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2288 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), 2288 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2289 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2289 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2290 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2290 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2291 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
2292 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
2291 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), 2293 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
2292 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), 2294 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2293 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), 2295 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
@@ -2296,6 +2298,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2296 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2298 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2297 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), 2299 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
2298 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), 2300 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
2301 SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
2299 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), 2302 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
2300 SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), 2303 SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
2301 {} 2304 {}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 17d4548cc353..f1ce7d7f5aa3 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2619,16 +2619,18 @@ static int alc_build_controls(struct hda_codec *codec)
2619 } 2619 }
2620 2620
2621 /* assign Capture Source enums to NID */ 2621 /* assign Capture Source enums to NID */
2622 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 2622 if (spec->capsrc_nids || spec->adc_nids) {
2623 if (!kctl) 2623 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2624 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 2624 if (!kctl)
2625 for (i = 0; kctl && i < kctl->count; i++) { 2625 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2626 hda_nid_t *nids = spec->capsrc_nids; 2626 for (i = 0; kctl && i < kctl->count; i++) {
2627 if (!nids) 2627 hda_nid_t *nids = spec->capsrc_nids;
2628 nids = spec->adc_nids; 2628 if (!nids)
2629 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 2629 nids = spec->adc_nids;
2630 if (err < 0) 2630 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2631 return err; 2631 if (err < 0)
2632 return err;
2633 }
2632 } 2634 }
2633 if (spec->cap_mixer) { 2635 if (spec->cap_mixer) {
2634 const char *kname = kctl ? kctl->id.name : NULL; 2636 const char *kname = kctl ? kctl->id.name : NULL;
@@ -6948,7 +6950,7 @@ static struct hda_input_mux mb5_capture_source = {
6948 .num_items = 3, 6950 .num_items = 3,
6949 .items = { 6951 .items = {
6950 { "Mic", 0x1 }, 6952 { "Mic", 0x1 },
6951 { "Line", 0x2 }, 6953 { "Line", 0x7 },
6952 { "CD", 0x4 }, 6954 { "CD", 0x4 },
6953 }, 6955 },
6954}; 6956};
@@ -7469,8 +7471,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7469 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7471 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7470 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7472 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7471 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7473 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7472 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7474 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7473 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7475 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7474 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7475 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7477 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7476 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7478 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
@@ -7853,10 +7855,9 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
7853 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7855 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7854 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7855 7857
7856 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7858 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
7857 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7859 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
7858 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7860 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
7859 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7860 { } 7861 { }
7861}; 7862};
7862 7863
@@ -9476,6 +9477,10 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9476 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), 9477 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9477 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), 9478 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9478 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), 9479 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9480 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9481 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9482 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9483 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9479 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 9484 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9480 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 9485 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9481 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 9486 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index 4c7b051f9d17..1bc56b2b94e2 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -69,7 +69,6 @@ struct snd_at73c213 {
69 int irq; 69 int irq;
70 int period; 70 int period;
71 unsigned long bitrate; 71 unsigned long bitrate;
72 struct clk *bitclk;
73 struct ssc_device *ssc; 72 struct ssc_device *ssc;
74 struct spi_device *spi; 73 struct spi_device *spi;
75 u8 spi_wbuffer[2]; 74 u8 spi_wbuffer[2];
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index e7ac7f493a8f..1e362bf8834f 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -11,7 +11,8 @@ snd-usb-audio-objs := card.o \
11 endpoint.o \ 11 endpoint.o \
12 urb.o \ 12 urb.o \
13 pcm.o \ 13 pcm.o \
14 helper.o 14 helper.o \
15 clock.o
15 16
16snd-usbmidi-lib-objs := midi.o 17snd-usbmidi-lib-objs := midi.o
17 18
diff --git a/sound/usb/card.c b/sound/usb/card.c
index da1346bd4856..7a8ac1d81be7 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -236,7 +236,6 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
236 } 236 }
237 237
238 case UAC_VERSION_2: { 238 case UAC_VERSION_2: {
239 struct uac_clock_source_descriptor *cs;
240 struct usb_interface_assoc_descriptor *assoc = 239 struct usb_interface_assoc_descriptor *assoc =
241 usb_ifnum_to_if(dev, ctrlif)->intf_assoc; 240 usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
242 241
@@ -245,21 +244,6 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
245 return -EINVAL; 244 return -EINVAL;
246 } 245 }
247 246
248 /* FIXME: for now, we expect there is at least one clock source
249 * descriptor and we always take the first one.
250 * We should properly support devices with multiple clock sources,
251 * clock selectors and sample rate conversion units. */
252
253 cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen,
254 NULL, UAC2_CLOCK_SOURCE);
255
256 if (!cs) {
257 snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n");
258 return -EINVAL;
259 }
260
261 chip->clock_id = cs->bClockID;
262
263 for (i = 0; i < assoc->bInterfaceCount; i++) { 247 for (i = 0; i < assoc->bInterfaceCount; i++) {
264 int intf = assoc->bFirstInterface + i; 248 int intf = assoc->bFirstInterface + i;
265 249
@@ -481,6 +465,8 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
481 goto __error; 465 goto __error;
482 } 466 }
483 467
468 chip->ctrl_intf = alts;
469
484 if (err > 0) { 470 if (err > 0) {
485 /* create normal USB audio interfaces */ 471 /* create normal USB audio interfaces */
486 if (snd_usb_create_streams(chip, ifnum) < 0 || 472 if (snd_usb_create_streams(chip, ifnum) < 0 ||
diff --git a/sound/usb/card.h b/sound/usb/card.h
index ed92420c1095..1febf2f23754 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -25,6 +25,7 @@ struct audioformat {
25 unsigned int rate_min, rate_max; /* min/max rates */ 25 unsigned int rate_min, rate_max; /* min/max rates */
26 unsigned int nr_rates; /* number of rate table entries */ 26 unsigned int nr_rates; /* number of rate table entries */
27 unsigned int *rate_table; /* rate table */ 27 unsigned int *rate_table; /* rate table */
28 unsigned char clock; /* associated clock */
28}; 29};
29 30
30struct snd_usb_substream; 31struct snd_usb_substream;
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
new file mode 100644
index 000000000000..b5855114667e
--- /dev/null
+++ b/sound/usb/clock.c
@@ -0,0 +1,315 @@
1/*
2 * Clock domain and sample rate management functions
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
20#include <linux/bitops.h>
21#include <linux/init.h>
22#include <linux/list.h>
23#include <linux/slab.h>
24#include <linux/string.h>
25#include <linux/usb.h>
26#include <linux/moduleparam.h>
27#include <linux/mutex.h>
28#include <linux/usb/audio.h>
29#include <linux/usb/audio-v2.h>
30
31#include <sound/core.h>
32#include <sound/info.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/initval.h>
36
37#include "usbaudio.h"
38#include "card.h"
39#include "midi.h"
40#include "mixer.h"
41#include "proc.h"
42#include "quirks.h"
43#include "endpoint.h"
44#include "helper.h"
45#include "debug.h"
46#include "pcm.h"
47#include "urb.h"
48#include "format.h"
49
50static struct uac_clock_source_descriptor *
51 snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface,
52 int clock_id)
53{
54 struct uac_clock_source_descriptor *cs = NULL;
55
56 while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
57 ctrl_iface->extralen,
58 cs, UAC2_CLOCK_SOURCE))) {
59 if (cs->bClockID == clock_id)
60 return cs;
61 }
62
63 return NULL;
64}
65
66static struct uac_clock_selector_descriptor *
67 snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface,
68 int clock_id)
69{
70 struct uac_clock_selector_descriptor *cs = NULL;
71
72 while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
73 ctrl_iface->extralen,
74 cs, UAC2_CLOCK_SELECTOR))) {
75 if (cs->bClockID == clock_id)
76 return cs;
77 }
78
79 return NULL;
80}
81
82static struct uac_clock_multiplier_descriptor *
83 snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface,
84 int clock_id)
85{
86 struct uac_clock_multiplier_descriptor *cs = NULL;
87
88 while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
89 ctrl_iface->extralen,
90 cs, UAC2_CLOCK_MULTIPLIER))) {
91 if (cs->bClockID == clock_id)
92 return cs;
93 }
94
95 return NULL;
96}
97
98static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
99{
100 unsigned char buf;
101 int ret;
102
103 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),
104 UAC2_CS_CUR,
105 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
106 UAC2_CX_CLOCK_SELECTOR << 8,
107 snd_usb_ctrl_intf(chip) | (selector_id << 8),
108 &buf, sizeof(buf), 1000);
109
110 if (ret < 0)
111 return ret;
112
113 return buf;
114}
115
116static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
117{
118 int err;
119 unsigned char data;
120 struct usb_device *dev = chip->dev;
121
122 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
123 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
124 UAC2_CS_CONTROL_CLOCK_VALID << 8,
125 snd_usb_ctrl_intf(chip) | (source_id << 8),
126 &data, sizeof(data), 1000);
127
128 if (err < 0) {
129 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
130 __func__, source_id);
131 return err;
132 }
133
134 return !!data;
135}
136
137/* Try to find the clock source ID of a given clock entity */
138
139static int __uac_clock_find_source(struct snd_usb_audio *chip,
140 struct usb_host_interface *host_iface,
141 int entity_id, unsigned long *visited)
142{
143 struct uac_clock_source_descriptor *source;
144 struct uac_clock_selector_descriptor *selector;
145 struct uac_clock_multiplier_descriptor *multiplier;
146
147 entity_id &= 0xff;
148
149 if (test_and_set_bit(entity_id, visited)) {
150 snd_printk(KERN_WARNING
151 "%s(): recursive clock topology detected, id %d.\n",
152 __func__, entity_id);
153 return -EINVAL;
154 }
155
156 /* first, see if the ID we're looking for is a clock source already */
157 source = snd_usb_find_clock_source(host_iface, entity_id);
158 if (source)
159 return source->bClockID;
160
161 selector = snd_usb_find_clock_selector(host_iface, entity_id);
162 if (selector) {
163 int ret;
164
165 /* the entity ID we are looking for is a selector.
166 * find out what it currently selects */
167 ret = uac_clock_selector_get_val(chip, selector->bClockID);
168 if (ret < 0)
169 return ret;
170
171 if (ret > selector->bNrInPins || ret < 1) {
172 printk(KERN_ERR
173 "%s(): selector reported illegal value, id %d, ret %d\n",
174 __func__, selector->bClockID, ret);
175
176 return -EINVAL;
177 }
178
179 return __uac_clock_find_source(chip, host_iface,
180 selector->baCSourceID[ret-1],
181 visited);
182 }
183
184 /* FIXME: multipliers only act as pass-thru element for now */
185 multiplier = snd_usb_find_clock_multiplier(host_iface, entity_id);
186 if (multiplier)
187 return __uac_clock_find_source(chip, host_iface,
188 multiplier->bCSourceID, visited);
189
190 return -EINVAL;
191}
192
193int snd_usb_clock_find_source(struct snd_usb_audio *chip,
194 struct usb_host_interface *host_iface,
195 int entity_id)
196{
197 DECLARE_BITMAP(visited, 256);
198 memset(visited, 0, sizeof(visited));
199 return __uac_clock_find_source(chip, host_iface, entity_id, visited);
200}
201
202static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
203 struct usb_host_interface *alts,
204 struct audioformat *fmt, int rate)
205{
206 struct usb_device *dev = chip->dev;
207 unsigned int ep;
208 unsigned char data[3];
209 int err, crate;
210
211 ep = get_endpoint(alts, 0)->bEndpointAddress;
212
213 /* if endpoint doesn't have sampling rate control, bail out */
214 if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) {
215 snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n",
216 dev->devnum, iface, fmt->altsetting);
217 return 0;
218 }
219
220 data[0] = rate;
221 data[1] = rate >> 8;
222 data[2] = rate >> 16;
223 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
224 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
225 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
226 data, sizeof(data), 1000)) < 0) {
227 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
228 dev->devnum, iface, fmt->altsetting, rate, ep);
229 return err;
230 }
231
232 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
233 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
234 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
235 data, sizeof(data), 1000)) < 0) {
236 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
237 dev->devnum, iface, fmt->altsetting, ep);
238 return 0; /* some devices don't support reading */
239 }
240
241 crate = data[0] | (data[1] << 8) | (data[2] << 16);
242 if (crate != rate) {
243 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
244 // runtime->rate = crate;
245 }
246
247 return 0;
248}
249
250static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
251 struct usb_host_interface *alts,
252 struct audioformat *fmt, int rate)
253{
254 struct usb_device *dev = chip->dev;
255 unsigned char data[4];
256 int err, crate;
257 int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fmt->clock);
258
259 if (clock < 0)
260 return clock;
261
262 if (!uac_clock_source_is_valid(chip, clock)) {
263 snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n",
264 dev->devnum, iface, fmt->altsetting, clock);
265 return -ENXIO;
266 }
267
268 data[0] = rate;
269 data[1] = rate >> 8;
270 data[2] = rate >> 16;
271 data[3] = rate >> 24;
272 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
273 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
274 UAC2_CS_CONTROL_SAM_FREQ << 8,
275 snd_usb_ctrl_intf(chip) | (clock << 8),
276 data, sizeof(data), 1000)) < 0) {
277 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
278 dev->devnum, iface, fmt->altsetting, rate);
279 return err;
280 }
281
282 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
283 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
284 UAC2_CS_CONTROL_SAM_FREQ << 8,
285 snd_usb_ctrl_intf(chip) | (clock << 8),
286 data, sizeof(data), 1000)) < 0) {
287 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
288 dev->devnum, iface, fmt->altsetting);
289 return err;
290 }
291
292 crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
293 if (crate != rate)
294 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
295
296 return 0;
297}
298
299int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
300 struct usb_host_interface *alts,
301 struct audioformat *fmt, int rate)
302{
303 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
304
305 switch (altsd->bInterfaceProtocol) {
306 case UAC_VERSION_1:
307 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
308
309 case UAC_VERSION_2:
310 return set_sample_rate_v2(chip, iface, alts, fmt, rate);
311 }
312
313 return -EINVAL;
314}
315
diff --git a/sound/usb/clock.h b/sound/usb/clock.h
new file mode 100644
index 000000000000..beb253684e2d
--- /dev/null
+++ b/sound/usb/clock.h
@@ -0,0 +1,12 @@
1#ifndef __USBAUDIO_CLOCK_H
2#define __USBAUDIO_CLOCK_H
3
4int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
5 struct usb_host_interface *alts,
6 struct audioformat *fmt, int rate);
7
8int snd_usb_clock_find_source(struct snd_usb_audio *chip,
9 struct usb_host_interface *host_iface,
10 int entity_id);
11
12#endif /* __USBAUDIO_CLOCK_H */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 28ee1ce3971a..9593b91452b9 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -190,6 +190,38 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
190 return attributes; 190 return attributes;
191} 191}
192 192
193static struct uac2_input_terminal_descriptor *
194 snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
195 int terminal_id)
196{
197 struct uac2_input_terminal_descriptor *term = NULL;
198
199 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
200 ctrl_iface->extralen,
201 term, UAC_INPUT_TERMINAL))) {
202 if (term->bTerminalID == terminal_id)
203 return term;
204 }
205
206 return NULL;
207}
208
209static struct uac2_output_terminal_descriptor *
210 snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
211 int terminal_id)
212{
213 struct uac2_output_terminal_descriptor *term = NULL;
214
215 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
216 ctrl_iface->extralen,
217 term, UAC_OUTPUT_TERMINAL))) {
218 if (term->bTerminalID == terminal_id)
219 return term;
220 }
221
222 return NULL;
223}
224
193int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) 225int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
194{ 226{
195 struct usb_device *dev; 227 struct usb_device *dev;
@@ -199,7 +231,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
199 int i, altno, err, stream; 231 int i, altno, err, stream;
200 int format = 0, num_channels = 0; 232 int format = 0, num_channels = 0;
201 struct audioformat *fp = NULL; 233 struct audioformat *fp = NULL;
202 int num, protocol; 234 int num, protocol, clock = 0;
203 struct uac_format_type_i_continuous_descriptor *fmt; 235 struct uac_format_type_i_continuous_descriptor *fmt;
204 236
205 dev = chip->dev; 237 dev = chip->dev;
@@ -263,6 +295,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
263 } 295 }
264 296
265 case UAC_VERSION_2: { 297 case UAC_VERSION_2: {
298 struct uac2_input_terminal_descriptor *input_term;
299 struct uac2_output_terminal_descriptor *output_term;
266 struct uac_as_header_descriptor_v2 *as = 300 struct uac_as_header_descriptor_v2 *as =
267 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); 301 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
268 302
@@ -281,7 +315,25 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
281 num_channels = as->bNrChannels; 315 num_channels = as->bNrChannels;
282 format = le32_to_cpu(as->bmFormats); 316 format = le32_to_cpu(as->bmFormats);
283 317
284 break; 318 /* lookup the terminal associated to this interface
319 * to extract the clock */
320 input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
321 as->bTerminalLink);
322 if (input_term) {
323 clock = input_term->bCSourceID;
324 break;
325 }
326
327 output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
328 as->bTerminalLink);
329 if (output_term) {
330 clock = output_term->bCSourceID;
331 break;
332 }
333
334 snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n",
335 dev->devnum, iface_no, altno, as->bTerminalLink);
336 continue;
285 } 337 }
286 338
287 default: 339 default:
@@ -338,6 +390,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
338 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) 390 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
339 * (fp->maxpacksize & 0x7ff); 391 * (fp->maxpacksize & 0x7ff);
340 fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); 392 fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
393 fp->clock = clock;
341 394
342 /* some quirks for attributes here */ 395 /* some quirks for attributes here */
343 396
diff --git a/sound/usb/format.c b/sound/usb/format.c
index fe29d61de19b..30364aba79cc 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -29,6 +29,7 @@
29#include "quirks.h" 29#include "quirks.h"
30#include "helper.h" 30#include "helper.h"
31#include "debug.h" 31#include "debug.h"
32#include "clock.h"
32 33
33/* 34/*
34 * parse the audio format type I descriptor 35 * parse the audio format type I descriptor
@@ -205,6 +206,60 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
205} 206}
206 207
207/* 208/*
209 * Helper function to walk the array of sample rate triplets reported by
210 * the device. The problem is that we need to parse whole array first to
211 * get to know how many sample rates we have to expect.
212 * Then fp->rate_table can be allocated and filled.
213 */
214static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
215 const unsigned char *data)
216{
217 int i, nr_rates = 0;
218
219 fp->rates = fp->rate_min = fp->rate_max = 0;
220
221 for (i = 0; i < nr_triplets; i++) {
222 int min = combine_quad(&data[2 + 12 * i]);
223 int max = combine_quad(&data[6 + 12 * i]);
224 int res = combine_quad(&data[10 + 12 * i]);
225 int rate;
226
227 if ((max < 0) || (min < 0) || (res < 0) || (max < min))
228 continue;
229
230 /*
231 * for ranges with res == 1, we announce a continuous sample
232 * rate range, and this function should return 0 for no further
233 * parsing.
234 */
235 if (res == 1) {
236 fp->rate_min = min;
237 fp->rate_max = max;
238 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
239 return 0;
240 }
241
242 for (rate = min; rate <= max; rate += res) {
243 if (fp->rate_table)
244 fp->rate_table[nr_rates] = rate;
245 if (!fp->rate_min || rate < fp->rate_min)
246 fp->rate_min = rate;
247 if (!fp->rate_max || rate > fp->rate_max)
248 fp->rate_max = rate;
249 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
250
251 nr_rates++;
252
253 /* avoid endless loop */
254 if (res == 0)
255 break;
256 }
257 }
258
259 return nr_rates;
260}
261
262/*
208 * parse the format descriptor and stores the possible sample rates 263 * parse the format descriptor and stores the possible sample rates
209 * on the audioformat table (audio class v2). 264 * on the audioformat table (audio class v2).
210 */ 265 */
@@ -214,21 +269,30 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
214{ 269{
215 struct usb_device *dev = chip->dev; 270 struct usb_device *dev = chip->dev;
216 unsigned char tmp[2], *data; 271 unsigned char tmp[2], *data;
217 int i, nr_rates, data_size, ret = 0; 272 int nr_triplets, data_size, ret = 0;
273 int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock);
274
275 if (clock < 0) {
276 snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",
277 __func__, clock);
278 goto err;
279 }
218 280
219 /* get the number of sample rates first by only fetching 2 bytes */ 281 /* get the number of sample rates first by only fetching 2 bytes */
220 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, 282 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
221 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 283 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
222 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8, 284 UAC2_CS_CONTROL_SAM_FREQ << 8,
285 snd_usb_ctrl_intf(chip) | (clock << 8),
223 tmp, sizeof(tmp), 1000); 286 tmp, sizeof(tmp), 1000);
224 287
225 if (ret < 0) { 288 if (ret < 0) {
226 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n"); 289 snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n",
290 __func__, clock);
227 goto err; 291 goto err;
228 } 292 }
229 293
230 nr_rates = (tmp[1] << 8) | tmp[0]; 294 nr_triplets = (tmp[1] << 8) | tmp[0];
231 data_size = 2 + 12 * nr_rates; 295 data_size = 2 + 12 * nr_triplets;
232 data = kzalloc(data_size, GFP_KERNEL); 296 data = kzalloc(data_size, GFP_KERNEL);
233 if (!data) { 297 if (!data) {
234 ret = -ENOMEM; 298 ret = -ENOMEM;
@@ -237,36 +301,40 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
237 301
238 /* now get the full information */ 302 /* now get the full information */
239 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, 303 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
240 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 304 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
241 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8, 305 UAC2_CS_CONTROL_SAM_FREQ << 8,
242 data, data_size, 1000); 306 snd_usb_ctrl_intf(chip) | (clock << 8),
307 data, data_size, 1000);
243 308
244 if (ret < 0) { 309 if (ret < 0) {
245 snd_printk(KERN_ERR "unable to retrieve sample rate range\n"); 310 snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n",
311 __func__, clock);
246 ret = -EINVAL; 312 ret = -EINVAL;
247 goto err_free; 313 goto err_free;
248 } 314 }
249 315
250 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); 316 /* Call the triplet parser, and make sure fp->rate_table is NULL.
317 * We just use the return value to know how many sample rates we
318 * will have to deal with. */
319 kfree(fp->rate_table);
320 fp->rate_table = NULL;
321 fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data);
322
323 if (fp->nr_rates == 0) {
324 /* SNDRV_PCM_RATE_CONTINUOUS */
325 ret = 0;
326 goto err_free;
327 }
328
329 fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
251 if (!fp->rate_table) { 330 if (!fp->rate_table) {
252 ret = -ENOMEM; 331 ret = -ENOMEM;
253 goto err_free; 332 goto err_free;
254 } 333 }
255 334
256 fp->nr_rates = 0; 335 /* Call the triplet parser again, but this time, fp->rate_table is
257 fp->rate_min = fp->rate_max = 0; 336 * allocated, so the rates will be stored */
258 337 parse_uac2_sample_rate_range(fp, nr_triplets, data);
259 for (i = 0; i < nr_rates; i++) {
260 int rate = combine_quad(&data[2 + 12 * i]);
261
262 fp->rate_table[fp->nr_rates] = rate;
263 if (!fp->rate_min || rate < fp->rate_min)
264 fp->rate_min = rate;
265 if (!fp->rate_max || rate > fp->rate_max)
266 fp->rate_max = rate;
267 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
268 fp->nr_rates++;
269 }
270 338
271err_free: 339err_free:
272 kfree(data); 340 kfree(data);
diff --git a/sound/usb/helper.h b/sound/usb/helper.h
index a6b0e51b3a9a..09bd943c43bf 100644
--- a/sound/usb/helper.h
+++ b/sound/usb/helper.h
@@ -28,5 +28,9 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
28#define snd_usb_get_speed(dev) ((dev)->speed) 28#define snd_usb_get_speed(dev) ((dev)->speed)
29#endif 29#endif
30 30
31static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip)
32{
33 return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber;
34}
31 35
32#endif /* __USBAUDIO_HELPER_H */ 36#endif /* __USBAUDIO_HELPER_H */
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 03ce971e0027..6939d0f517d9 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -78,39 +78,6 @@ enum {
78 USB_MIXER_U16, 78 USB_MIXER_U16,
79}; 79};
80 80
81enum {
82 USB_PROC_UPDOWN = 1,
83 USB_PROC_UPDOWN_SWITCH = 1,
84 USB_PROC_UPDOWN_MODE_SEL = 2,
85
86 USB_PROC_PROLOGIC = 2,
87 USB_PROC_PROLOGIC_SWITCH = 1,
88 USB_PROC_PROLOGIC_MODE_SEL = 2,
89
90 USB_PROC_3DENH = 3,
91 USB_PROC_3DENH_SWITCH = 1,
92 USB_PROC_3DENH_SPACE = 2,
93
94 USB_PROC_REVERB = 4,
95 USB_PROC_REVERB_SWITCH = 1,
96 USB_PROC_REVERB_LEVEL = 2,
97 USB_PROC_REVERB_TIME = 3,
98 USB_PROC_REVERB_DELAY = 4,
99
100 USB_PROC_CHORUS = 5,
101 USB_PROC_CHORUS_SWITCH = 1,
102 USB_PROC_CHORUS_LEVEL = 2,
103 USB_PROC_CHORUS_RATE = 3,
104 USB_PROC_CHORUS_DEPTH = 4,
105
106 USB_PROC_DCR = 6,
107 USB_PROC_DCR_SWITCH = 1,
108 USB_PROC_DCR_RATIO = 2,
109 USB_PROC_DCR_MAX_AMP = 3,
110 USB_PROC_DCR_THRESHOLD = 4,
111 USB_PROC_DCR_ATTACK = 5,
112 USB_PROC_DCR_RELEASE = 6,
113};
114 81
115/*E-mu 0202(0404) eXtension Unit(XU) control*/ 82/*E-mu 0202(0404) eXtension Unit(XU) control*/
116enum { 83enum {
@@ -198,22 +165,24 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,
198 165
199/* 166/*
200 * find an audio control unit with the given unit id 167 * find an audio control unit with the given unit id
201 * this doesn't return any clock related units, so they need to be handled elsewhere
202 */ 168 */
203static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit) 169static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
204{ 170{
205 unsigned char *p; 171 /* we just parse the header */
172 struct uac_feature_unit_descriptor *hdr = NULL;
206 173
207 p = NULL; 174 while ((hdr = snd_usb_find_desc(state->buffer, state->buflen, hdr,
208 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, 175 USB_DT_CS_INTERFACE)) != NULL) {
209 USB_DT_CS_INTERFACE)) != NULL) { 176 if (hdr->bLength >= 4 &&
210 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC2_EXTENSION_UNIT_V2 && p[3] == unit) 177 hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL &&
211 return p; 178 hdr->bDescriptorSubtype <= UAC2_SAMPLE_RATE_CONVERTER &&
179 hdr->bUnitID == unit)
180 return hdr;
212 } 181 }
182
213 return NULL; 183 return NULL;
214} 184}
215 185
216
217/* 186/*
218 * copy a string with the given id 187 * copy a string with the given id
219 */ 188 */
@@ -328,27 +297,36 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
328 297
329static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) 298static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
330{ 299{
331 unsigned char buf[14]; /* enough space for one range of 4 bytes */ 300 unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
332 unsigned char *val; 301 unsigned char *val;
333 int ret; 302 int ret, size;
334 __u8 bRequest; 303 __u8 bRequest;
335 304
336 bRequest = (request == UAC_GET_CUR) ? 305 if (request == UAC_GET_CUR) {
337 UAC2_CS_CUR : UAC2_CS_RANGE; 306 bRequest = UAC2_CS_CUR;
307 size = sizeof(__u16);
308 } else {
309 bRequest = UAC2_CS_RANGE;
310 size = sizeof(buf);
311 }
312
313 memset(buf, 0, sizeof(buf));
338 314
339 ret = snd_usb_ctl_msg(cval->mixer->chip->dev, 315 ret = snd_usb_ctl_msg(cval->mixer->chip->dev,
340 usb_rcvctrlpipe(cval->mixer->chip->dev, 0), 316 usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
341 bRequest, 317 bRequest,
342 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 318 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
343 validx, cval->mixer->ctrlif | (cval->id << 8), 319 validx, cval->mixer->ctrlif | (cval->id << 8),
344 buf, sizeof(buf), 1000); 320 buf, size, 1000);
345 321
346 if (ret < 0) { 322 if (ret < 0) {
347 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 323 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
348 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type); 324 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
349 return ret; 325 return ret;
350 } 326 }
351 327
328 /* FIXME: how should we handle multiple triplets here? */
329
352 switch (request) { 330 switch (request) {
353 case UAC_GET_CUR: 331 case UAC_GET_CUR:
354 val = buf; 332 val = buf;
@@ -462,6 +440,16 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
462 int index, int value) 440 int index, int value)
463{ 441{
464 int err; 442 int err;
443 unsigned int read_only = (channel == 0) ?
444 cval->master_readonly :
445 cval->ch_readonly & (1 << (channel - 1));
446
447 if (read_only) {
448 snd_printdd(KERN_INFO "%s(): channel %d of control %d is read_only\n",
449 __func__, channel, cval->control);
450 return 0;
451 }
452
465 err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel, 453 err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
466 value); 454 value);
467 if (err < 0) 455 if (err < 0)
@@ -631,6 +619,7 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
631 */ 619 */
632static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) 620static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
633{ 621{
622 int err;
634 void *p1; 623 void *p1;
635 624
636 memset(term, 0, sizeof(*term)); 625 memset(term, 0, sizeof(*term));
@@ -651,6 +640,11 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
651 term->channels = d->bNrChannels; 640 term->channels = d->bNrChannels;
652 term->chconfig = le32_to_cpu(d->bmChannelConfig); 641 term->chconfig = le32_to_cpu(d->bmChannelConfig);
653 term->name = d->iTerminal; 642 term->name = d->iTerminal;
643
644 /* call recursively to get the clock selectors */
645 err = check_input_term(state, d->bCSourceID, term);
646 if (err < 0)
647 return err;
654 } 648 }
655 return 0; 649 return 0;
656 case UAC_FEATURE_UNIT: { 650 case UAC_FEATURE_UNIT: {
@@ -667,7 +661,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
667 term->name = uac_mixer_unit_iMixer(d); 661 term->name = uac_mixer_unit_iMixer(d);
668 return 0; 662 return 0;
669 } 663 }
670 case UAC_SELECTOR_UNIT: { 664 case UAC_SELECTOR_UNIT:
665 case UAC2_CLOCK_SELECTOR: {
671 struct uac_selector_unit_descriptor *d = p1; 666 struct uac_selector_unit_descriptor *d = p1;
672 /* call recursively to retrieve the channel info */ 667 /* call recursively to retrieve the channel info */
673 if (check_input_term(state, d->baSourceID[0], term) < 0) 668 if (check_input_term(state, d->baSourceID[0], term) < 0)
@@ -690,6 +685,13 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
690 term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol); 685 term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol);
691 return 0; 686 return 0;
692 } 687 }
688 case UAC2_CLOCK_SOURCE: {
689 struct uac_clock_source_descriptor *d = p1;
690 term->type = d->bDescriptorSubtype << 16; /* virtual type */
691 term->id = id;
692 term->name = d->iClockSource;
693 return 0;
694 }
693 default: 695 default:
694 return -ENODEV; 696 return -ENODEV;
695 } 697 }
@@ -709,16 +711,20 @@ struct usb_feature_control_info {
709}; 711};
710 712
711static struct usb_feature_control_info audio_feature_info[] = { 713static struct usb_feature_control_info audio_feature_info[] = {
712 { "Mute", USB_MIXER_INV_BOOLEAN }, 714 { "Mute", USB_MIXER_INV_BOOLEAN },
713 { "Volume", USB_MIXER_S16 }, 715 { "Volume", USB_MIXER_S16 },
714 { "Tone Control - Bass", USB_MIXER_S8 }, 716 { "Tone Control - Bass", USB_MIXER_S8 },
715 { "Tone Control - Mid", USB_MIXER_S8 }, 717 { "Tone Control - Mid", USB_MIXER_S8 },
716 { "Tone Control - Treble", USB_MIXER_S8 }, 718 { "Tone Control - Treble", USB_MIXER_S8 },
717 { "Graphic Equalizer", USB_MIXER_S8 }, /* FIXME: not implemeted yet */ 719 { "Graphic Equalizer", USB_MIXER_S8 }, /* FIXME: not implemeted yet */
718 { "Auto Gain Control", USB_MIXER_BOOLEAN }, 720 { "Auto Gain Control", USB_MIXER_BOOLEAN },
719 { "Delay Control", USB_MIXER_U16 }, 721 { "Delay Control", USB_MIXER_U16 },
720 { "Bass Boost", USB_MIXER_BOOLEAN }, 722 { "Bass Boost", USB_MIXER_BOOLEAN },
721 { "Loudness", USB_MIXER_BOOLEAN }, 723 { "Loudness", USB_MIXER_BOOLEAN },
724 /* UAC2 specific */
725 { "Input Gain Control", USB_MIXER_U16 },
726 { "Input Gain Pad Control", USB_MIXER_BOOLEAN },
727 { "Phase Inverter Control", USB_MIXER_BOOLEAN },
722}; 728};
723 729
724 730
@@ -958,7 +964,7 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
958static void build_feature_ctl(struct mixer_build *state, void *raw_desc, 964static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
959 unsigned int ctl_mask, int control, 965 unsigned int ctl_mask, int control,
960 struct usb_audio_term *iterm, int unitid, 966 struct usb_audio_term *iterm, int unitid,
961 int read_only) 967 int readonly_mask)
962{ 968{
963 struct uac_feature_unit_descriptor *desc = raw_desc; 969 struct uac_feature_unit_descriptor *desc = raw_desc;
964 unsigned int len = 0; 970 unsigned int len = 0;
@@ -970,7 +976,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
970 976
971 control++; /* change from zero-based to 1-based value */ 977 control++; /* change from zero-based to 1-based value */
972 978
973 if (control == UAC_GRAPHIC_EQUALIZER_CONTROL) { 979 if (control == UAC_FU_GRAPHIC_EQUALIZER) {
974 /* FIXME: not supported yet */ 980 /* FIXME: not supported yet */
975 return; 981 return;
976 } 982 }
@@ -989,20 +995,25 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
989 cval->control = control; 995 cval->control = control;
990 cval->cmask = ctl_mask; 996 cval->cmask = ctl_mask;
991 cval->val_type = audio_feature_info[control-1].type; 997 cval->val_type = audio_feature_info[control-1].type;
992 if (ctl_mask == 0) 998 if (ctl_mask == 0) {
993 cval->channels = 1; /* master channel */ 999 cval->channels = 1; /* master channel */
994 else { 1000 cval->master_readonly = readonly_mask;
1001 } else {
995 int i, c = 0; 1002 int i, c = 0;
996 for (i = 0; i < 16; i++) 1003 for (i = 0; i < 16; i++)
997 if (ctl_mask & (1 << i)) 1004 if (ctl_mask & (1 << i))
998 c++; 1005 c++;
999 cval->channels = c; 1006 cval->channels = c;
1007 cval->ch_readonly = readonly_mask;
1000 } 1008 }
1001 1009
1002 /* get min/max values */ 1010 /* get min/max values */
1003 get_min_max(cval, 0); 1011 get_min_max(cval, 0);
1004 1012
1005 if (read_only) 1013 /* if all channels in the mask are marked read-only, make the control
1014 * read-only. set_cur_mix_value() will check the mask again and won't
1015 * issue write commands to read-only channels. */
1016 if (cval->channels == readonly_mask)
1006 kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval); 1017 kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
1007 else 1018 else
1008 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); 1019 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
@@ -1021,8 +1032,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1021 kctl->id.name, sizeof(kctl->id.name)); 1032 kctl->id.name, sizeof(kctl->id.name));
1022 1033
1023 switch (control) { 1034 switch (control) {
1024 case UAC_MUTE_CONTROL: 1035 case UAC_FU_MUTE:
1025 case UAC_VOLUME_CONTROL: 1036 case UAC_FU_VOLUME:
1026 /* determine the control name. the rule is: 1037 /* determine the control name. the rule is:
1027 * - if a name id is given in descriptor, use it. 1038 * - if a name id is given in descriptor, use it.
1028 * - if the connected input can be determined, then use the name 1039 * - if the connected input can be determined, then use the name
@@ -1049,9 +1060,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1049 len = append_ctl_name(kctl, " Playback"); 1060 len = append_ctl_name(kctl, " Playback");
1050 } 1061 }
1051 } 1062 }
1052 append_ctl_name(kctl, control == UAC_MUTE_CONTROL ? 1063 append_ctl_name(kctl, control == UAC_FU_MUTE ?
1053 " Switch" : " Volume"); 1064 " Switch" : " Volume");
1054 if (control == UAC_VOLUME_CONTROL) { 1065 if (control == UAC_FU_VOLUME) {
1055 kctl->tlv.c = mixer_vol_tlv; 1066 kctl->tlv.c = mixer_vol_tlv;
1056 kctl->vd[0].access |= 1067 kctl->vd[0].access |=
1057 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 1068 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
@@ -1150,7 +1161,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1150 snd_printk(KERN_INFO 1161 snd_printk(KERN_INFO
1151 "usbmixer: master volume quirk for PCM2702 chip\n"); 1162 "usbmixer: master volume quirk for PCM2702 chip\n");
1152 /* disable non-functional volume control */ 1163 /* disable non-functional volume control */
1153 master_bits &= ~UAC_FU_VOLUME; 1164 master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);
1154 break; 1165 break;
1155 } 1166 }
1156 if (channels > 0) 1167 if (channels > 0)
@@ -1188,19 +1199,22 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1188 1199
1189 for (j = 0; j < channels; j++) { 1200 for (j = 0; j < channels; j++) {
1190 unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize); 1201 unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
1191 if (mask & (1 << (i * 2))) { 1202 if (uac2_control_is_readable(mask, i)) {
1192 ch_bits |= (1 << j); 1203 ch_bits |= (1 << j);
1193 if (~mask & (1 << ((i * 2) + 1))) 1204 if (!uac2_control_is_writeable(mask, i))
1194 ch_read_only |= (1 << j); 1205 ch_read_only |= (1 << j);
1195 } 1206 }
1196 } 1207 }
1197 1208
1198 /* FIXME: the whole unit is read-only if any of the channels is marked read-only */ 1209 /* NOTE: build_feature_ctl() will mark the control read-only if all channels
1210 * are marked read-only in the descriptors. Otherwise, the control will be
1211 * reported as writeable, but the driver will not actually issue a write
1212 * command for read-only channels */
1199 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ 1213 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1200 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, !!ch_read_only); 1214 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only);
1201 if (master_bits & (1 << i * 2)) 1215 if (uac2_control_is_readable(master_bits, i))
1202 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 1216 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
1203 ~master_bits & (1 << ((i * 2) + 1))); 1217 !uac2_control_is_writeable(master_bits, i));
1204 } 1218 }
1205 } 1219 }
1206 1220
@@ -1392,51 +1406,51 @@ struct procunit_info {
1392}; 1406};
1393 1407
1394static struct procunit_value_info updown_proc_info[] = { 1408static struct procunit_value_info updown_proc_info[] = {
1395 { USB_PROC_UPDOWN_SWITCH, "Switch", USB_MIXER_BOOLEAN }, 1409 { UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN },
1396 { USB_PROC_UPDOWN_MODE_SEL, "Mode Select", USB_MIXER_U8, 1 }, 1410 { UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
1397 { 0 } 1411 { 0 }
1398}; 1412};
1399static struct procunit_value_info prologic_proc_info[] = { 1413static struct procunit_value_info prologic_proc_info[] = {
1400 { USB_PROC_PROLOGIC_SWITCH, "Switch", USB_MIXER_BOOLEAN }, 1414 { UAC_DP_ENABLE, "Switch", USB_MIXER_BOOLEAN },
1401 { USB_PROC_PROLOGIC_MODE_SEL, "Mode Select", USB_MIXER_U8, 1 }, 1415 { UAC_DP_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
1402 { 0 } 1416 { 0 }
1403}; 1417};
1404static struct procunit_value_info threed_enh_proc_info[] = { 1418static struct procunit_value_info threed_enh_proc_info[] = {
1405 { USB_PROC_3DENH_SWITCH, "Switch", USB_MIXER_BOOLEAN }, 1419 { UAC_3D_ENABLE, "Switch", USB_MIXER_BOOLEAN },
1406 { USB_PROC_3DENH_SPACE, "Spaciousness", USB_MIXER_U8 }, 1420 { UAC_3D_SPACE, "Spaciousness", USB_MIXER_U8 },
1407 { 0 } 1421 { 0 }
1408}; 1422};
1409static struct procunit_value_info reverb_proc_info[] = { 1423static struct procunit_value_info reverb_proc_info[] = {
1410 { USB_PROC_REVERB_SWITCH, "Switch", USB_MIXER_BOOLEAN }, 1424 { UAC_REVERB_ENABLE, "Switch", USB_MIXER_BOOLEAN },
1411 { USB_PROC_REVERB_LEVEL, "Level", USB_MIXER_U8 }, 1425 { UAC_REVERB_LEVEL, "Level", USB_MIXER_U8 },
1412 { USB_PROC_REVERB_TIME, "Time", USB_MIXER_U16 }, 1426 { UAC_REVERB_TIME, "Time", USB_MIXER_U16 },
1413 { USB_PROC_REVERB_DELAY, "Delay", USB_MIXER_U8 }, 1427 { UAC_REVERB_FEEDBACK, "Feedback", USB_MIXER_U8 },
1414 { 0 } 1428 { 0 }
1415}; 1429};
1416static struct procunit_value_info chorus_proc_info[] = { 1430static struct procunit_value_info chorus_proc_info[] = {
1417 { USB_PROC_CHORUS_SWITCH, "Switch", USB_MIXER_BOOLEAN }, 1431 { UAC_CHORUS_ENABLE, "Switch", USB_MIXER_BOOLEAN },
1418 { USB_PROC_CHORUS_LEVEL, "Level", USB_MIXER_U8 }, 1432 { UAC_CHORUS_LEVEL, "Level", USB_MIXER_U8 },
1419 { USB_PROC_CHORUS_RATE, "Rate", USB_MIXER_U16 }, 1433 { UAC_CHORUS_RATE, "Rate", USB_MIXER_U16 },
1420 { USB_PROC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 }, 1434 { UAC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 },
1421 { 0 } 1435 { 0 }
1422}; 1436};
1423static struct procunit_value_info dcr_proc_info[] = { 1437static struct procunit_value_info dcr_proc_info[] = {
1424 { USB_PROC_DCR_SWITCH, "Switch", USB_MIXER_BOOLEAN }, 1438 { UAC_DCR_ENABLE, "Switch", USB_MIXER_BOOLEAN },
1425 { USB_PROC_DCR_RATIO, "Ratio", USB_MIXER_U16 }, 1439 { UAC_DCR_RATE, "Ratio", USB_MIXER_U16 },
1426 { USB_PROC_DCR_MAX_AMP, "Max Amp", USB_MIXER_S16 }, 1440 { UAC_DCR_MAXAMPL, "Max Amp", USB_MIXER_S16 },
1427 { USB_PROC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 }, 1441 { UAC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 },
1428 { USB_PROC_DCR_ATTACK, "Attack Time", USB_MIXER_U16 }, 1442 { UAC_DCR_ATTACK_TIME, "Attack Time", USB_MIXER_U16 },
1429 { USB_PROC_DCR_RELEASE, "Release Time", USB_MIXER_U16 }, 1443 { UAC_DCR_RELEASE_TIME, "Release Time", USB_MIXER_U16 },
1430 { 0 } 1444 { 0 }
1431}; 1445};
1432 1446
1433static struct procunit_info procunits[] = { 1447static struct procunit_info procunits[] = {
1434 { USB_PROC_UPDOWN, "Up Down", updown_proc_info }, 1448 { UAC_PROCESS_UP_DOWNMIX, "Up Down", updown_proc_info },
1435 { USB_PROC_PROLOGIC, "Dolby Prologic", prologic_proc_info }, 1449 { UAC_PROCESS_DOLBY_PROLOGIC, "Dolby Prologic", prologic_proc_info },
1436 { USB_PROC_3DENH, "3D Stereo Extender", threed_enh_proc_info }, 1450 { UAC_PROCESS_STEREO_EXTENDER, "3D Stereo Extender", threed_enh_proc_info },
1437 { USB_PROC_REVERB, "Reverb", reverb_proc_info }, 1451 { UAC_PROCESS_REVERB, "Reverb", reverb_proc_info },
1438 { USB_PROC_CHORUS, "Chorus", chorus_proc_info }, 1452 { UAC_PROCESS_CHORUS, "Chorus", chorus_proc_info },
1439 { USB_PROC_DCR, "DCR", dcr_proc_info }, 1453 { UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info },
1440 { 0 }, 1454 { 0 },
1441}; 1455};
1442/* 1456/*
@@ -1524,7 +1538,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
1524 cval->channels = 1; 1538 cval->channels = 1;
1525 1539
1526 /* get min/max values */ 1540 /* get min/max values */
1527 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) { 1541 if (type == UAC_PROCESS_UP_DOWNMIX && cval->control == UAC_UD_MODE_SELECT) {
1528 __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol); 1542 __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol);
1529 /* FIXME: hard-coded */ 1543 /* FIXME: hard-coded */
1530 cval->min = 1; 1544 cval->min = 1;
@@ -1619,7 +1633,7 @@ static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
1619 struct usb_mixer_elem_info *cval = kcontrol->private_data; 1633 struct usb_mixer_elem_info *cval = kcontrol->private_data;
1620 int val, err; 1634 int val, err;
1621 1635
1622 err = get_cur_ctl_value(cval, 0, &val); 1636 err = get_cur_ctl_value(cval, cval->control << 8, &val);
1623 if (err < 0) { 1637 if (err < 0) {
1624 if (cval->mixer->ignore_ctl_error) { 1638 if (cval->mixer->ignore_ctl_error) {
1625 ucontrol->value.enumerated.item[0] = 0; 1639 ucontrol->value.enumerated.item[0] = 0;
@@ -1638,7 +1652,7 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
1638 struct usb_mixer_elem_info *cval = kcontrol->private_data; 1652 struct usb_mixer_elem_info *cval = kcontrol->private_data;
1639 int val, oval, err; 1653 int val, oval, err;
1640 1654
1641 err = get_cur_ctl_value(cval, 0, &oval); 1655 err = get_cur_ctl_value(cval, cval->control << 8, &oval);
1642 if (err < 0) { 1656 if (err < 0) {
1643 if (cval->mixer->ignore_ctl_error) 1657 if (cval->mixer->ignore_ctl_error)
1644 return 0; 1658 return 0;
@@ -1647,7 +1661,7 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
1647 val = ucontrol->value.enumerated.item[0]; 1661 val = ucontrol->value.enumerated.item[0];
1648 val = get_abs_value(cval, val); 1662 val = get_abs_value(cval, val);
1649 if (val != oval) { 1663 if (val != oval) {
1650 set_cur_ctl_value(cval, 0, val); 1664 set_cur_ctl_value(cval, cval->control << 8, val);
1651 return 1; 1665 return 1;
1652 } 1666 }
1653 return 0; 1667 return 0;
@@ -1729,6 +1743,11 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
1729 cval->res = 1; 1743 cval->res = 1;
1730 cval->initialized = 1; 1744 cval->initialized = 1;
1731 1745
1746 if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
1747 cval->control = UAC2_CX_CLOCK_SELECTOR;
1748 else
1749 cval->control = 0;
1750
1732 namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL); 1751 namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
1733 if (! namelist) { 1752 if (! namelist) {
1734 snd_printk(KERN_ERR "cannot malloc\n"); 1753 snd_printk(KERN_ERR "cannot malloc\n");
@@ -1778,7 +1797,9 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
1778 if (! len) 1797 if (! len)
1779 strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); 1798 strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
1780 1799
1781 if ((state->oterm.type & 0xff00) == 0x0100) 1800 if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
1801 append_ctl_name(kctl, " Clock Source");
1802 else if ((state->oterm.type & 0xff00) == 0x0100)
1782 append_ctl_name(kctl, " Capture Source"); 1803 append_ctl_name(kctl, " Capture Source");
1783 else 1804 else
1784 append_ctl_name(kctl, " Playback Source"); 1805 append_ctl_name(kctl, " Playback Source");
@@ -1812,10 +1833,12 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
1812 1833
1813 switch (p1[2]) { 1834 switch (p1[2]) {
1814 case UAC_INPUT_TERMINAL: 1835 case UAC_INPUT_TERMINAL:
1836 case UAC2_CLOCK_SOURCE:
1815 return 0; /* NOP */ 1837 return 0; /* NOP */
1816 case UAC_MIXER_UNIT: 1838 case UAC_MIXER_UNIT:
1817 return parse_audio_mixer_unit(state, unitid, p1); 1839 return parse_audio_mixer_unit(state, unitid, p1);
1818 case UAC_SELECTOR_UNIT: 1840 case UAC_SELECTOR_UNIT:
1841 case UAC2_CLOCK_SELECTOR:
1819 return parse_audio_selector_unit(state, unitid, p1); 1842 return parse_audio_selector_unit(state, unitid, p1);
1820 case UAC_FEATURE_UNIT: 1843 case UAC_FEATURE_UNIT:
1821 return parse_audio_feature_unit(state, unitid, p1); 1844 return parse_audio_feature_unit(state, unitid, p1);
@@ -1912,6 +1935,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1912 err = parse_audio_unit(&state, desc->bSourceID); 1935 err = parse_audio_unit(&state, desc->bSourceID);
1913 if (err < 0) 1936 if (err < 0)
1914 return err; 1937 return err;
1938
1939 /* for UAC2, use the same approach to also add the clock selectors */
1940 err = parse_audio_unit(&state, desc->bCSourceID);
1941 if (err < 0)
1942 return err;
1915 } 1943 }
1916 } 1944 }
1917 1945
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 130123854a6c..a7cf1007fbb0 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -34,6 +34,8 @@ struct usb_mixer_elem_info {
34 unsigned int id; 34 unsigned int id;
35 unsigned int control; /* CS or ICN (high byte) */ 35 unsigned int control; /* CS or ICN (high byte) */
36 unsigned int cmask; /* channel mask bitmap: 0 = master */ 36 unsigned int cmask; /* channel mask bitmap: 0 = master */
37 unsigned int ch_readonly;
38 unsigned int master_readonly;
37 int channels; 39 int channels;
38 int val_type; 40 int val_type;
39 int min, max, res; 41 int min, max, res;
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
index d93fc89beba8..f1324c423835 100644
--- a/sound/usb/mixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -85,8 +85,8 @@ static struct usbmix_name_map extigy_map[] = {
85 /* 16: MU (w/o controls) */ 85 /* 16: MU (w/o controls) */
86 { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */ 86 { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */
87 { 17, "Channel Routing", 2 }, /* PU: mode select */ 87 { 17, "Channel Routing", 2 }, /* PU: mode select */
88 { 18, "Tone Control - Bass", UAC_BASS_CONTROL }, /* FU */ 88 { 18, "Tone Control - Bass", UAC_FU_BASS }, /* FU */
89 { 18, "Tone Control - Treble", UAC_TREBLE_CONTROL }, /* FU */ 89 { 18, "Tone Control - Treble", UAC_FU_TREBLE }, /* FU */
90 { 18, "Master Playback" }, /* FU; others */ 90 { 18, "Master Playback" }, /* FU; others */
91 /* 19: OT speaker */ 91 /* 19: OT speaker */
92 /* 20: OT headphone */ 92 /* 20: OT headphone */
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 056587de7be4..456829882f40 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -31,6 +31,7 @@
31#include "urb.h" 31#include "urb.h"
32#include "helper.h" 32#include "helper.h"
33#include "pcm.h" 33#include "pcm.h"
34#include "clock.h"
34 35
35/* 36/*
36 * return the current pcm pointer. just based on the hwptr_done value. 37 * return the current pcm pointer. just based on the hwptr_done value.
@@ -181,103 +182,6 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
181 return -EINVAL; 182 return -EINVAL;
182} 183}
183 184
184static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
185 struct usb_host_interface *alts,
186 struct audioformat *fmt, int rate)
187{
188 struct usb_device *dev = chip->dev;
189 unsigned int ep;
190 unsigned char data[3];
191 int err, crate;
192
193 ep = get_endpoint(alts, 0)->bEndpointAddress;
194 /* if endpoint doesn't have sampling rate control, bail out */
195 if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) {
196 snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n",
197 dev->devnum, iface, fmt->altsetting);
198 return 0;
199 }
200
201 data[0] = rate;
202 data[1] = rate >> 8;
203 data[2] = rate >> 16;
204 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
205 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
206 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
207 data, sizeof(data), 1000)) < 0) {
208 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
209 dev->devnum, iface, fmt->altsetting, rate, ep);
210 return err;
211 }
212 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
213 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
214 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
215 data, sizeof(data), 1000)) < 0) {
216 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
217 dev->devnum, iface, fmt->altsetting, ep);
218 return 0; /* some devices don't support reading */
219 }
220 crate = data[0] | (data[1] << 8) | (data[2] << 16);
221 if (crate != rate) {
222 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
223 // runtime->rate = crate;
224 }
225
226 return 0;
227}
228
229static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
230 struct usb_host_interface *alts,
231 struct audioformat *fmt, int rate)
232{
233 struct usb_device *dev = chip->dev;
234 unsigned char data[4];
235 int err, crate;
236
237 data[0] = rate;
238 data[1] = rate >> 8;
239 data[2] = rate >> 16;
240 data[3] = rate >> 24;
241 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
242 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
243 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
244 data, sizeof(data), 1000)) < 0) {
245 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
246 dev->devnum, iface, fmt->altsetting, rate);
247 return err;
248 }
249 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
250 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
251 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
252 data, sizeof(data), 1000)) < 0) {
253 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
254 dev->devnum, iface, fmt->altsetting);
255 return err;
256 }
257 crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
258 if (crate != rate)
259 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
260
261 return 0;
262}
263
264int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
265 struct usb_host_interface *alts,
266 struct audioformat *fmt, int rate)
267{
268 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
269
270 switch (altsd->bInterfaceProtocol) {
271 case UAC_VERSION_1:
272 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
273
274 case UAC_VERSION_2:
275 return set_sample_rate_v2(chip, iface, alts, fmt, rate);
276 }
277
278 return -EINVAL;
279}
280
281/* 185/*
282 * find a matching format and set up the interface 186 * find a matching format and set up the interface
283 */ 187 */
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 06ebf24d3a4d..24d3319cc34d 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -40,9 +40,6 @@ struct snd_usb_audio {
40 int num_interfaces; 40 int num_interfaces;
41 int num_suspended_intf; 41 int num_suspended_intf;
42 42
43 /* for audio class v2 */
44 int clock_id;
45
46 struct list_head pcm_list; /* list of pcm streams */ 43 struct list_head pcm_list; /* list of pcm streams */
47 int pcm_devs; 44 int pcm_devs;
48 45
@@ -53,6 +50,8 @@ struct snd_usb_audio {
53 int setup; /* from the 'device_setup' module param */ 50 int setup; /* from the 'device_setup' module param */
54 int nrpacks; /* from the 'nrpacks' module param */ 51 int nrpacks; /* from the 'nrpacks' module param */
55 int async_unlink; /* from the 'async_unlink' module param */ 52 int async_unlink; /* from the 'async_unlink' module param */
53
54 struct usb_host_interface *ctrl_intf; /* the audio control interface */
56}; 55};
57 56
58/* 57/*
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 44a47e13bd67..99890728409e 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -43,8 +43,10 @@ static int __cmd_buildid_list(void)
43 if (session == NULL) 43 if (session == NULL)
44 return -1; 44 return -1;
45 45
46 if (with_hits) 46 if (with_hits) {
47 symbol_conf.full_paths = true;
47 perf_session__process_events(session, &build_id__mark_dso_hit_ops); 48 perf_session__process_events(session, &build_id__mark_dso_hit_ops);
49 }
48 50
49 perf_session__fprintf_dsos_buildid(session, stdout, with_hits); 51 perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
50 52
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 9bc89050e6f8..dc3435e18bde 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -503,7 +503,6 @@ static int __cmd_record(int argc, const char **argv)
503{ 503{
504 int i, counter; 504 int i, counter;
505 struct stat st; 505 struct stat st;
506 pid_t pid = 0;
507 int flags; 506 int flags;
508 int err; 507 int err;
509 unsigned long waking = 0; 508 unsigned long waking = 0;
@@ -572,7 +571,7 @@ static int __cmd_record(int argc, const char **argv)
572 571
573 if (forks) { 572 if (forks) {
574 child_pid = fork(); 573 child_pid = fork();
575 if (pid < 0) { 574 if (child_pid < 0) {
576 perror("failed to fork"); 575 perror("failed to fork");
577 exit(-1); 576 exit(-1);
578 } 577 }
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index f67bce2a83b4..55f3b5dcc731 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1645,6 +1645,7 @@ static struct perf_event_ops event_ops = {
1645 .sample = process_sample_event, 1645 .sample = process_sample_event,
1646 .comm = event__process_comm, 1646 .comm = event__process_comm,
1647 .lost = event__process_lost, 1647 .lost = event__process_lost,
1648 .fork = event__process_task,
1648 .ordered_samples = true, 1649 .ordered_samples = true,
1649}; 1650};
1650 1651
diff --git a/tools/perf/scripts/python/check-perf-trace.py b/tools/perf/scripts/python/check-perf-trace.py
index 964d934395ff..d9f7893e315c 100644
--- a/tools/perf/scripts/python/check-perf-trace.py
+++ b/tools/perf/scripts/python/check-perf-trace.py
@@ -51,8 +51,7 @@ def kmem__kmalloc(event_name, context, common_cpu,
51 51
52 flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)), 52 flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)),
53 53
54def trace_unhandled(event_name, context, common_cpu, common_secs, common_nsecs, 54def trace_unhandled(event_name, context, event_fields_dict):
55 common_pid, common_comm):
56 try: 55 try:
57 unhandled[event_name] += 1 56 unhandled[event_name] += 1
58 except TypeError: 57 except TypeError:
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 50771b5813ee..1f08f008d289 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -370,9 +370,9 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm)
370 370
371int event__process_comm(event_t *self, struct perf_session *session) 371int event__process_comm(event_t *self, struct perf_session *session)
372{ 372{
373 struct thread *thread = perf_session__findnew(session, self->comm.pid); 373 struct thread *thread = perf_session__findnew(session, self->comm.tid);
374 374
375 dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid); 375 dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid);
376 376
377 if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) { 377 if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) {
378 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); 378 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
@@ -532,16 +532,11 @@ out_problem:
532 532
533int event__process_task(event_t *self, struct perf_session *session) 533int event__process_task(event_t *self, struct perf_session *session)
534{ 534{
535 struct thread *thread = perf_session__findnew(session, self->fork.pid); 535 struct thread *thread = perf_session__findnew(session, self->fork.tid);
536 struct thread *parent = perf_session__findnew(session, self->fork.ppid); 536 struct thread *parent = perf_session__findnew(session, self->fork.ptid);
537 537
538 dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid, 538 dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid,
539 self->fork.ppid, self->fork.ptid); 539 self->fork.ppid, self->fork.ptid);
540 /*
541 * A thread clone will have the same PID for both parent and child.
542 */
543 if (thread == parent)
544 return 0;
545 540
546 if (self->header.type == PERF_RECORD_EXIT) 541 if (self->header.type == PERF_RECORD_EXIT)
547 return 0; 542 return 0;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index cbf7eae2ce09..07f89b66b318 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -965,7 +965,7 @@ static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file,
965 * Parse hexa addresses followed by ':' 965 * Parse hexa addresses followed by ':'
966 */ 966 */
967 line_ip = strtoull(tmp, &tmp2, 16); 967 line_ip = strtoull(tmp, &tmp2, 16);
968 if (*tmp2 != ':') 968 if (*tmp2 != ':' || tmp == tmp2)
969 line_ip = -1; 969 line_ip = -1;
970 } 970 }
971 971
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 81f39cab3aaa..33a632523743 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -208,7 +208,7 @@ static void python_process_event(int cpu, void *data,
208 int size __unused, 208 int size __unused,
209 unsigned long long nsecs, char *comm) 209 unsigned long long nsecs, char *comm)
210{ 210{
211 PyObject *handler, *retval, *context, *t, *obj; 211 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
212 static char handler_name[256]; 212 static char handler_name[256];
213 struct format_field *field; 213 struct format_field *field;
214 unsigned long long val; 214 unsigned long long val;
@@ -232,6 +232,14 @@ static void python_process_event(int cpu, void *data,
232 232
233 sprintf(handler_name, "%s__%s", event->system, event->name); 233 sprintf(handler_name, "%s__%s", event->system, event->name);
234 234
235 handler = PyDict_GetItemString(main_dict, handler_name);
236 if (handler && !PyCallable_Check(handler))
237 handler = NULL;
238 if (!handler) {
239 dict = PyDict_New();
240 if (!dict)
241 Py_FatalError("couldn't create Python dict");
242 }
235 s = nsecs / NSECS_PER_SEC; 243 s = nsecs / NSECS_PER_SEC;
236 ns = nsecs - s * NSECS_PER_SEC; 244 ns = nsecs - s * NSECS_PER_SEC;
237 245
@@ -242,12 +250,20 @@ static void python_process_event(int cpu, void *data,
242 PyTuple_SetItem(t, n++, PyString_FromString(handler_name)); 250 PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
243 PyTuple_SetItem(t, n++, 251 PyTuple_SetItem(t, n++,
244 PyCObject_FromVoidPtr(scripting_context, NULL)); 252 PyCObject_FromVoidPtr(scripting_context, NULL));
245 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
246 PyTuple_SetItem(t, n++, PyInt_FromLong(s));
247 PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
248 PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
249 PyTuple_SetItem(t, n++, PyString_FromString(comm));
250 253
254 if (handler) {
255 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
256 PyTuple_SetItem(t, n++, PyInt_FromLong(s));
257 PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
258 PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
259 PyTuple_SetItem(t, n++, PyString_FromString(comm));
260 } else {
261 PyDict_SetItemString(dict, "common_cpu", PyInt_FromLong(cpu));
262 PyDict_SetItemString(dict, "common_s", PyInt_FromLong(s));
263 PyDict_SetItemString(dict, "common_ns", PyInt_FromLong(ns));
264 PyDict_SetItemString(dict, "common_pid", PyInt_FromLong(pid));
265 PyDict_SetItemString(dict, "common_comm", PyString_FromString(comm));
266 }
251 for (field = event->format.fields; field; field = field->next) { 267 for (field = event->format.fields; field; field = field->next) {
252 if (field->flags & FIELD_IS_STRING) { 268 if (field->flags & FIELD_IS_STRING) {
253 int offset; 269 int offset;
@@ -272,27 +288,31 @@ static void python_process_event(int cpu, void *data,
272 obj = PyLong_FromUnsignedLongLong(val); 288 obj = PyLong_FromUnsignedLongLong(val);
273 } 289 }
274 } 290 }
275 PyTuple_SetItem(t, n++, obj); 291 if (handler)
292 PyTuple_SetItem(t, n++, obj);
293 else
294 PyDict_SetItemString(dict, field->name, obj);
295
276 } 296 }
297 if (!handler)
298 PyTuple_SetItem(t, n++, dict);
277 299
278 if (_PyTuple_Resize(&t, n) == -1) 300 if (_PyTuple_Resize(&t, n) == -1)
279 Py_FatalError("error resizing Python tuple"); 301 Py_FatalError("error resizing Python tuple");
280 302
281 handler = PyDict_GetItemString(main_dict, handler_name); 303 if (handler) {
282 if (handler && PyCallable_Check(handler)) {
283 retval = PyObject_CallObject(handler, t); 304 retval = PyObject_CallObject(handler, t);
284 if (retval == NULL) 305 if (retval == NULL)
285 handler_call_die(handler_name); 306 handler_call_die(handler_name);
286 } else { 307 } else {
287 handler = PyDict_GetItemString(main_dict, "trace_unhandled"); 308 handler = PyDict_GetItemString(main_dict, "trace_unhandled");
288 if (handler && PyCallable_Check(handler)) { 309 if (handler && PyCallable_Check(handler)) {
289 if (_PyTuple_Resize(&t, N_COMMON_FIELDS) == -1)
290 Py_FatalError("error resizing Python tuple");
291 310
292 retval = PyObject_CallObject(handler, t); 311 retval = PyObject_CallObject(handler, t);
293 if (retval == NULL) 312 if (retval == NULL)
294 handler_call_die("trace_unhandled"); 313 handler_call_die("trace_unhandled");
295 } 314 }
315 Py_DECREF(dict);
296 } 316 }
297 317
298 Py_DECREF(t); 318 Py_DECREF(t);
@@ -548,12 +568,10 @@ static int python_generate_script(const char *outfile)
548 } 568 }
549 569
550 fprintf(ofp, "def trace_unhandled(event_name, context, " 570 fprintf(ofp, "def trace_unhandled(event_name, context, "
551 "common_cpu, common_secs, common_nsecs,\n\t\t" 571 "event_fields_dict):\n");
552 "common_pid, common_comm):\n");
553 572
554 fprintf(ofp, "\t\tprint_header(event_name, common_cpu, " 573 fprintf(ofp, "\t\tprint ' '.join(['%%s=%%s'%%(k,str(v))"
555 "common_secs, common_nsecs,\n\t\tcommon_pid, " 574 "for k,v in sorted(event_fields_dict.items())])\n\n");
556 "common_comm)\n\n");
557 575
558 fprintf(ofp, "def print_header(" 576 fprintf(ofp, "def print_header("
559 "event_name, cpu, secs, nsecs, pid, comm):\n" 577 "event_name, cpu, secs, nsecs, pid, comm):\n"